AVMAccessControlListDAO.java
| Index Score | ||
|---|---|---|
![]() |
![]() |
org.alfresco.repo.domain.hibernate |
![]() |
![]() |
Alfresco |
View: Reasons, Metrics, Source Code
These are the metrics that contribute to the Enerjy Score for this file, ranked by impact. So the metrics listed at the top influence the score to a greater extent that the metrics listed at the bottom.
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing" */
package org.alfresco.repo.domain.hibernate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.repo.avm.AVMNodeConverter;
import org.alfresco.repo.avm.AVMRepository;
import org.alfresco.repo.domain.AccessControlListDAO;
import org.alfresco.repo.domain.DbAccessControlList;
import org.alfresco.repo.domain.hibernate.AclDaoComponentImpl.Indirection;
import org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.security.permissions.ACLType;
import org.alfresco.repo.security.permissions.AccessControlEntry;
import org.alfresco.repo.security.permissions.AccessControlList;
import org.alfresco.repo.security.permissions.SimpleAccessControlListProperties;
import org.alfresco.repo.security.permissions.impl.AclChange;
import org.alfresco.repo.security.permissions.impl.AclDaoComponent;
import org.alfresco.service.cmr.avm.AVMException;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.avm.AVMStoreDescriptor;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.InvalidStoreRefException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.util.EqualsHelper;
import org.alfresco.util.Pair;
/**
* The AVM implementation for getting and setting ACLs.
*
* @author britt
*/
public class AVMAccessControlListDAO implements AccessControlListDAO
{
/**
* Reference to the AVM Repository instance.
*/
private AVMRepository fAVMRepository;
private AVMService fAVMService;
private AclDaoComponent aclDaoComponent;
private AVMSnapShotTriggeredIndexingMethodInterceptor avmSnapShotTriggeredIndexingMethodInterceptor;
private HibernateSessionHelper hibernateSessionHelper;
/**
* Default constructory.
*/
public AVMAccessControlListDAO()
{
}
/**
* Set the AVM repository
*
* @param repository
*/
public void setAvmRepository(AVMRepository repository)
{
fAVMRepository = repository;
}
/**
* Set the AVM service
*
* @param avmService
*/
public void setAvmService(AVMService avmService)
{
fAVMService = avmService;
}
/**
* Set the ACL DAO component
*
* @param aclDaoComponent
*/
public void setAclDaoComponent(AclDaoComponent aclDaoComponent)
{
this.aclDaoComponent = aclDaoComponent;
}
/**
* @param avmSnapShotTriggeredIndexingMethodInterceptor
*/
public void setAvmSnapShotTriggeredIndexingMethodInterceptor(AVMSnapShotTriggeredIndexingMethodInterceptor avmSnapShotTriggeredIndexingMethodInterceptor)
{
this.avmSnapShotTriggeredIndexingMethodInterceptor = avmSnapShotTriggeredIndexingMethodInterceptor;
}
/**
* @param hibernateSessionHelper
*/
public void setHibernateSessionHelper(HibernateSessionHelper hibernateSessionHelper)
{
this.hibernateSessionHelper = hibernateSessionHelper;
}
public Long getIndirectAcl(NodeRef nodeRef)
{
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
int version = avmVersionPath.getFirst();
if (version >= 0)
{
throw new InvalidNodeRefException("Read Only Node.", nodeRef);
}
String path = avmVersionPath.getSecond();
try
{
AVMNodeDescriptor descriptor = fAVMService.lookup(version, path);
if (descriptor == null)
{
return null;
}
if (descriptor.isPrimary())
{
DbAccessControlList acl = getAclAsSystem(descriptor.getIndirectionVersion(), descriptor.getIndirection());
if (acl == null)
{
return null;
}
else
{
return acl.getId();
}
}
else
{
DbAccessControlList acl = getAclAsSystem(version, path);
if (acl == null)
{
return null;
}
else
{
return acl.getId();
}
}
}
catch (AVMException e)
{
throw new InvalidNodeRefException(nodeRef);
}
}
public Long getInheritedAcl(NodeRef nodeRef)
{
// TODO OK, for now we'll simply return the single parent that corresponds
// to the path stuffed in the NodeRef.
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
String path = avmVersionPath.getSecond();
@SuppressWarnings("unused")
List<ChildAssociationRef> result = new ArrayList<ChildAssociationRef>();
String[] splitPath = AVMNodeConverter.SplitBase(path);
if (splitPath[0] == null)
{
return null;
}
DbAccessControlList acl = getAclAsSystem(avmVersionPath.getFirst(), splitPath[0]);
if (acl == null)
{
return null;
}
else
{
return acl.getId();
}
}
/**
* Get the ACL from a node.
*
* @param nodeRef
* The reference to the node.
* @return The ACL.
* @throws InvalidNodeRefException
*/
public DbAccessControlList getAccessControlList(NodeRef nodeRef)
{
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
int version = avmVersionPath.getFirst();
String path = avmVersionPath.getSecond();
try
{
return getAclAsSystem(version, path);
}
catch (AVMException e)
{
throw new InvalidNodeRefException(nodeRef);
}
}
/**
* Set the ACL on a node.
*
* @param nodeRef
* The reference to the node.
* @param acl
* The ACL.
* @throws InvalidNodeRefException
*/
public void setAccessControlList(NodeRef nodeRef, DbAccessControlList acl)
{
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
int version = avmVersionPath.getFirst();
if (version >= 0)
{
throw new InvalidNodeRefException("Read Only Node.", nodeRef);
}
String path = avmVersionPath.getSecond();
try
{
setAclAsSystem(path, acl);
}
catch (AVMException e)
{
throw new InvalidNodeRefException(nodeRef);
}
}
public void updateChangedAcls(NodeRef startingPoint, List<AclChange> changes)
{
// If their are no actual changes there is nothing to do (the changes are all in TX and have already COWed so they can just change)
boolean hasChanges = false;
Long after = null;
for (AclChange change : changes)
{
if (change.getBefore() == null)
{
after = change.getAfter();
}
else if (change.getTypeBefore() != change.getTypeAfter())
{
after = change.getAfter();
}
if(!EqualsHelper.nullSafeEquals(change.getTypeBefore(), change.getTypeAfter()))
{
hasChanges = true;
}
if(!EqualsHelper.nullSafeEquals(change.getBefore(), change.getAfter()))
{
hasChanges = true;
}
}
if(!hasChanges)
{
return;
}
Long inherited = null;
if (after != null)
{
inherited = aclDaoComponent.getInheritedAccessControlList(after);
}
Map<Long, Set<Long>> indirections = buildIndirections();
updateChangedAclsImpl(startingPoint, changes, SetMode.ALL, inherited, after, indirections);
}
private void updateChangedAclsImpl(NodeRef startingPoint, List<AclChange> changes, SetMode mode, Long inherited, Long setAcl, Map<Long, Set<Long>> indirections)
{
hibernateSessionHelper.mark();
try
{
HashMap<Long, Long> changeMap = new HashMap<Long, Long>();
HashSet<Long> unchangedSet = new HashSet<Long>();
for (AclChange change : changes)
{
if (change.getBefore() == null)
{
// null is treated using the inherited acl
}
else if (!change.getBefore().equals(change.getAfter()))
{
changeMap.put(change.getBefore(), change.getAfter());
}
else
{
unchangedSet.add(change.getBefore());
}
}
unchangedSet.add(inherited);
unchangedSet.add(setAcl);
if (inherited != null)
{
updateReferencingLayeredAcls(startingPoint, inherited, indirections);
}
updateInheritedChangedAcls(startingPoint, changeMap, unchangedSet, inherited, mode, indirections);
updateLayeredAclsChangedByInheritance(changes, changeMap, unchangedSet, indirections);
}
finally
{
hibernateSessionHelper.resetAndRemoveMark();
}
}
public void forceCopy(NodeRef nodeRef)
{
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
int version = avmVersionPath.getFirst();
if (version >= 0)
{
throw new InvalidNodeRefException("Read Only Node.", nodeRef);
}
String path = avmVersionPath.getSecond();
try
{
fAVMRepository.forceCopy(path);
}
catch (AVMException e)
{
throw new InvalidNodeRefException(nodeRef);
}
}
private Map<Long, Set<Long>> buildIndirections()
{
Map<Long, Set<Long>> answer = new HashMap<Long, Set<Long>>();
List<Indirection> indirections = aclDaoComponent.getAvmIndirections();
for (Indirection indirection : indirections)
{
AVMNodeDescriptor toDesc = fAVMService.lookup(indirection.getToVersion(), indirection.getTo(), true);
if (toDesc != null)
{
Long toId = Long.valueOf(toDesc.getId());
Set<Long> referees = answer.get(toId);
if (referees == null)
{
referees = new HashSet<Long>();
answer.put(toId, referees);
}
referees.add(indirection.getFrom());
}
}
return answer;
}
private void updateReferencingLayeredAcls(NodeRef node, Long inherited, Map<Long, Set<Long>> indirections)
{
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(node);
int version = avmVersionPath.getFirst();
if (version >= 0)
{
throw new InvalidNodeRefException("Read Only Node.", node);
}
String path = avmVersionPath.getSecond();
try
{
AVMNodeDescriptor descriptor = fAVMService.lookup(version, path);
if (descriptor == null)
{
return;
}
else
{
Set<Long> avmNodeIds = indirections.get(Long.valueOf(descriptor.getId()));
if (avmNodeIds != null)
{
for (Long id : avmNodeIds)
{
// need to fix up inheritance as is has changed
AVMNodeDescriptor layerDesc = new AVMNodeDescriptor(null, null, 0, null, null, null, 0, 0, 0, id, null, 0, null, 0, false, 0, false, 0, 0);
List<Pair<Integer, String>> layerPaths = fAVMRepository.getHeadPaths(layerDesc);
// Update all locations with the updated ACL
for (Pair<Integer, String> layerPath : layerPaths)
{
DbAccessControlList target = getAclAsSystem(-1, layerPath.getSecond());
if (target != null)
{
if (target.getAclType() == ACLType.LAYERED)
{
fAVMService.forceCopy(layerPath.getSecond());
List<AclChange> layeredChanges = aclDaoComponent.mergeInheritedAccessControlList(inherited, target.getId());
NodeRef layeredNode = AVMNodeConverter.ToNodeRef(-1, layerPath.getSecond());
for (AclChange change : layeredChanges)
{
if (change.getBefore().equals(target.getId()))
{
Long newInherited = null;
if (change.getAfter() != null)
{
newInherited = aclDaoComponent.getInheritedAccessControlList(change.getAfter());
}
updateChangedAclsImpl(layeredNode, layeredChanges, SetMode.DIRECT_ONLY, newInherited, change.getAfter(), indirections);
break;
}
}
}
}
}
}
}
}
}
catch (AVMException e)
{
throw new InvalidNodeRefException(node);
}
}
private void updateLayeredAclsChangedByInheritance(List<AclChange> changes, HashMap<Long, Long> changeMap, Set<Long> unchanged, Map<Long, Set<Long>> indirections)
{
for (AclChange change : changes)
{
if ((change.getTypeBefore() == ACLType.LAYERED) && (change.getTypeAfter() == ACLType.LAYERED))
{
// Query for affected nodes
List<Long> avmNodeIds = aclDaoComponent.getAvmNodesByACL(change.getBefore());
for (Long id : avmNodeIds)
{
// Find all paths to the nodes
AVMNodeDescriptor desc = new AVMNodeDescriptor(null, null, 0, null, null, null, 0, 0, 0, id, null, 0, null, 0, false, 0, false, 0, 0);
List<Pair<Integer, String>> paths = fAVMRepository.getHeadPaths(desc);
// Update all locations with the updated ACL
for (Pair<Integer, String> path : paths)
{
// No need to force COW - any inherited ACL will have COWED if the top ACL required it
setAclAsSystem(path.getSecond(), aclDaoComponent.getDbAccessControlList(change.getAfter()));
NodeRef layeredNode = AVMNodeConverter.ToNodeRef(-1, path.getSecond());
updateInheritedChangedAcls(layeredNode, changeMap, unchanged, aclDaoComponent.getInheritedAccessControlList(change.getAfter()), SetMode.DIRECT_ONLY,
indirections);
}
}
}
}
}
private void updateInheritedChangedAcls(NodeRef startingPoint, HashMap<Long, Long> changeMap, Set<Long> unchanged, Long unsetAcl, SetMode mode,
Map<Long, Set<Long>> indirections)
{
// Walk children and fix up any that reference the given list ..
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(startingPoint);
int version = avmVersionPath.getFirst();
if (version >= 0)
{
throw new InvalidNodeRefException("Read Only Node.", startingPoint);
}
String path = avmVersionPath.getSecond();
try
{
AVMNodeDescriptor descriptor = fAVMService.lookup(version, path);
if (descriptor == null)
{
return;
}
else
{
if (descriptor.isLayeredDirectory())
{
setInheritanceForDirectChildren(descriptor, changeMap, aclDaoComponent.getInheritedAccessControlList(getAclAsSystem(-1, descriptor.getPath()).getId()),
indirections);
}
fixUpAcls(descriptor, changeMap, unchanged, unsetAcl, mode, indirections);
}
}
catch (AVMException e)
{
throw new InvalidNodeRefException(startingPoint);
}
}
private void fixUpAcls(AVMNodeDescriptor descriptor, Map<Long, Long> changes, Set<Long> unchanged, Long unsetAcl, SetMode mode, Map<Long, Set<Long>> indirections)
{
DbAccessControlList acl = getAclAsSystem(-1, descriptor.getPath());
Long id = null;
if (acl != null)
{
id = acl.getId();
}
if (id == null)
{
// No need to force COW - ACL should have COWed if required
setAclAsSystem(descriptor.getPath(), aclDaoComponent.getDbAccessControlList(unsetAcl));
NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, descriptor.getPath());
updateReferencingLayeredAcls(nodeRef, unsetAcl, indirections);
}
else if (changes.containsKey(id))
{
Long updateId = changes.get(id);
if (updateId != id)
{
DbAccessControlList newAcl = aclDaoComponent.getDbAccessControlList(updateId);
// No need to force COW - ACL should have COWed if required
setAclAsSystem(descriptor.getPath(), newAcl);
}
}
else if (unchanged.contains(id))
{
// carry on
}
else
{
// Not in the list
return;
}
if (descriptor.isDirectory())
{
Map<String, AVMNodeDescriptor> children;
switch (mode)
{
case ALL:
children = fAVMService.getDirectoryListing(descriptor, false);
break;
case DIRECT_ONLY:
children = fAVMService.getDirectoryListingDirect(descriptor, false);
break;
default:
throw new IllegalStateException();
}
for (AVMNodeDescriptor child : children.values())
{
hibernateSessionHelper.mark();
try
{
fixUpAcls(child, changes, unchanged, unsetAcl, mode, indirections);
}
finally
{
hibernateSessionHelper.resetAndRemoveMark();
}
}
}
}
private void setInheritanceForDirectChildren(AVMNodeDescriptor descriptor, Map<Long, Long> changeMap, Long mergeFrom, Map<Long, Set<Long>> indirections)
{
List<AclChange> changes = new ArrayList<AclChange>();
setFixedAcls(descriptor, mergeFrom, changes, SetMode.DIRECT_ONLY, false, indirections);
for (AclChange change : changes)
{
if (!change.getBefore().equals(change.getAfter()))
{
changeMap.put(change.getBefore(), change.getAfter());
}
}
}
public List<AclChange> setInheritanceForChildren(NodeRef parent, Long mergeFrom)
{
// Walk children and fix up any that reference the given list ..
// If previous is null we need to visit all descendants with a null acl and set
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(parent);
int version = avmVersionPath.getFirst();
if (version >= 0)
{
throw new InvalidNodeRefException("Read Only Node.", parent);
}
String path = avmVersionPath.getSecond();
try
{
Map<Long, Set<Long>> indirections = buildIndirections();
List<AclChange> changes = new ArrayList<AclChange>();
AVMNodeDescriptor descriptor = fAVMService.lookup(version, path);
setFixedAcls(descriptor, mergeFrom, changes, SetMode.ALL, false, indirections);
return changes;
}
catch (AVMException e)
{
throw new InvalidNodeRefException(parent);
}
}
/**
* Set and cascade ACls
*
* @param descriptor
* @param mergeFrom
* @param changes
* @param mode
* @param set
* @param indirections
*/
public void setFixedAcls(AVMNodeDescriptor descriptor, Long mergeFrom, List<AclChange> changes, SetMode mode, boolean set, Map<Long, Set<Long>> indirections)
{
if (descriptor == null)
{
return;
}
else
{
if (set)
{
// Simple set does not require any special COW wire up
// The AVM node will COW as required
DbAccessControlList previous = getAclAsSystem(-1, descriptor.getPath());
setAclAsSystem(descriptor.getPath(), aclDaoComponent.getDbAccessControlList(mergeFrom));
if (previous == null)
{
NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, descriptor.getPath());
updateReferencingLayeredAcls(nodeRef, mergeFrom, indirections);
}
}
if (descriptor.isDirectory())
{
Map<String, AVMNodeDescriptor> children;
switch (mode)
{
case ALL:
children = fAVMService.getDirectoryListing(descriptor, false);
break;
case DIRECT_ONLY:
children = fAVMService.getDirectoryListingDirect(descriptor, false);
break;
default:
throw new IllegalStateException();
}
for (String key : children.keySet())
{
AVMNodeDescriptor child = children.get(key);
DbAccessControlList acl = getAclAsSystem(-1, child.getPath());
if (acl == null)
{
hibernateSessionHelper.mark();
try
{
setFixedAcls(child, mergeFrom, changes, mode, true, indirections);
}
finally
{
hibernateSessionHelper.resetAndRemoveMark();
}
}
else if (acl.getAclType() == ACLType.LAYERED)
{
// nothing to do
}
else if (acl.getAclType() == ACLType.DEFINING)
{
// Can require copy on right to be triggered for ACLS
// So we force a copy on write (which marks ACLS and below to copy if required)
fAVMService.forceCopy(child.getPath());
List<AclChange> newChanges = aclDaoComponent.mergeInheritedAccessControlList(mergeFrom, acl.getId());
for (AclChange change : newChanges)
{
if (change.getBefore().equals(acl.getId()))
{
hibernateSessionHelper.mark();
try
{
setAclAsSystem(child.getPath(), aclDaoComponent.getDbAccessControlList(change.getAfter()));
setFixedAcls(child, aclDaoComponent.getInheritedAccessControlList(change.getAfter()), newChanges, SetMode.DIRECT_ONLY, false, indirections);
changes.addAll(newChanges);
break;
}
finally
{
hibernateSessionHelper.resetAndRemoveMark();
}
}
}
}
else
{
hibernateSessionHelper.mark();
try
{
setFixedAcls(child, mergeFrom, changes, mode, true, indirections);
}
finally
{
hibernateSessionHelper.resetAndRemoveMark();
}
}
}
}
}
}
/**
* Mode to sue when setting ACLs
* @author andyh
*
*/
private enum SetMode
{
/**
* Set ALL
*/
ALL,
/**
* Set only direct children (not those present by layering)
*/
DIRECT_ONLY;
}
public Map<ACLType, Integer> patchAcls()
{
CounterSet result = new CounterSet();
List<AVMStoreDescriptor> stores = fAVMService.getStores();
Map<Long, Set<Long>> indirections = buildIndirections();
for (AVMStoreDescriptor store : stores)
{
AVMNodeDescriptor root = fAVMService.getStoreRoot(-1, store.getName());
CounterSet update;
switch (avmSnapShotTriggeredIndexingMethodInterceptor.getStoreType(store.getName()))
{
case AUTHOR:
case AUTHOR_PREVIEW:
case AUTHOR_WORKFLOW:
case AUTHOR_WORKFLOW_PREVIEW:
case STAGING:
case STAGING_PREVIEW:
case WORKFLOW:
case WORKFLOW_PREVIEW:
AVMNodeDescriptor www = fAVMService.lookup(-1, store.getName() + ":/www");
update = fixOldAvmAcls(www, false, indirections);
result.add(update);
break;
case UNKNOWN:
default:
update = fixOldAvmAcls(root, true, indirections);
result.add(update);
}
}
HashMap<ACLType, Integer> toReturn = new HashMap<ACLType, Integer>();
toReturn.put(ACLType.DEFINING, Integer.valueOf(result.get(ACLType.DEFINING).getCounter()));
toReturn.put(ACLType.FIXED, Integer.valueOf(result.get(ACLType.FIXED).getCounter()));
toReturn.put(ACLType.GLOBAL, Integer.valueOf(result.get(ACLType.GLOBAL).getCounter()));
toReturn.put(ACLType.LAYERED, Integer.valueOf(result.get(ACLType.LAYERED).getCounter()));
toReturn.put(ACLType.OLD, Integer.valueOf(result.get(ACLType.OLD).getCounter()));
toReturn.put(ACLType.SHARED, Integer.valueOf(result.get(ACLType.SHARED).getCounter()));
return toReturn;
}
private CounterSet fixOldAvmAcls(AVMNodeDescriptor node, boolean searchDirectories, Map<Long, Set<Long>> indirections)
{
hibernateSessionHelper.mark();
try
{
return fixOldAvmAclsImpl(node, searchDirectories, indirections);
}
finally
{
hibernateSessionHelper.resetAndRemoveMark();
}
}
private CounterSet fixOldAvmAclsImpl(AVMNodeDescriptor node, boolean searchDirectories, Map<Long, Set<Long>> indirections)
{
CounterSet result = new CounterSet();
// Do the children first
if (searchDirectories && node.isDirectory())
{
Map<String, AVMNodeDescriptor> children = fAVMRepository.getListingDirect(node, true);
for (AVMNodeDescriptor child : children.values())
{
CounterSet update = fixOldAvmAcls(child, searchDirectories, indirections);
result.add(update);
}
}
DbAccessControlList existingAcl = getAclAsSystem(-1, node.getPath());
if (existingAcl != null)
{
if (existingAcl.getAclType() == ACLType.OLD)
{
result.increment(ACLType.DEFINING);
//
SimpleAccessControlListProperties properties = new SimpleAccessControlListProperties();
properties.setAclType(ACLType.DEFINING);
// Accept default versioning
Long id = aclDaoComponent.createAccessControlList(properties);
DbAccessControlList newAcl = aclDaoComponent.getDbAccessControlList(id);
AccessControlList existing = aclDaoComponent.getAccessControlList(existingAcl.getId());
for (AccessControlEntry entry : existing.getEntries())
{
if (entry.getPosition() == 0)
{
aclDaoComponent.setAccessControlEntry(id, entry);
}
}
setAclAsSystem(node.getPath(), newAcl);
// Cascade to children - changes should all be 1-1 so we do not have to post fix
List<AclChange> changes = new ArrayList<AclChange>();
setFixedAcls(node, aclDaoComponent.getInheritedAccessControlList(id), changes, SetMode.DIRECT_ONLY, false, indirections);
for (AclChange change : changes)
{
if (!change.getBefore().equals(change.getAfter()))
{
throw new IllegalStateException("ACL fix should not change the acl ids - unexpected COW!");
}
}
}
else
{
throw new IllegalStateException();
}
}
else if (node.isLayeredDirectory())
{
result.increment(ACLType.LAYERED);
// create layered permission entry
if (node.getIndirection() != null)
{
AVMNodeDescriptor referencedNode = fAVMService.lookup(-1, node.getIndirection(), false);
if ((referencedNode != null) && (referencedNode.isDirectory()))
{
DbAccessControlList acl = getAclAsSystem(-1, referencedNode.getPath());
if (acl != null)
{
setAclAsSystem(node.getPath(), DbAccessControlListImpl.createLayeredAcl(acl.getId()));
}
else
{
setAclAsSystem(node.getPath(), DbAccessControlListImpl.createLayeredAcl(null));
}
}
else
{
setAclAsSystem(node.getPath(), DbAccessControlListImpl.createLayeredAcl(null));
}
}
else
{
setAclAsSystem(node.getPath(), DbAccessControlListImpl.createLayeredAcl(null));
}
List<AclChange> changes = new ArrayList<AclChange>();
setFixedAcls(node, aclDaoComponent.getInheritedAccessControlList(getAclAsSystem(-1, node.getPath()).getId()), changes, SetMode.DIRECT_ONLY, false, indirections);
for (AclChange change : changes)
{
if (!change.getBefore().equals(change.getAfter()))
{
throw new IllegalStateException("ACL fix should not change the acl ids - unexpected COW!");
}
}
}
else if (node.isLayeredFile())
{
result.increment(ACLType.LAYERED);
if (node.getIndirection() != null)
{
AVMNodeDescriptor referencedNode = fAVMService.lookup(-1, node.getIndirection(), false);
if (referencedNode != null)
{
DbAccessControlList acl = getAclAsSystem(-1, referencedNode.getPath());
if (acl != null)
{
setAclAsSystem(node.getPath(), DbAccessControlListImpl.createLayeredAcl(acl.getId()));
}
else
{
setAclAsSystem(node.getPath(), DbAccessControlListImpl.createLayeredAcl(null));
}
}
else
{
setAclAsSystem(node.getPath(), DbAccessControlListImpl.createLayeredAcl(null));
}
}
else
{
setAclAsSystem(node.getPath(), DbAccessControlListImpl.createLayeredAcl(null));
}
List<AclChange> changes = new ArrayList<AclChange>();
setFixedAcls(node, aclDaoComponent.getInheritedAccessControlList(getAclAsSystem(-1, node.getPath()).getId()), changes, SetMode.DIRECT_ONLY, false, indirections);
for (AclChange change : changes)
{
if (!change.getBefore().equals(change.getAfter()))
{
throw new IllegalStateException("ACL fix should not change the acl ids - unexpected COW!");
}
}
}
return result;
}
/**
*
* Counter for each type of ACL change
* @author andyh
*
*/
public static class CounterSet extends HashMap<ACLType, Counter>
{
/**
*
*/
private static final long serialVersionUID = -3682278258679211481L;
CounterSet()
{
super();
this.put(ACLType.DEFINING, new Counter());
this.put(ACLType.FIXED, new Counter());
this.put(ACLType.GLOBAL, new Counter());
this.put(ACLType.LAYERED, new Counter());
this.put(ACLType.OLD, new Counter());
this.put(ACLType.SHARED, new Counter());
}
void add(ACLType type, Counter c)
{
Counter counter = get(type);
counter.add(c.getCounter());
}
void increment(ACLType type)
{
Counter counter = get(type);
counter.increment();
}
void add(CounterSet other)
{
add(ACLType.DEFINING, other.get(ACLType.DEFINING));
add(ACLType.FIXED, other.get(ACLType.FIXED));
add(ACLType.GLOBAL, other.get(ACLType.GLOBAL));
add(ACLType.LAYERED, other.get(ACLType.LAYERED));
add(ACLType.OLD, other.get(ACLType.OLD));
add(ACLType.SHARED, other.get(ACLType.SHARED));
}
}
/**
* Simple counter
* @author andyh
*
*/
public static class Counter
{
int counter;
void increment()
{
counter++;
}
int getCounter()
{
return counter;
}
void add(int i)
{
counter += i;
}
}
private DbAccessControlList getStoreAclAsSystem(final String storeName)
{
return AuthenticationUtil.runAs(new RunAsWork<DbAccessControlList>()
{
public DbAccessControlList doWork() throws Exception
{
return fAVMRepository.getStoreAcl(storeName);
}
}, AuthenticationUtil.getSystemUserName());
}
private void setStoreAclAsSystem(final String storeName, final DbAccessControlList acl)
{
AuthenticationUtil.runAs(new RunAsWork<Object>()
{
public Object doWork() throws Exception
{
fAVMRepository.setStoreAcl(storeName, acl);
return null;
}
}, AuthenticationUtil.getSystemUserName());
}
private DbAccessControlList getAclAsSystem(final int version, final String path)
{
return AuthenticationUtil.runAs(new RunAsWork<DbAccessControlList>()
{
public DbAccessControlList doWork() throws Exception
{
return fAVMRepository.getACL(version, path);
}
}, AuthenticationUtil.getSystemUserName());
}
private void setAclAsSystem(final String path, final DbAccessControlList acl)
{
AuthenticationUtil.runAs(new RunAsWork<Object>()
{
public Object doWork() throws Exception
{
fAVMRepository.setACL(path, acl);
return null;
}
}, AuthenticationUtil.getSystemUserName());
}
public DbAccessControlList getAccessControlList(StoreRef storeRef)
{
try
{
return getStoreAclAsSystem(storeRef.getIdentifier());
}
catch (AVMException e)
{
throw new InvalidStoreRefException(storeRef);
}
}
public void setAccessControlList(StoreRef storeRef, DbAccessControlList acl)
{
try
{
setStoreAclAsSystem(storeRef.getIdentifier(), acl);
}
catch (AVMException e)
{
throw new InvalidStoreRefException(storeRef);
}
}
}
The table below shows all metrics for AVMAccessControlListDAO.java.




