use of org.alfresco.repo.security.permissions.PermissionCheckValue in project records-management by Alfresco.
the class RMAfterInvocationProvider method decide.
private Object[] decide(Authentication authentication, Object object, ConfigAttributeDefinition config, Object[] returnedObject) {
// Assumption: value is not null
BitSet incudedSet = new BitSet(returnedObject.length);
List<ConfigAttributeDefintion> supportedDefinitions = extractSupportedDefinitions(config);
if (supportedDefinitions.size() == 0) {
return returnedObject;
}
for (int i = 0, l = returnedObject.length; i < l; i++) {
Object current = returnedObject[i];
int parentReadCheck = checkRead(getParentReadCheckNode(current));
int childReadChek = checkRead(getChildReadCheckNode(current));
for (ConfigAttributeDefintion cad : supportedDefinitions) {
incudedSet.set(i, true);
NodeRef testNodeRef = null;
if (cad.parent) {
if (StoreRef.class.isAssignableFrom(current.getClass())) {
testNodeRef = null;
} else if (NodeRef.class.isAssignableFrom(current.getClass())) {
testNodeRef = nodeService.getPrimaryParent((NodeRef) current).getParentRef();
} else if (ChildAssociationRef.class.isAssignableFrom(current.getClass())) {
testNodeRef = ((ChildAssociationRef) current).getParentRef();
} else if (PermissionCheckValue.class.isAssignableFrom(current.getClass())) {
NodeRef nodeRef = ((PermissionCheckValue) current).getNodeRef();
testNodeRef = nodeService.getPrimaryParent(nodeRef).getParentRef();
} else {
throw new ACLEntryVoterException("The specified parameter is recognized: " + current.getClass());
}
} else {
if (StoreRef.class.isAssignableFrom(current.getClass())) {
testNodeRef = nodeService.getRootNode((StoreRef) current);
} else if (NodeRef.class.isAssignableFrom(current.getClass())) {
testNodeRef = (NodeRef) current;
} else if (ChildAssociationRef.class.isAssignableFrom(current.getClass())) {
testNodeRef = ((ChildAssociationRef) current).getChildRef();
} else if (PermissionCheckValue.class.isAssignableFrom(current.getClass())) {
testNodeRef = ((PermissionCheckValue) current).getNodeRef();
} else {
throw new ACLEntryVoterException("The specified parameter is recognized: " + current.getClass());
}
}
if (logger.isDebugEnabled()) {
logger.debug("\t" + cad.typeString + " test on " + testNodeRef + " from " + current.getClass().getName());
}
if (isUnfiltered(testNodeRef)) {
continue;
}
int readCheck = childReadChek;
if (cad.parent) {
readCheck = parentReadCheck;
}
if (incudedSet.get(i) && (testNodeRef != null) && (readCheck != AccessDecisionVoter.ACCESS_GRANTED)) {
incudedSet.set(i, false);
}
}
}
if (incudedSet.cardinality() == returnedObject.length) {
return returnedObject;
} else {
Object[] answer = new Object[incudedSet.cardinality()];
for (int i = incudedSet.nextSetBit(0), p = 0; i >= 0; i = incudedSet.nextSetBit(++i), p++) {
answer[p] = returnedObject[i];
}
return answer;
}
}
use of org.alfresco.repo.security.permissions.PermissionCheckValue in project records-management by Alfresco.
the class RMAfterInvocationProvider method decide.
@SuppressWarnings({ "unchecked", "rawtypes" })
private Collection decide(Authentication authentication, Object object, ConfigAttributeDefinition config, Collection returnedObject) {
if (returnedObject == null) {
return null;
}
List<ConfigAttributeDefintion> supportedDefinitions = extractSupportedDefinitions(config);
if (logger.isDebugEnabled()) {
logger.debug("Entries are " + supportedDefinitions);
}
if (supportedDefinitions.size() == 0) {
return returnedObject;
}
// Default to the system-wide values and we'll see if they need to be reduced
long targetResultCount = returnedObject.size();
int maxPermissionChecks = Integer.MAX_VALUE;
long maxPermissionCheckTimeMillis = this.maxPermissionCheckTimeMillis;
if (returnedObject instanceof PermissionCheckCollection<?>) {
PermissionCheckCollection permissionCheckCollection = (PermissionCheckCollection) returnedObject;
// Get values
targetResultCount = permissionCheckCollection.getTargetResultCount();
if (permissionCheckCollection.getCutOffAfterCount() > 0) {
maxPermissionChecks = permissionCheckCollection.getCutOffAfterCount();
}
if (permissionCheckCollection.getCutOffAfterTimeMs() > 0) {
maxPermissionCheckTimeMillis = permissionCheckCollection.getCutOffAfterTimeMs();
}
}
// Start timer and counter for cut-off
boolean cutoff = false;
long startTimeMillis = System.currentTimeMillis();
int count = 0;
// Keep values explicitly
List<Object> keepValues = new ArrayList<Object>(returnedObject.size());
for (Object nextObject : returnedObject) {
// if the maximum result size or time has been exceeded, then we have to remove only
long currentTimeMillis = System.currentTimeMillis();
// NOTE: for reference - the "maxPermissionChecks" has never been honoured by this loop (since previously the count was not being incremented)
if (count >= targetResultCount) {
// We have enough results. We stop without cutoff.
break;
} else if (count >= maxPermissionChecks) {
// We have been cut off by count
cutoff = true;
if (logger.isDebugEnabled()) {
logger.debug("decide (collection) cut-off: " + count + " checks exceeded " + maxPermissionChecks + " checks");
}
break;
} else if ((currentTimeMillis - startTimeMillis) > maxPermissionCheckTimeMillis) {
// We have been cut off by time
cutoff = true;
if (logger.isDebugEnabled()) {
logger.debug("decide (collection) cut-off: " + (currentTimeMillis - startTimeMillis) + "ms exceeded " + maxPermissionCheckTimeMillis + "ms");
}
break;
}
boolean allowed = true;
for (ConfigAttributeDefintion cad : supportedDefinitions) {
if (cad.mode.equalsIgnoreCase("FilterNode")) {
NodeRef testNodeRef = null;
if (cad.parent) {
if (StoreRef.class.isAssignableFrom(nextObject.getClass())) {
// Will be allowed
testNodeRef = null;
} else if (NodeRef.class.isAssignableFrom(nextObject.getClass())) {
testNodeRef = nodeService.getPrimaryParent((NodeRef) nextObject).getParentRef();
} else if (ChildAssociationRef.class.isAssignableFrom(nextObject.getClass())) {
testNodeRef = ((ChildAssociationRef) nextObject).getParentRef();
} else if (AssociationRef.class.isAssignableFrom(nextObject.getClass())) {
testNodeRef = ((AssociationRef) nextObject).getSourceRef();
} else if (PermissionCheckValue.class.isAssignableFrom(nextObject.getClass())) {
NodeRef nodeRef = ((PermissionCheckValue) nextObject).getNodeRef();
testNodeRef = nodeService.getPrimaryParent(nodeRef).getParentRef();
} else {
throw new ACLEntryVoterException("The specified parameter is recognized: " + nextObject.getClass());
}
} else {
if (StoreRef.class.isAssignableFrom(nextObject.getClass())) {
testNodeRef = nodeService.getRootNode((StoreRef) nextObject);
} else if (NodeRef.class.isAssignableFrom(nextObject.getClass())) {
testNodeRef = (NodeRef) nextObject;
} else if (ChildAssociationRef.class.isAssignableFrom(nextObject.getClass())) {
testNodeRef = ((ChildAssociationRef) nextObject).getChildRef();
} else if (AssociationRef.class.isAssignableFrom(nextObject.getClass())) {
testNodeRef = ((AssociationRef) nextObject).getTargetRef();
} else if (PermissionCheckValue.class.isAssignableFrom(nextObject.getClass())) {
testNodeRef = ((PermissionCheckValue) nextObject).getNodeRef();
} else {
throw new ACLEntryVoterException("The specified parameter is recognized: " + nextObject.getClass());
}
}
if (logger.isDebugEnabled()) {
logger.debug("\t" + cad.typeString + " test on " + testNodeRef + " from " + nextObject.getClass().getName());
}
// Null allows
if (isUnfiltered(testNodeRef)) {
// Continue to next ConfigAttributeDefintion
continue;
}
if (allowed && testNodeRef != null && checkRead(testNodeRef) != AccessDecisionVoter.ACCESS_GRANTED) {
allowed = false;
// No point evaluating more ConfigAttributeDefintions
break;
}
}
}
// Failure or success, increase the count
count++;
if (allowed) {
keepValues.add(nextObject);
}
}
// Work out how many were left unchecked (for whatever reason)
int sizeOriginal = returnedObject.size();
int checksRemaining = sizeOriginal - count;
// So make sure that the collection needs modification at all
if (keepValues.size() < sizeOriginal) {
// There are values that need to be removed. We have to modify the collection.
try {
returnedObject.clear();
returnedObject.addAll(keepValues);
} catch (UnsupportedOperationException e) {
throw new AccessDeniedException("Permission-checked list must be modifiable", e);
}
}
// Attach the extra permission-check data to the collection
return PermissionCheckedCollectionMixin.create(returnedObject, cutoff, checksRemaining, sizeOriginal);
}
Aggregations