mirror of
https://gitee.com/jmix/cuba.git
synced 2024-12-01 02:38:21 +08:00
PL-7476 Paging does not work when using in-memory security constraints
This commit is contained in:
parent
11ff8d8a9a
commit
035dadd4bd
@ -55,9 +55,8 @@ public interface PersistenceSecurity extends Security {
|
||||
/**
|
||||
* Applies in-memory constraints to the entity
|
||||
* @param entity -
|
||||
* @return true, if entity should be filtered from client output
|
||||
*/
|
||||
boolean applyConstraints(Entity entity);
|
||||
void applyConstraints(Entity entity);
|
||||
|
||||
/**
|
||||
* Applies in-memory constraints to the entity fields
|
||||
@ -71,6 +70,13 @@ public interface PersistenceSecurity extends Security {
|
||||
*/
|
||||
boolean filterByConstraints(Collection<Entity> entities);
|
||||
|
||||
/**
|
||||
* Filter entities in collection by in-memory constraints
|
||||
* @param entity - collection of entities that will be filtered
|
||||
* @return true, if entity should be filtered from client output
|
||||
*/
|
||||
boolean filterByConstraints(Entity entity);
|
||||
|
||||
/**
|
||||
* Reads security token and restores filtered data
|
||||
* @param resultEntity -
|
||||
|
@ -98,6 +98,7 @@ public class DataManagerBean implements DataManager {
|
||||
}
|
||||
|
||||
E result = null;
|
||||
boolean needToApplyInMemoryConstraints = needToApplyInMemoryConstraints(context);
|
||||
try (Transaction tx = persistence.createTransaction()) {
|
||||
final EntityManager em = persistence.getEntityManager();
|
||||
|
||||
@ -119,7 +120,7 @@ public class DataManagerBean implements DataManager {
|
||||
result = resultList.get(0);
|
||||
}
|
||||
|
||||
if (result != null && needToApplyInMemoryConstraints(context) && security.applyConstraints(result)) {
|
||||
if (result != null && needToApplyInMemoryConstraints && security.filterByConstraints(result)) {
|
||||
result = null;
|
||||
}
|
||||
|
||||
@ -130,7 +131,12 @@ public class DataManagerBean implements DataManager {
|
||||
tx.commit();
|
||||
}
|
||||
|
||||
attributeSecurity.afterLoad(result);
|
||||
if (result != null) {
|
||||
if (needToApplyInMemoryConstraints) {
|
||||
security.applyConstraints(result);
|
||||
}
|
||||
attributeSecurity.afterLoad(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -174,10 +180,6 @@ public class DataManagerBean implements DataManager {
|
||||
|
||||
resultList = getResultList(context, query, ensureDistinct);
|
||||
|
||||
if (needToApplyInMemoryConstraints(context)) {
|
||||
security.applyConstraints((Collection<Entity>) resultList);
|
||||
}
|
||||
|
||||
// Fetch dynamic attributes
|
||||
if (context.getView() != null
|
||||
&& BaseGenericIdEntity.class.isAssignableFrom(context.getView().getEntityClass())
|
||||
@ -188,6 +190,10 @@ public class DataManagerBean implements DataManager {
|
||||
tx.commit();
|
||||
}
|
||||
|
||||
if (needToApplyInMemoryConstraints(context)) {
|
||||
security.applyConstraints((Collection<Entity>) resultList);
|
||||
}
|
||||
|
||||
attributeSecurity.afterLoad(resultList);
|
||||
|
||||
return resultList;
|
||||
@ -385,13 +391,16 @@ public class DataManagerBean implements DataManager {
|
||||
|
||||
if (isAuthorizationRequired() && userSessionSource.getUserSession().hasConstraints()) {
|
||||
security.filterByConstraints(res);
|
||||
security.applyConstraints(res);
|
||||
}
|
||||
}
|
||||
|
||||
tx.commit();
|
||||
}
|
||||
|
||||
if (isAuthorizationRequired() && userSessionSource.getUserSession().hasConstraints()) {
|
||||
security.applyConstraints(res);
|
||||
}
|
||||
|
||||
for (Entity entity : res) {
|
||||
if (!persisted.contains(entity)) {
|
||||
View view = context.getViews().get(entity);
|
||||
|
@ -41,7 +41,6 @@ import org.slf4j.LoggerFactory;
|
||||
import javax.inject.Inject;
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
@ -130,19 +129,24 @@ public class PersistenceSecurityImpl extends SecurityImpl implements Persistence
|
||||
return filtered;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean filterByConstraints(Entity entity) {
|
||||
return entity instanceof HasUuid && !isPermittedInMemory(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyConstraints(Collection<Entity> entities) {
|
||||
Set<UUID> handled = new LinkedHashSet<>();
|
||||
entities.stream().filter(entity -> entity instanceof HasUuid).forEach(entity -> {
|
||||
internalApplyConstraints(entity, handled);
|
||||
internalApplyConstraints(entity, handled, false);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyConstraints(Entity entity) {
|
||||
if (!(entity instanceof HasUuid))
|
||||
return false;
|
||||
return internalApplyConstraints(entity, new HashSet<>());
|
||||
public void applyConstraints(Entity entity) {
|
||||
if (entity instanceof HasUuid) {
|
||||
internalApplyConstraints(entity, new HashSet<>(), false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -211,13 +215,13 @@ public class PersistenceSecurityImpl extends SecurityImpl implements Persistence
|
||||
}
|
||||
} catch (JpqlSyntaxException e) {
|
||||
log.error("Syntax errors found in constraint's JPQL expressions. Entity [{}]. Constraint ID [{}].",
|
||||
entityName, constraint.getId(), e);
|
||||
entityName, constraint.getId(), e);
|
||||
|
||||
throw new RowLevelSecurityException(
|
||||
"Syntax errors found in constraint's JPQL expressions. Please see the logs.", entityName);
|
||||
} catch (Exception e) {
|
||||
log.error("An error occurred when applying security constraint. Entity [{}]. Constraint ID [{}].",
|
||||
entityName, constraint.getId(), e);
|
||||
entityName, constraint.getId(), e);
|
||||
|
||||
throw new RowLevelSecurityException(
|
||||
"An error occurred when applying security constraint. Please see the logs.", entityName);
|
||||
@ -228,7 +232,7 @@ public class PersistenceSecurityImpl extends SecurityImpl implements Persistence
|
||||
Set<UUID> filtered = new LinkedHashSet<>();
|
||||
for (Iterator<Entity> iterator = entities.iterator(); iterator.hasNext(); ) {
|
||||
Entity next = iterator.next();
|
||||
if (internalApplyConstraints(next, handled)) {
|
||||
if (internalApplyConstraints(next, handled, true)) {
|
||||
filtered.add(((HasUuid) next).getUuid());
|
||||
//we ignore situations when the collection is immutable
|
||||
iterator.remove();
|
||||
@ -239,10 +243,10 @@ public class PersistenceSecurityImpl extends SecurityImpl implements Persistence
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected boolean internalApplyConstraints(Entity entity, Set<UUID> handled) {
|
||||
protected boolean internalApplyConstraints(Entity entity, Set<UUID> handled, boolean checkPermitted) {
|
||||
MetaClass metaClass = entity.getMetaClass();
|
||||
|
||||
if (!isPermittedInMemory(entity)) {
|
||||
if (!isPermittedInMemory(entity) && checkPermitted) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -262,7 +266,7 @@ public class PersistenceSecurityImpl extends SecurityImpl implements Persistence
|
||||
}
|
||||
} else if (value instanceof Entity && value instanceof HasUuid) {
|
||||
Entity valueEntity = (Entity) value;
|
||||
if (internalApplyConstraints(valueEntity, handled)) {
|
||||
if (internalApplyConstraints(valueEntity, handled, true)) {
|
||||
//we ignore the situation when the field is read-only
|
||||
entity.setValue(property.getName(), null);
|
||||
if (entity instanceof BaseGenericIdEntity) {
|
||||
|
Loading…
Reference in New Issue
Block a user