diff --git a/source/java/org/alfresco/opencmis/CMISConnector.java b/source/java/org/alfresco/opencmis/CMISConnector.java index 7a881d40f1..d0de2778ba 100644 --- a/source/java/org/alfresco/opencmis/CMISConnector.java +++ b/source/java/org/alfresco/opencmis/CMISConnector.java @@ -2769,7 +2769,11 @@ public class CMISConnector implements ApplicationContextAware, ApplicationListen if (hasRemove) { Set permissions = permissionService.getAllSetPermissions(nodeRef); - for (Ace ace : removeAces.getAces()) + + // get only direct ACE since only those can be removed + Acl onlyDirectAcl = excludeInheritedAces(nodeRef, removeAces); + + for (Ace ace : onlyDirectAcl.getAces()) { String principalId = ace.getPrincipalId(); if (CMIS_USER.equals(principalId)) @@ -2811,6 +2815,91 @@ public class CMISConnector implements ApplicationContextAware, ApplicationListen } } + /** + * Converts Acl to map and ignore the indirect ACEs + * + * @param acl + * @return + */ + private Map> convertAclToMap(Acl acl) + { + Map> result = new HashMap>(); + + if (acl == null || acl.getAces() == null) + { + return result; + } + + for (Ace ace : acl.getAces()) + { + // don't consider indirect ACEs - we can't change them + if (!ace.isDirect()) + { + // ignore + continue; + } + + // although a principal must not be null, check it + if (ace.getPrincipal() == null || ace.getPrincipal().getId() == null) + { + // ignore + continue; + } + + Set permissions = result.get(ace.getPrincipal().getId()); + if (permissions == null) + { + permissions = new HashSet(); + result.put(ace.getPrincipal().getId(), permissions); + } + + if (ace.getPermissions() != null) + { + permissions.addAll(ace.getPermissions()); + } + } + + return result; + } + + /** + * Filter acl to ignore inherited ACEs + * + * @param nodeRef + * @param acl + * @return + */ + protected Acl excludeInheritedAces(NodeRef nodeRef, Acl acl) + { + + List newAces = new ArrayList(); + Acl allACLs = getACL(nodeRef, false); + + Map> originalsAcls = convertAclToMap(allACLs); + Map> newAcls = convertAclToMap(acl); + + // iterate through the original ACEs + for (Map.Entry> ace : originalsAcls.entrySet()) + { + + // add permissions + Set addPermissions = newAcls.get(ace.getKey()); + if (addPermissions != null) + { + ace.getValue().addAll(addPermissions); + } + + // create new ACE + if (!ace.getValue().isEmpty()) + { + newAces.add(new AccessControlEntryImpl(new AccessControlPrincipalDataImpl(ace + .getKey()), new ArrayList(ace.getValue()))); + } + } + + return new AccessControlListImpl(newAces); + } + /** * Sets the given ACL. */