Search in sources :

Example 1 with AclChange

use of org.alfresco.repo.security.permissions.impl.AclChange in project alfresco-repository by Alfresco.

the class AclDAOImpl method getWritable.

/**
 * Make a whole tree of ACLs copy on write if required Includes adding and removing ACEs which can be optimised
 * slightly for copy on write (no need to add and then remove)
 */
private void getWritable(final Long id, final Long parent, Set<Long> visitedAcls, List<? extends AccessControlEntry> exclude, List<Ace> toAdd, Long inheritsFrom, List<Ace> inherited, List<Integer> positions, boolean cascade, int depth, List<AclChange> changes, WriteMode mode, boolean requiresVersion) {
    AclChange current = getWritable(id, parent, exclude, toAdd, inheritsFrom, inherited, positions, depth, mode, requiresVersion);
    changes.add(current);
    boolean cascadeVersion = requiresVersion;
    if (!cascadeVersion) {
        cascadeVersion = !current.getBefore().equals(current.getAfter());
    }
    if (cascade) {
        List<Long> inheritors = aclCrudDAO.getAclsThatInheritFromAcl(id);
        for (Long nextId : inheritors) {
            if (visitedAcls.contains(nextId)) {
                if (logger.isWarnEnabled()) {
                    StringBuilder message = new StringBuilder("ACL cycle detected! Repeated ALC id = '").append(nextId).append("', inherited ACL id = '").append(id).append("', already visited ACLs: '").append(visitedAcls).append("'. Skipping processing of the ACL id...");
                    logger.warn(message.toString());
                }
            } else {
                // Check for those that inherit themselves to other nodes ...
                getWritable(nextId, current.getAfter(), visitedAcls, exclude, toAdd, current.getAfter(), inherited, positions, cascade, depth + 1, changes, mode, cascadeVersion);
            }
        }
    }
}
Also used : AclChange(org.alfresco.repo.security.permissions.impl.AclChange)

Example 2 with AclChange

use of org.alfresco.repo.security.permissions.impl.AclChange in project alfresco-repository by Alfresco.

the class AclDAOImpl method getCopy.

private Long getCopy(Long toCopy, Long toInheritFrom, ACLCopyMode mode) {
    AclUpdateEntity aclToCopy;
    Long inheritedId;
    Acl aclToInheritFrom;
    switch(mode) {
        case INHERIT:
            if (toCopy.equals(toInheritFrom)) {
                return getInheritedAccessControlList(toCopy);
            } else {
                throw new UnsupportedOperationException();
            }
        case COW:
            aclToCopy = aclCrudDAO.getAclForUpdate(toCopy);
            aclToCopy.setRequiresVersion(true);
            aclToCopy.setAclChangeSetId(getCurrentChangeSetId());
            aclCrudDAO.updateAcl(aclToCopy);
            inheritedId = getInheritedAccessControlList(toCopy);
            if ((inheritedId != null) && (!inheritedId.equals(toCopy))) {
                AclUpdateEntity inheritedAcl = aclCrudDAO.getAclForUpdate(inheritedId);
                inheritedAcl.setRequiresVersion(true);
                inheritedAcl.setAclChangeSetId(getCurrentChangeSetId());
                aclCrudDAO.updateAcl(inheritedAcl);
            }
            return toCopy;
        case REDIRECT:
            if ((toInheritFrom != null) && (toInheritFrom.equals(toCopy))) {
                return getInheritedAccessControlList(toInheritFrom);
            }
            aclToCopy = aclCrudDAO.getAclForUpdate(toCopy);
            aclToInheritFrom = null;
            if (toInheritFrom != null) {
                aclToInheritFrom = aclCrudDAO.getAcl(toInheritFrom);
            }
            switch(aclToCopy.getAclType()) {
                case DEFINING:
                // So this needs to make a copy in the same way layered does
                case LAYERED:
                    if (toInheritFrom == null) {
                        return toCopy;
                    }
                    // manages cache clearing beneath
                    List<AclChange> changes = mergeInheritedAccessControlList(toInheritFrom, toCopy);
                    for (AclChange change : changes) {
                        if (change.getBefore().equals(toCopy)) {
                            return change.getAfter();
                        }
                    }
                    throw new UnsupportedOperationException();
                case SHARED:
                    if (aclToInheritFrom != null) {
                        return getInheritedAccessControlList(toInheritFrom);
                    } else {
                        throw new UnsupportedOperationException();
                    }
                case FIXED:
                case GLOBAL:
                case OLD:
                    return toCopy;
                default:
                    throw new UnsupportedOperationException();
            }
        case COPY:
            aclToCopy = aclCrudDAO.getAclForUpdate(toCopy);
            aclToInheritFrom = null;
            if (toInheritFrom != null) {
                aclToInheritFrom = aclCrudDAO.getAcl(toInheritFrom);
            }
            switch(aclToCopy.getAclType()) {
                case DEFINING:
                    SimpleAccessControlListProperties properties = new SimpleAccessControlListProperties();
                    properties.setAclType(ACLType.DEFINING);
                    properties.setInherits(aclToCopy.getInherits());
                    properties.setVersioned(true);
                    Long id = createAccessControlList(properties).getId();
                    AccessControlList indirectAcl = getAccessControlList(toCopy);
                    for (AccessControlEntry entry : indirectAcl.getEntries()) {
                        if (entry.getPosition() == 0) {
                            setAccessControlEntry(id, entry);
                        }
                    }
                    if (aclToInheritFrom != null) {
                        mergeInheritedAccessControlList(toInheritFrom, id);
                    }
                    return id;
                case SHARED:
                    if (aclToInheritFrom != null) {
                        return getInheritedAccessControlList(toInheritFrom);
                    } else {
                        return null;
                    }
                case FIXED:
                case GLOBAL:
                case LAYERED:
                case OLD:
                    return toCopy;
                default:
                    throw new UnsupportedOperationException();
            }
        default:
            throw new UnsupportedOperationException();
    }
}
Also used : AccessControlList(org.alfresco.repo.security.permissions.AccessControlList) SimpleAccessControlList(org.alfresco.repo.security.permissions.SimpleAccessControlList) SimpleAccessControlEntry(org.alfresco.repo.security.permissions.SimpleAccessControlEntry) AccessControlEntry(org.alfresco.repo.security.permissions.AccessControlEntry) AclChange(org.alfresco.repo.security.permissions.impl.AclChange) SimpleAccessControlListProperties(org.alfresco.repo.security.permissions.SimpleAccessControlListProperties)

Example 3 with AclChange

use of org.alfresco.repo.security.permissions.impl.AclChange in project alfresco-repository by Alfresco.

the class AclDAOImpl method deleteAccessControlEntries.

/**
 * {@inheritDoc}
 */
@Override
public List<AclChange> deleteAccessControlEntries(final String authority) {
    List<AclChange> aclChanges = new LinkedList<AclChange>();
    // get authority
    Authority authEntity = aclCrudDAO.getAuthority(authority);
    if (authEntity == null) {
        return aclChanges;
    }
    List<Long> aces = new ArrayList<Long>();
    List<AclMember> members = aclCrudDAO.getAclMembersByAuthority(authority);
    boolean leaveAuthority = false;
    if (members.size() > 0) {
        Set<AclUpdateEntity> acls = new HashSet<AclUpdateEntity>(members.size() * 2);
        List<Long> membersToDelete = new ArrayList<Long>(members.size());
        // fix up members and extract acls and aces
        for (AclMember member : members) {
            // Delete acl entry
            Long aclMemberId = member.getId();
            Long aclId = member.getAclId();
            Long aceId = member.getAceId();
            boolean hasAnotherTenantNodes = false;
            if (AuthenticationUtil.isMtEnabled()) {
                // ALF-3563
                // Retrieve dependent nodes
                List<Long> nodeIds = aclCrudDAO.getADMNodesByAcl(aclId, -1);
                if (nodeIds.size() > 0) {
                    for (Long nodeId : nodeIds) {
                        Pair<Long, NodeRef> nodePair = nodeDAO.getNodePair(nodeId);
                        if (nodePair == null) {
                            logger.warn("Node does not exist: " + nodeId);
                            continue;
                        } else {
                            NodeRef nodeRef = nodePair.getSecond();
                            try {
                                // Throws AlfrescoRuntimeException in case of domain mismatch
                                tenantService.checkDomain(nodeRef.getStoreRef().getIdentifier());
                            } catch (AlfrescoRuntimeException e) {
                                hasAnotherTenantNodes = true;
                                leaveAuthority = true;
                                break;
                            }
                        }
                    }
                }
            }
            if (!hasAnotherTenantNodes) {
                AclUpdateEntity list = aclCrudDAO.getAclForUpdate(aclId);
                aclChanges.add(new AclChangeImpl(aclId, aclId, list.getAclType(), list.getAclType()));
                acls.add(list);
                membersToDelete.add(aclMemberId);
                aces.add((Long) aceId);
            }
        }
        // delete list of acl members
        aclCrudDAO.deleteAclMembers(membersToDelete);
        // Remember to 'touch' all affected ACLs
        for (AclUpdateEntity acl : acls) {
            acl.setAclChangeSetId(getCurrentChangeSetId());
            aclCrudDAO.updateAcl(acl);
        }
    }
    if (!leaveAuthority) {
        // remove ACEs
        aclCrudDAO.deleteAces(aces);
        // Tidy up any unreferenced ACEs
        // get aces by authority
        List<Ace> unreferenced = aclCrudDAO.getAcesByAuthority(authEntity.getId());
        if (unreferenced.size() > 0) {
            List<Long> unrefencedAcesToDelete = new ArrayList<Long>(unreferenced.size());
            for (Ace ace : unreferenced) {
                unrefencedAcesToDelete.add(ace.getId());
            }
            aclCrudDAO.deleteAces(unrefencedAcesToDelete);
        }
        // remove authority
        if (authEntity != null) {
            aclCrudDAO.deleteAuthority(authEntity.getId());
        }
    }
    return aclChanges;
}
Also used : ArrayList(java.util.ArrayList) AclChange(org.alfresco.repo.security.permissions.impl.AclChange) LinkedList(java.util.LinkedList) NodeRef(org.alfresco.service.cmr.repository.NodeRef) AlfrescoRuntimeException(org.alfresco.error.AlfrescoRuntimeException) HashSet(java.util.HashSet)

Example 4 with AclChange

use of org.alfresco.repo.security.permissions.impl.AclChange in project alfresco-repository by Alfresco.

the class AclDAOImpl method deleteAccessControlList.

/**
 * {@inheritDoc}
 */
@Override
public List<AclChange> deleteAccessControlList(final Long id) {
    if (logger.isDebugEnabled()) {
        // debug only
        int maxForDebug = 11;
        List<Long> nodeIds = getADMNodesByAcl(id, maxForDebug);
        for (Long nodeId : nodeIds) {
            logger.debug("deleteAccessControlList: Found nodeId=" + nodeId + ", aclId=" + id);
        }
    }
    List<AclChange> acls = new ArrayList<AclChange>();
    final AclUpdateEntity acl = aclCrudDAO.getAclForUpdate(id);
    if (!acl.isLatest()) {
        throw new UnsupportedOperationException("Old ACL versions can not be updated");
    }
    if (acl.getAclType() == ACLType.SHARED) {
        throw new UnsupportedOperationException("Delete is not supported for shared acls - they are deleted with the defining acl");
    }
    if ((acl.getAclType() == ACLType.DEFINING) || (acl.getAclType() == ACLType.LAYERED)) {
        if ((acl.getInheritedAcl() != null) && (acl.getInheritedAcl() != -1)) {
            final Acl inherited = aclCrudDAO.getAcl(acl.getInheritedAcl());
            // Will remove from the cache
            getWritable(inherited.getId(), acl.getInheritsFrom(), null, null, null, true, acls, WriteMode.REMOVE_INHERITED);
            Acl unusedInherited = null;
            for (AclChange change : acls) {
                if (change.getBefore() != null && change.getBefore().equals(inherited.getId())) {
                    unusedInherited = aclCrudDAO.getAcl(change.getAfter());
                }
            }
            final Long newId = unusedInherited.getId();
            List<Long> inheritors = aclCrudDAO.getAclsThatInheritFromAcl(newId);
            for (Long nextId : inheritors) {
                // Will remove from the cache
                getWritable(nextId, acl.getInheritsFrom(), null, null, acl.getInheritsFrom(), true, acls, WriteMode.REMOVE_INHERITED);
            }
            // delete acl members
            aclCrudDAO.deleteAclMembersByAcl(newId);
            // delete 'unusedInherited' acl
            aclCrudDAO.deleteAcl(unusedInherited.getId());
            if (inherited.isVersioned()) {
                AclUpdateEntity inheritedForUpdate = aclCrudDAO.getAclForUpdate(inherited.getId());
                if (inheritedForUpdate != null) {
                    inheritedForUpdate.setLatest(Boolean.FALSE);
                    aclCrudDAO.updateAcl(inheritedForUpdate);
                }
            } else {
                // delete 'inherited' acl
                aclCrudDAO.deleteAcl(inherited.getId());
            }
        }
    } else {
        List<Long> inheritors = aclCrudDAO.getAclsThatInheritFromAcl(id);
        for (Long nextId : inheritors) {
            // Will remove from the cache
            getWritable(nextId, acl.getInheritsFrom(), null, null, null, true, acls, WriteMode.REMOVE_INHERITED);
        }
    }
    // delete
    if (acl.isVersioned()) {
        acl.setLatest(Boolean.FALSE);
        acl.setAclChangeSetId(getCurrentChangeSetId());
        aclCrudDAO.updateAcl(acl);
    } else {
        // delete acl members & acl
        aclCrudDAO.deleteAclMembersByAcl(id);
        aclCrudDAO.deleteAcl(acl.getId());
    }
    acls.add(new AclChangeImpl(id, null, acl.getAclType(), null));
    return acls;
}
Also used : ArrayList(java.util.ArrayList) AclChange(org.alfresco.repo.security.permissions.impl.AclChange)

Example 5 with AclChange

use of org.alfresco.repo.security.permissions.impl.AclChange in project alfresco-repository by Alfresco.

the class AclDAOImpl method deleteInheritedAccessControlEntries.

/**
 * {@inheritDoc}
 */
@Override
public List<AclChange> deleteInheritedAccessControlEntries(Long id) {
    List<AclChange> changes = new ArrayList<AclChange>();
    SimpleAccessControlEntry pattern = new SimpleAccessControlEntry();
    pattern.setPosition(Integer.valueOf(-1));
    // Will remove from the cache
    getWritable(id, null, Collections.singletonList(pattern), null, null, true, changes, WriteMode.COPY_UPDATE_AND_INHERIT);
    return changes;
}
Also used : ArrayList(java.util.ArrayList) AclChange(org.alfresco.repo.security.permissions.impl.AclChange) SimpleAccessControlEntry(org.alfresco.repo.security.permissions.SimpleAccessControlEntry)

Aggregations

AclChange (org.alfresco.repo.security.permissions.impl.AclChange)16 ArrayList (java.util.ArrayList)12 SimpleAccessControlEntry (org.alfresco.repo.security.permissions.SimpleAccessControlEntry)10 SimpleAccessControlListProperties (org.alfresco.repo.security.permissions.SimpleAccessControlListProperties)4 InvalidNodeRefException (org.alfresco.service.cmr.repository.InvalidNodeRefException)3 AccessControlEntry (org.alfresco.repo.security.permissions.AccessControlEntry)2 NodeRef (org.alfresco.service.cmr.repository.NodeRef)2 HashSet (java.util.HashSet)1 LinkedList (java.util.LinkedList)1 AlfrescoRuntimeException (org.alfresco.error.AlfrescoRuntimeException)1 AccessControlList (org.alfresco.repo.security.permissions.AccessControlList)1 NodePermissionEntry (org.alfresco.repo.security.permissions.NodePermissionEntry)1 PermissionEntry (org.alfresco.repo.security.permissions.PermissionEntry)1 SimpleAccessControlList (org.alfresco.repo.security.permissions.SimpleAccessControlList)1 SimpleNodePermissionEntry (org.alfresco.repo.security.permissions.impl.SimpleNodePermissionEntry)1 SimplePermissionEntry (org.alfresco.repo.security.permissions.impl.SimplePermissionEntry)1 SimplePermissionReference (org.alfresco.repo.security.permissions.impl.SimplePermissionReference)1 QName (org.alfresco.service.namespace.QName)1