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);
}
}
}
}
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();
}
}
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;
}
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;
}
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;
}
Aggregations