Search in sources :

Example 1 with PermissionCheckCollection

use of org.alfresco.repo.security.permissions.PermissionCheckCollection 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);
}
Also used : StoreRef(org.alfresco.service.cmr.repository.StoreRef) AccessDeniedException(net.sf.acegisecurity.AccessDeniedException) ArrayList(java.util.ArrayList) ACLEntryVoterException(org.alfresco.repo.security.permissions.impl.acegi.ACLEntryVoterException) AssociationRef(org.alfresco.service.cmr.repository.AssociationRef) ChildAssociationRef(org.alfresco.service.cmr.repository.ChildAssociationRef) NodeRef(org.alfresco.service.cmr.repository.NodeRef) PermissionCheckValue(org.alfresco.repo.security.permissions.PermissionCheckValue) PermissionCheckCollection(org.alfresco.repo.security.permissions.PermissionCheckCollection)

Aggregations

ArrayList (java.util.ArrayList)1 AccessDeniedException (net.sf.acegisecurity.AccessDeniedException)1 PermissionCheckCollection (org.alfresco.repo.security.permissions.PermissionCheckCollection)1 PermissionCheckValue (org.alfresco.repo.security.permissions.PermissionCheckValue)1 ACLEntryVoterException (org.alfresco.repo.security.permissions.impl.acegi.ACLEntryVoterException)1 AssociationRef (org.alfresco.service.cmr.repository.AssociationRef)1 ChildAssociationRef (org.alfresco.service.cmr.repository.ChildAssociationRef)1 NodeRef (org.alfresco.service.cmr.repository.NodeRef)1 StoreRef (org.alfresco.service.cmr.repository.StoreRef)1