Merged V2.2 to HEAD

7732: Support to cache null QName look ups ...
   7733: Support for store ACLs
   7741: Fix for over keen stiore ACLs ....
   7794: Fix for WCM-1019, tasks show all assets as modified when only one has
   7996: Fix for AWC-1519: cancelling discussion creation results in error


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@8448 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2008-03-07 01:50:03 +00:00
parent 513a32a71b
commit 6ce34484fc
22 changed files with 838 additions and 129 deletions

View File

@@ -46,9 +46,7 @@ import org.alfresco.service.namespace.RegexQNamePattern;
/**
* Remove ACLs on all but staging area stores On staging area stores, set ACls according to the users and roles as set
* on the web site
*
* Note: runs as the system user
* on the web site Note: runs as the system user
*
* @author andyh
*/
@@ -61,7 +59,7 @@ public class WCMPermissionPatch extends AbstractPatch
AVMService avmService;
PermissionService permissionService;
public void setAvmService(AVMService avmService)
{
this.avmService = avmService;
@@ -88,6 +86,7 @@ public class WCMPermissionPatch extends AbstractPatch
/* Set permissions in staging */
case STAGING:
setStagingAreaPermissions(store);
setStagingAreaMasks(store);
// TODO: mark read only
break;
/* Clear permissions */
@@ -97,9 +96,11 @@ public class WCMPermissionPatch extends AbstractPatch
case AUTHOR_WORKFLOW_PREVIEW:
// TODO: add app access control
clearPermissions(store);
setSandBoxMasks(store);
break;
case STAGING_PREVIEW:
clearPermissions(store);
setStagingAreaMasks(store);
// TODO: mark read only
break;
case WORKFLOW:
@@ -109,7 +110,6 @@ public class WCMPermissionPatch extends AbstractPatch
/* non WCM stores - nothing to do */
case UNKNOWN:
default:
break;
}
}
@@ -122,7 +122,7 @@ public class WCMPermissionPatch extends AbstractPatch
private void clearPermissions(AVMStoreDescriptor store)
{
AVMNodeDescriptor www = avmService.lookup(-1, store.getName() + ":/www");
if(www.isLayeredDirectory() && www.isPrimary())
if (www.isLayeredDirectory() && www.isPrimary())
{
// throw away any acl
AVMRepository.GetInstance().setACL(store.getName() + ":/www", null);
@@ -130,7 +130,6 @@ public class WCMPermissionPatch extends AbstractPatch
avmService.retargetLayeredDirectory(store.getName() + ":/www", www.getIndirection());
}
}
private void setStagingAreaPermissions(AVMStoreDescriptor store)
{
@@ -143,8 +142,8 @@ public class WCMPermissionPatch extends AbstractPatch
if (pValue != null)
{
NodeRef webProjectNodeRef = (NodeRef)pValue.getValue(DataTypeDefinition.NODE_REF);
NodeRef webProjectNodeRef = (NodeRef) pValue.getValue(DataTypeDefinition.NODE_REF);
// Apply sepcific user permissions as set on the web project
List<ChildAssociationRef> userInfoRefs = nodeService.getChildAssocs(webProjectNodeRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL);
for (ChildAssociationRef ref : userInfoRefs)
@@ -158,4 +157,75 @@ public class WCMPermissionPatch extends AbstractPatch
}
}
private void setStagingAreaMasks(AVMStoreDescriptor store)
{
NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, store.getName() + ":/www");
permissionService.setPermission(dirRef.getStoreRef(), PermissionService.ALL_AUTHORITIES, PermissionService.READ, true);
}
private void setSandBoxMasks(AVMStoreDescriptor sandBoxStore)
{
// get the settings from the staging store ...
String owner = extractOwner(sandBoxStore.getName());
String stagingAreaName = extractStagingAreaName(sandBoxStore.getName());
QName propQName = QName.createQName(null, ".web_project.noderef");
NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, sandBoxStore.getName() + ":/www");
PropertyValue pValue = avmService.getStoreProperty(stagingAreaName, propQName);
permissionService.setPermission(dirRef.getStoreRef(), PermissionService.ALL_AUTHORITIES, PermissionService.READ, true);
if (pValue != null)
{
NodeRef webProjectNodeRef = (NodeRef) pValue.getValue(DataTypeDefinition.NODE_REF);
// Apply sepcific user permissions as set on the web project
List<ChildAssociationRef> userInfoRefs = nodeService.getChildAssocs(webProjectNodeRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL);
for (ChildAssociationRef ref : userInfoRefs)
{
NodeRef userInfoRef = ref.getChildRef();
String username = (String) nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME);
String userrole = (String) nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE);
if (username.equals(owner))
{
permissionService.setPermission(dirRef.getStoreRef(), username, PermissionService.ALL_PERMISSIONS, true);
}
else if (userrole.equals("ContentManager"))
{
permissionService.setPermission(dirRef.getStoreRef(), username, userrole, true);
}
}
}
}
private String extractOwner(String name)
{
int start = name.indexOf("--");
if (start == -1)
{
throw new UnsupportedOperationException(name);
}
int end = name.indexOf("--", start + 1);
if (end == -1)
{
return name.substring(start+2);
}
return name.substring(start + 2, end);
}
private String extractStagingAreaName(String name)
{
int index = name.indexOf("--");
if (index == -1)
{
throw new UnsupportedOperationException(name);
}
return name.substring(0, index);
}
}

View File

@@ -3230,13 +3230,29 @@ public class AVMRepository
if (storeAcl != null)
{
Long storeAclID = storeAcl.getId();
context.getAdditionalContext().put("STORE_ACL_ID", storeAclID);
context.setStoreAcl(storeAclID);
}
}
return fPermissionService.hasPermission(aclId, context, permission)
== AccessStatus.ALLOWED;
}
public boolean can(String storeName, int version, String path, String permission)
{
Lookup lookup = AVMRepository.GetInstance().lookup(version, path, true);
if (lookup != null)
{
AVMNode node = lookup.getCurrentNode();
AVMStore store = getAVMStoreByName(storeName);
return can(store, node, permission);
}
else
{
// Does not exist => allowed
return true;
}
}
/**
* Set the acl on a store.
* @param storeName

View File

@@ -75,7 +75,7 @@ import junit.framework.TestCase;
/**
* Specifically test AVM permissions with the updated ACL schema
*
*
* @author andyh
*/
public class AVMServicePermissionsTest extends TestCase
@@ -139,7 +139,7 @@ public class AVMServicePermissionsTest extends TestCase
aclDaoComponent = (AclDaoComponent) applicationContext.getBean("aclDaoComponent");
avmService = (AVMService) applicationContext.getBean("avmService");
avmSyncService = (AVMSyncService)applicationContext.getBean("AVMSyncService");
avmSyncService = (AVMSyncService) applicationContext.getBean("AVMSyncService");
nodeService = (NodeService) applicationContext.getBean("nodeService");
dictionaryService = (DictionaryService) applicationContext.getBean(ServiceRegistry.DICTIONARY_SERVICE.getLocalName());
@@ -328,7 +328,9 @@ public class AVMServicePermissionsTest extends TestCase
runAs(user);
AVMNodeDescriptor desc = avmService.lookup(-1, path);
AVMNode node = avmNodeDAO.getByID(desc.getId());
boolean can = AVMRepository.GetInstance().can(null, node, permission);
NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, path);
AVMStore store = AVMDAOs.Instance().fAVMStoreDAO.getByName(nodeRef.getStoreRef().getIdentifier());
boolean can = AVMRepository.GetInstance().can(store, node, permission);
return allowed ? can : !can;
}
finally
@@ -345,14 +347,17 @@ public class AVMServicePermissionsTest extends TestCase
runAs(user);
AVMNodeDescriptor desc = avmService.lookup(-1, path);
AVMNode node = avmNodeDAO.getByID(desc.getId());
boolean can = AVMRepository.GetInstance().can(null, node, permission);
NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, path);
AVMStore store = AVMDAOs.Instance().fAVMStoreDAO.getByName(nodeRef.getStoreRef().getIdentifier());
boolean can = AVMRepository.GetInstance().can(store, node, permission);
long start = System.nanoTime();
for(int i = 0; i < count; i++)
for (int i = 0; i < count; i++)
{
can = AVMRepository.GetInstance().can(null, node, permission);
}
long end = System.nanoTime();
System.out.println("Can in "+((end-start)/1.0e9f));
System.out.println("Can in " + ((end - start) / 10e9f / count));
System.out.println("Can per second " + (1 / ((end - start) / 10e9f / count)));
return allowed ? can : !can;
}
finally
@@ -370,12 +375,13 @@ public class AVMServicePermissionsTest extends TestCase
NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, path);
boolean can = permissionService.hasPermission(nodeRef, permission) == AccessStatus.ALLOWED;
long start = System.nanoTime();
for(int i = 0; i < count; i++)
for (int i = 0; i < count; i++)
{
can = permissionService.hasPermission(nodeRef, permission) == AccessStatus.ALLOWED;
}
long end = System.nanoTime();
System.out.println("Has Permission in "+((end-start)/1.0e9f));
System.out.println("Has Permission in " + ((end - start) / 10e9f / count));
System.out.println("Has Permission per second " + (1 / ((end - start) / 10e9f / count)));
return allowed ? can : !can;
}
finally
@@ -384,7 +390,114 @@ public class AVMServicePermissionsTest extends TestCase
}
}
public boolean checkHasPermission(String user, NodeRef nodeRef, String permission, boolean allowed)
{
String curentUser = AuthenticationUtil.getCurrentUserName();
try
{
runAs(user);
boolean can = permissionService.hasPermission(nodeRef, permission) == AccessStatus.ALLOWED;
return allowed ? can : !can;
}
finally
{
runAs(curentUser);
}
}
public void testStoreAcls() throws Exception
{
runAs("admin");
String storeName = "PermissionsTest-" + getName() + "-" + (new Date().getTime());
try
{
buildBaseStructure(storeName);
AVMNodeDescriptor nodeDesc = avmService.lookup(-1, storeName + ":/base");
NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, nodeDesc.getPath());
permissionService.setPermission(nodeRef, PermissionService.ALL_AUTHORITIES, PermissionService.ALL_PERMISSIONS, true);
assertTrue(checkPermission("andy", storeName + ":/base", PermissionService.ALL_PERMISSIONS, true));
assertTrue(checkHasPermission("andy", nodeRef, PermissionService.ALL_PERMISSIONS, true));
assertTrue(checkPermission("lemur", storeName + ":/base", PermissionService.ALL_PERMISSIONS, true));
assertTrue(checkHasPermission("lemur", nodeRef, PermissionService.ALL_PERMISSIONS, true));
assertTrue(checkPermission("admin", storeName + ":/base", PermissionService.ALL_PERMISSIONS, true));
assertTrue(checkHasPermission("admin", nodeRef, PermissionService.ALL_PERMISSIONS, true));
permissionService.setPermission(nodeRef.getStoreRef(), "andy", PermissionService.ALL_PERMISSIONS, true);
assertTrue(checkPermission("andy", storeName + ":/base", PermissionService.ALL_PERMISSIONS, true));
assertTrue(checkHasPermission("andy", nodeRef, PermissionService.ALL_PERMISSIONS, true));
assertTrue(checkPermission("lemur", storeName + ":/base", PermissionService.ALL_PERMISSIONS, false));
assertTrue(checkHasPermission("lemur", nodeRef, PermissionService.ALL_PERMISSIONS, false));
assertTrue(checkPermission("admin", storeName + ":/base", PermissionService.ALL_PERMISSIONS, true));
assertTrue(checkHasPermission("admin", nodeRef, PermissionService.ALL_PERMISSIONS, true));
permissionService.deletePermission(nodeRef.getStoreRef(), "andy", PermissionService.ALL_PERMISSIONS);
assertTrue(checkPermission("andy", storeName + ":/base", PermissionService.ALL_PERMISSIONS, false));
assertTrue(checkHasPermission("andy", nodeRef, PermissionService.ALL_PERMISSIONS, false));
assertTrue(checkPermission("lemur", storeName + ":/base", PermissionService.ALL_PERMISSIONS, false));
assertTrue(checkHasPermission("lemur", nodeRef, PermissionService.ALL_PERMISSIONS, false));
assertTrue(checkPermission("admin", storeName + ":/base", PermissionService.ALL_PERMISSIONS, true));
assertTrue(checkHasPermission("admin", nodeRef, PermissionService.ALL_PERMISSIONS, true));
permissionService.deletePermissions(nodeRef.getStoreRef());
assertTrue(checkPermission("andy", storeName + ":/base", PermissionService.ALL_PERMISSIONS, true));
assertTrue(checkHasPermission("andy", nodeRef, PermissionService.ALL_PERMISSIONS, true));
assertTrue(checkPermission("lemur", storeName + ":/base", PermissionService.ALL_PERMISSIONS, true));
assertTrue(checkHasPermission("lemur", nodeRef, PermissionService.ALL_PERMISSIONS, true));
assertTrue(checkPermission("admin", storeName + ":/base", PermissionService.ALL_PERMISSIONS, true));
assertTrue(checkHasPermission("admin", nodeRef, PermissionService.ALL_PERMISSIONS, true));
permissionService.setPermission(nodeRef.getStoreRef(), "andy", PermissionService.ALL_PERMISSIONS, true);
assertTrue(checkHasPermission("andy", nodeRef, PermissionService.ALL_PERMISSIONS, true));
permissionService.setPermission(nodeRef.getStoreRef(), "andy", PermissionService.READ, true);
permissionService.setPermission(nodeRef.getStoreRef(), "lemur", PermissionService.ALL_PERMISSIONS, true);
assertTrue(checkPermission("andy", storeName + ":/base", PermissionService.ALL_PERMISSIONS, true));
assertTrue(checkHasPermission("andy", nodeRef, PermissionService.ALL_PERMISSIONS, true));
assertTrue(checkPermission("lemur", storeName + ":/base", PermissionService.ALL_PERMISSIONS, true));
assertTrue(checkHasPermission("lemur", nodeRef, PermissionService.ALL_PERMISSIONS, true));
assertTrue(checkPermission("admin", storeName + ":/base", PermissionService.ALL_PERMISSIONS, true));
assertTrue(checkHasPermission("admin", nodeRef, PermissionService.ALL_PERMISSIONS, true));
assertEquals(permissionService.getAllSetPermissions(nodeRef.getStoreRef()).size(), 3);
permissionService.clearPermission(nodeRef.getStoreRef(), "andy");
assertTrue(checkPermission("andy", storeName + ":/base", PermissionService.ALL_PERMISSIONS, false));
assertTrue(checkHasPermission("andy", nodeRef, PermissionService.ALL_PERMISSIONS, false));
assertTrue(checkPermission("lemur", storeName + ":/base", PermissionService.ALL_PERMISSIONS, true));
assertTrue(checkHasPermission("lemur", nodeRef, PermissionService.ALL_PERMISSIONS, true));
assertTrue(checkPermission("admin", storeName + ":/base", PermissionService.ALL_PERMISSIONS, true));
assertTrue(checkHasPermission("admin", nodeRef, PermissionService.ALL_PERMISSIONS, true));
assertEquals(permissionService.getAllSetPermissions(nodeRef.getStoreRef()).size(), 1);
permissionService.clearPermission(nodeRef.getStoreRef(), "lemur");
assertTrue(checkPermission("andy", storeName + ":/base", PermissionService.ALL_PERMISSIONS, false));
assertTrue(checkHasPermission("andy", nodeRef, PermissionService.ALL_PERMISSIONS, false));
assertTrue(checkPermission("lemur", storeName + ":/base", PermissionService.ALL_PERMISSIONS, false));
assertTrue(checkHasPermission("lemur", nodeRef, PermissionService.ALL_PERMISSIONS, false));
assertTrue(checkPermission("admin", storeName + ":/base", PermissionService.ALL_PERMISSIONS, true));
assertTrue(checkHasPermission("admin", nodeRef, PermissionService.ALL_PERMISSIONS, true));
}
finally
{
avmService.purgeStore(storeName);
avmService.purgeStore(storeName + "-layer-base");
avmService.purgeStore(storeName + "-layer-a");
avmService.purgeStore(storeName + "-layer-b");
avmService.purgeStore(storeName + "-layer-c");
avmService.purgeStore(storeName + "-layer-d");
avmService.purgeStore(storeName + "-layer-layer-base");
avmService.purgeStore(storeName + "-layer-layer-layer-base");
}
}
public void testSimpleUpdate() throws Exception
{
@@ -415,7 +528,6 @@ public class AVMServicePermissionsTest extends TestCase
assertNotNull(fileAcl);
assertTrue(acl.getId() == fileAcl.getId());
avmService.createSnapshot(storeName, "store", "store");
avmService.createSnapshot(storeName + "-layer-base", "store", "store");
@@ -423,7 +535,6 @@ public class AVMServicePermissionsTest extends TestCase
avmSyncService.update(diffs, null, false, false, false, false, "A", "A");
desc = avmService.lookup(-1, storeName + ":/base/update-dir");
node = avmNodeDAO.getByID(desc.getId());
dirAcl = node.getAcl();
@@ -472,7 +583,6 @@ public class AVMServicePermissionsTest extends TestCase
Long baseAcl = avmNodeDAO.getByID(nodeDesc.getId()).getAcl().getId();
Long inheritedBaseAcl = aclDaoComponent.getInheritedAccessControlList(baseAcl);
avmService.createDirectory(storeName + "-layer-base:/layer-to-base", "update-dir");
avmService.createFile(storeName + "-layer-base:/layer-to-base/update-dir", "update-file").close();
@@ -495,7 +605,6 @@ public class AVMServicePermissionsTest extends TestCase
assertNotNull(fileAcl);
assertTrue(acl.getId() == fileAcl.getId());
avmService.createSnapshot(storeName, "store", "store");
avmService.createSnapshot(storeName + "-layer-base", "store", "store");
@@ -503,7 +612,6 @@ public class AVMServicePermissionsTest extends TestCase
avmSyncService.update(diffs, null, false, false, false, false, "A", "A");
desc = avmService.lookup(-1, storeName + ":/base/update-dir");
node = avmNodeDAO.getByID(desc.getId());
dirAcl = node.getAcl();
@@ -1860,7 +1968,7 @@ public class AVMServicePermissionsTest extends TestCase
finally
{
avmService.purgeStore(storeName);
avmService.purgeStore(storeName+"-a-");
avmService.purgeStore(storeName + "-a-");
}
}
@@ -2228,7 +2336,7 @@ public class AVMServicePermissionsTest extends TestCase
finally
{
avmService.purgeStore(storeName);
avmService.purgeStore(storeName+"-a-");
avmService.purgeStore(storeName + "-a-");
}
}
@@ -2547,7 +2655,7 @@ public class AVMServicePermissionsTest extends TestCase
finally
{
avmService.purgeStore(storeName);
avmService.purgeStore(storeName+"-a-");
avmService.purgeStore(storeName + "-a-");
}
}
@@ -2625,7 +2733,7 @@ public class AVMServicePermissionsTest extends TestCase
finally
{
avmService.purgeStore(storeName);
avmService.purgeStore(storeName+"-a-");
avmService.purgeStore(storeName + "-a-");
}
}
}

View File

@@ -30,6 +30,7 @@ import java.util.Set;
import org.alfresco.repo.security.permissions.ACLType;
import org.alfresco.repo.security.permissions.impl.AclChange;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
/**
* This abstracts the reading and writing of ACLs on nodes from particular node implementations.
@@ -84,4 +85,8 @@ public interface AccessControlListDAO
public void forceCopy(NodeRef nodeRef);
public Map<ACLType, Integer> patchAcls();
public DbAccessControlList getAccessControlList(StoreRef storeRef);
public void setAccessControlList(StoreRef storeRef, DbAccessControlList acl);
}

View File

@@ -52,5 +52,18 @@ public interface DbAuthority extends Serializable
* @param the authority
*/
public void setAuthority(String authority);
/**
* Use a crc to enforce case sensitive unique key
* @param crc
*/
public void setCrc(Long crc);
/**
* Get the CRC
*
* @return
*/
public Long getCrc();
}

View File

@@ -48,7 +48,9 @@ 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.Pair;
/**
@@ -814,7 +816,26 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
}
}
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)
{
@@ -836,4 +857,30 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
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);
}
}
}

View File

@@ -34,12 +34,14 @@ import java.util.Set;
import org.alfresco.repo.domain.AccessControlListDAO;
import org.alfresco.repo.domain.DbAccessControlList;
import org.alfresco.repo.security.permissions.ACEType;
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.NodePermissionEntry;
import org.alfresco.repo.security.permissions.PermissionEntry;
import org.alfresco.repo.security.permissions.PermissionReference;
import org.alfresco.repo.security.permissions.SimpleAccessControlEntry;
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.repo.security.permissions.impl.PermissionsDaoComponent;
@@ -48,6 +50,7 @@ import org.alfresco.repo.security.permissions.impl.SimplePermissionEntry;
import org.alfresco.repo.transaction.TransactionalDao;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AccessPermission;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.util.GUID;
@@ -267,6 +270,30 @@ public abstract class AbstractPermissionsDaoComponentImpl implements Permissions
return snpe;
}
}
private SimpleNodePermissionEntry createSimpleNodePermissionEntry(StoreRef storeRef)
{
DbAccessControlList acl = getACLDAO(storeRef).getAccessControlList(storeRef);
if (acl == null)
{
// there isn't an access control list for the node - spoof a null one
SimpleNodePermissionEntry snpe = new SimpleNodePermissionEntry(null, true, Collections.<SimplePermissionEntry> emptySet());
return snpe;
}
else
{
AccessControlList info = aclDaoComponent.getAccessControlList(acl.getId());
HashSet<SimplePermissionEntry> spes = new HashSet<SimplePermissionEntry>(info.getEntries().size(), 1.0f);
for (AccessControlEntry entry : info.getEntries())
{
SimplePermissionEntry spe = new SimplePermissionEntry(null, entry.getPermission(), entry.getAuthority(), entry.getAccessStatus());
spes.add(spe);
}
SimpleNodePermissionEntry snpe = new SimpleNodePermissionEntry(null, acl.getInherits(), spes);
return snpe;
}
}
public boolean getInheritParentPermissions(NodeRef nodeRef)
{
@@ -456,6 +483,117 @@ public abstract class AbstractPermissionsDaoComponentImpl implements Permissions
getACLDAO(nodeRef).updateChangedAcls(nodeRef, all);
}
public void deletePermission(StoreRef storeRef, String authority, PermissionReference permission)
{
DbAccessControlList acl = getAccessControlList(storeRef);
if(acl == null)
{
return;
}
acl = getMutableAccessControlList(storeRef);
SimpleAccessControlEntry pattern = new SimpleAccessControlEntry();
pattern.setAuthority(authority);
pattern.setPermission(permission);
aclDaoComponent.deleteAccessControlEntries(acl.getId(), pattern);
}
private DbAccessControlList getMutableAccessControlList(StoreRef storeRef)
{
DbAccessControlList acl = getACLDAO(storeRef).getAccessControlList(storeRef);
if(acl == null)
{
SimpleAccessControlListProperties properties = new SimpleAccessControlListProperties();
properties.setAclType(ACLType.DEFINING);
properties.setVersioned(false);
properties.setInherits(false);
// Accept default versioning
Long id = aclDaoComponent.createAccessControlList(properties);
acl = aclDaoComponent.getDbAccessControlList(id);
getACLDAO(storeRef).setAccessControlList(storeRef, acl);
}
return acl;
}
private AccessControlListDAO getACLDAO(StoreRef storeRef)
{
AccessControlListDAO ret = fProtocolToACLDAO.get(storeRef.getProtocol());
if (ret == null)
{
return fDefaultACLDAO;
}
return ret;
}
private DbAccessControlList getAccessControlList(StoreRef storeRef)
{
return getACLDAO(storeRef).getAccessControlList(storeRef);
}
public void deletePermissions(StoreRef storeRef, String authority)
{
DbAccessControlList acl = getAccessControlList(storeRef);
if(acl == null)
{
return;
}
acl = getMutableAccessControlList(storeRef);
SimpleAccessControlEntry pattern = new SimpleAccessControlEntry();
pattern.setAuthority(authority);
aclDaoComponent.deleteAccessControlEntries(acl.getId(), pattern);
}
public void deletePermissions(StoreRef storeRef)
{
getACLDAO(storeRef).setAccessControlList(storeRef, null);
}
public void setPermission(StoreRef storeRef, String authority, PermissionReference permission, boolean allow)
{
DbAccessControlList acl = getMutableAccessControlList(storeRef);
SimpleAccessControlEntry entry = new SimpleAccessControlEntry();
entry.setAuthority(authority);
entry.setPermission(permission);
entry.setAccessStatus(allow ? AccessStatus.ALLOWED : AccessStatus.DENIED);
entry.setAceType(ACEType.ALL);
aclDaoComponent.setAccessControlEntry(acl.getId(), entry);
}
public NodePermissionEntry getPermissions(StoreRef storeRef)
{
// Create the object if it is not found.
// Null objects are not cached in hibernate
// If the object does not exist it will repeatedly query to check its
// non existence.
NodePermissionEntry npe = null;
DbAccessControlList acl = null;
try
{
acl = getAccessControlList(storeRef);
}
catch (InvalidNodeRefException e)
{
// Do nothing.
}
if (acl == null)
{
// there isn't an access control list for the node - spoof a null one
SimpleNodePermissionEntry snpe = new SimpleNodePermissionEntry(null, true, Collections.<SimplePermissionEntry> emptySet());
npe = snpe;
}
else
{
npe = createSimpleNodePermissionEntry(storeRef);
}
return npe;
}
protected abstract CreationReport createAccessControlList(NodeRef nodeRef, boolean inherit, DbAccessControlList existing);
static class CreationReport

View File

@@ -30,6 +30,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.zip.CRC32;
import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.domain.DbAccessControlEntry;
@@ -94,7 +95,7 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
/** a transactionally-safe cache to be injected */
private SimpleCache<Long, AccessControlList> aclCache;
private enum WriteMode
{
TRUNCATE_INHERITED, ADD_INHERITED, CHANGE_INHERITED, REMOVE_INHERITED, INSERT_INHERITED, COPY_UPDATE_AND_INHERIT, COPY_ONLY;
@@ -106,15 +107,11 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
DbAccessControlListImpl.setAclDaoComponent(this);
}
public void setAclCache(SimpleCache<Long, AccessControlList> aclCache)
{
this.aclCache = aclCache;
}
public DbAccessControlList getDbAccessControlList(Long id)
{
if (id == null)
@@ -722,14 +719,18 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
for (Object[] ids : results)
{
// Delete acl entry
DbAccessControlListMember member = (DbAccessControlListMember) getHibernateTemplate().get(DbAccessControlListMemberImpl.class, (Long) ids[0]);
Long aclId = ((Long) ids[1]);
aclCache.remove(aclId);
DbAccessControlList list = (DbAccessControlList) getHibernateTemplate().get(DbAccessControlListImpl.class, aclId);
acls.add(new AclChangeImpl(aclId, aclId, list.getAclType(), list.getAclType()));
getHibernateTemplate().delete(member);
aces.add((Long) ids[2]);
String authorityFound = (String) ids[3];
if (authorityFound.equals(authority))
{
// Delete acl entry
DbAccessControlListMember member = (DbAccessControlListMember) getHibernateTemplate().get(DbAccessControlListMemberImpl.class, (Long) ids[0]);
Long aclId = ((Long) ids[1]);
aclCache.remove(aclId);
DbAccessControlList list = (DbAccessControlList) getHibernateTemplate().get(DbAccessControlListImpl.class, aclId);
acls.add(new AclChangeImpl(aclId, aclId, list.getAclType(), list.getAclType()));
getHibernateTemplate().delete(member);
aces.add((Long) ids[2]);
}
}
// remove ACEs
@@ -749,13 +750,16 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
{
Query query = session.getNamedQuery(QUERY_GET_AUTHORITY);
query.setParameter("authority", authority);
return query.uniqueResult();
return query.list();
}
};
DbAuthority dbAuthority = (DbAuthority) getHibernateTemplate().execute(callback);
if (dbAuthority != null)
List<DbAuthority> authorities = (List<DbAuthority>) getHibernateTemplate().execute(callback);
for (DbAuthority found : authorities)
{
getHibernateTemplate().delete(dbAuthority);
if (found.getAuthority().equals(authority))
{
getHibernateTemplate().delete(found);
}
}
// TODO: Remove affected ACLs from the cache
@@ -948,18 +952,18 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
public AccessControlList getAccessControlList(Long id)
{
AccessControlList acl = aclCache.get(id);
if(acl == null)
if (acl == null)
{
acl = getAccessControlListImpl(id);
aclCache.put(id, acl);
}
else
{
//System.out.println("Used cache for "+id);
// System.out.println("Used cache for "+id);
}
return acl;
}
@SuppressWarnings("unchecked")
public AccessControlList getAccessControlListImpl(final Long id)
{
@@ -1194,14 +1198,24 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
{
Query query = session.getNamedQuery(QUERY_GET_AUTHORITY);
query.setParameter("authority", ace.getAuthority());
return query.uniqueResult();
return query.list();
}
};
DbAuthority authority = (DbAuthority) getHibernateTemplate().execute(callback);
DbAuthority authority = null;
List<DbAuthority> authorities = (List<DbAuthority>) getHibernateTemplate().execute(callback);
for(DbAuthority found : authorities)
{
if(found.getAuthority().equals(ace.getAuthority()))
{
authority = found;
break;
}
}
if (authority == null)
{
DbAuthorityImpl newAuthority = new DbAuthorityImpl();
newAuthority.setAuthority(ace.getAuthority());
newAuthority.setCrc(getCrc(ace.getAuthority()));
authority = newAuthority;
getHibernateTemplate().save(newAuthority);
}
@@ -1280,6 +1294,14 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
return changes;
}
private long getCrc(String str)
{
CRC32 crc = new CRC32();
crc.update(str.getBytes());
return crc.getValue();
}
public List<AclChange> enableInheritance(Long id, Long parent)
{
List<AclChange> changes = new ArrayList<AclChange>();

View File

@@ -29,7 +29,6 @@ import java.io.Serializable;
import org.alfresco.repo.domain.DbAuthority;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.CallbackException;
import org.hibernate.Session;
/**
@@ -37,45 +36,44 @@ import org.hibernate.Session;
*
* @author andyh
*/
public class DbAuthorityImpl
implements DbAuthority, Serializable
public class DbAuthorityImpl implements DbAuthority, Serializable
{
private static final long serialVersionUID = -5582068692208928127L;
private static Log logger = LogFactory.getLog(DbAuthorityImpl.class);
private Long id;
private Long version;
private String authority;
private Long crc;
public DbAuthorityImpl()
{
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder(128);
sb.append("DbAuthorityImpl")
.append("[ id=").append(id)
.append(", version=").append(version)
.append(", authority=").append(authority)
.append("]");
sb.append("DbAuthorityImpl").append("[ id=").append(id).append(", version=").append(version).append(", authority=").append(authority).append("]");
return sb.toString();
}
@Override
public boolean equals(Object o)
{
if(this == o)
if (this == o)
{
return true;
}
if(!(o instanceof DbAuthority))
if (!(o instanceof DbAuthority))
{
return false;
}
DbAuthority other = (DbAuthority)o;
DbAuthority other = (DbAuthority) o;
return this.getAuthority().equals(other.getAuthority());
}
@@ -89,19 +87,29 @@ public class DbAuthorityImpl
{
return id;
}
@SuppressWarnings("unused")
private void setId(Long id)
{
this.id = id;
}
@SuppressWarnings("unused")
public void setCrc(Long crc)
{
this.crc = crc;
}
public Long getVersion()
{
return version;
}
public Long getCrc()
{
return crc;
}
/**
* For Hibernate use
*/
@@ -118,19 +126,21 @@ public class DbAuthorityImpl
public void setAuthority(String authority)
{
this.authority = authority;
this.authority = authority;
}
/**
* Helper method to find an authority based on its natural key
*
* @param session the Hibernate session to use
* @param authority the authority name
* @param session
* the Hibernate session to use
* @param authority
* the authority name
* @return Returns an existing instance or null if not found
*/
public static DbAuthority find(Session session, String authority)
{
// TODO: Needs to use a query
// TODO: Needs to use a query
throw new UnsupportedOperationException("TODO");
}
}

View File

@@ -164,6 +164,14 @@ public class HibernateQNameDAOImpl extends HibernateDaoSupport implements QNameD
// We found something, so we can add it to the cache
qnameEntityCache.put(qname, id);
}
else
{
qnameEntityCache.put(qname, -1L);
}
}
else if(id == -1L)
{
return null;
}
else
{

View File

@@ -36,6 +36,7 @@ import org.alfresco.repo.security.permissions.ACLType;
import org.alfresco.repo.security.permissions.impl.AclChange;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
/**
* The Node implementation for getting and setting ACLs.
@@ -146,4 +147,15 @@ public class NodeAccessControlListDAO implements AccessControlListDAO
throw new UnsupportedOperationException();
}
public DbAccessControlList getAccessControlList(StoreRef storeRef)
{
throw new UnsupportedOperationException();
}
public void setAccessControlList(StoreRef storeRef, DbAccessControlList acl)
{
throw new UnsupportedOperationException();
}
}

View File

@@ -193,13 +193,15 @@
lazy="false"
optimistic-lock="version" >
<id name="id" column="id" type="long" >
<id name="id" column="id" type="long" >
<generator class="native" />
</id>
<version column="version" name="version" type="long" />
<property name="authority" column="authority" type="string" length="100" unique="true"/>
<property name="authority" column="authority" type="string" length="100" unique-key="uidx_auth_name" index="idx_authority" />
<property name="crc" column="crc" type="long" unique-key="uidx_auth_name" />
</class>
@@ -317,7 +319,7 @@
<query name="permission.GetAcesAndAclsByAuthority" cacheable="true">
select
aclmem.id, acl.id, ace.id
aclmem.id, acl.id, ace.id, authority.authority
from
org.alfresco.repo.domain.hibernate.DbAccessControlListMemberImpl as aclmem
join aclmem.accessControlList as acl

View File

@@ -25,31 +25,27 @@
package org.alfresco.repo.security.permissions.impl;
import org.alfresco.repo.security.permissions.NodePermissionEntry;
import org.alfresco.util.EqualsHelper;
/**
* This class provides common support for hash code and equality.
*
* @author andyh
*/
public abstract class AbstractNodePermissionEntry implements
NodePermissionEntry
public abstract class AbstractNodePermissionEntry implements NodePermissionEntry
{
public AbstractNodePermissionEntry()
{
super();
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder(200);
sb.append("NodePermissionEntry")
.append("[ node=").append(getNodeRef())
.append(", entries=").append(getPermissionEntries())
.append(", inherits=").append(inheritPermissions())
.append("]");
sb.append("NodePermissionEntry").append("[ node=").append(getNodeRef()).append(", entries=").append(getPermissionEntries()).append(", inherits=").append(
inheritPermissions()).append("]");
return sb.toString();
}
@@ -66,14 +62,21 @@ public abstract class AbstractNodePermissionEntry implements
}
AbstractNodePermissionEntry other = (AbstractNodePermissionEntry) o;
return this.getNodeRef().equals(other.getNodeRef())
&& (this.inheritPermissions() == other.inheritPermissions())
&& (this.getPermissionEntries().equals(other.getPermissionEntries()));
return EqualsHelper.nullSafeEquals(this.getNodeRef(), other.getNodeRef()) &&
EqualsHelper.nullSafeEquals(this.inheritPermissions(), other.inheritPermissions()) &&
EqualsHelper.nullSafeEquals(this.getPermissionEntries(), other.getPermissionEntries());
}
@Override
public int hashCode()
{
return getNodeRef().hashCode();
if (getNodeRef() != null)
{
return getNodeRef().hashCode();
}
else
{
return 0;
}
}
}

View File

@@ -54,14 +54,17 @@ public abstract class AbstractPermissionEntry implements PermissionEntry
AbstractPermissionEntry other = (AbstractPermissionEntry) o;
return EqualsHelper.nullSafeEquals(this.getNodeRef(), other.getNodeRef())
&& EqualsHelper.nullSafeEquals(this.getPermissionReference(), other.getPermissionReference())
&& EqualsHelper.nullSafeEquals(this.getAuthority(), other.getAuthority())
&& EqualsHelper.nullSafeEquals(this.getAccessStatus(), other.getAccessStatus());
&& EqualsHelper.nullSafeEquals(this.getAuthority(), other.getAuthority()) && EqualsHelper.nullSafeEquals(this.getAccessStatus(), other.getAccessStatus());
}
@Override
public int hashCode()
{
int hashCode = getNodeRef().hashCode();
int hashCode = 0;
if (getNodeRef() != null)
{
getNodeRef().hashCode();
}
if (getPermissionReference() != null)
{
hashCode = hashCode * 37 + getPermissionReference().hashCode();
@@ -70,9 +73,9 @@ public abstract class AbstractPermissionEntry implements PermissionEntry
{
hashCode = hashCode * 37 + getAuthority().hashCode();
}
if(getAccessStatus() != null)
if (getAccessStatus() != null)
{
hashCode = hashCode * 37 + getAccessStatus().hashCode();
hashCode = hashCode * 37 + getAccessStatus().hashCode();
}
return hashCode;
}
@@ -81,13 +84,9 @@ public abstract class AbstractPermissionEntry implements PermissionEntry
public String toString()
{
StringBuilder sb = new StringBuilder(200);
sb.append("PermissionEntry")
.append("[ authority=").append(getAuthority())
.append(", permission=").append(getPermissionReference())
.append(", access=").append(getAccessStatus())
.append("]");
sb.append("PermissionEntry").append("[ authority=").append(getAuthority()).append(", permission=").append(getPermissionReference()).append(", access=").append(
getAccessStatus()).append("]");
return sb.toString();
}
}

View File

@@ -36,6 +36,8 @@ import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.providers.dao.User;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.avm.AVMNodeConverter;
import org.alfresco.repo.avm.AVMRepository;
import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.repo.policy.PolicyComponent;
@@ -54,6 +56,7 @@ import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AccessPermission;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.AuthorityService;
@@ -283,6 +286,17 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
return accessPermissions;
}
public Set<AccessPermission> getAllSetPermissions(StoreRef storeRef)
{
HashSet<AccessPermission> accessPermissions = new HashSet<AccessPermission>();
NodePermissionEntry nodePremissionEntry = getSetPermissions(storeRef);
for (PermissionEntry pe : nodePremissionEntry.getPermissionEntries())
{
accessPermissions.add(new AccessPermissionImpl(getPermission(pe.getPermissionReference()), pe.getAccessStatus(), pe.getAuthority()));
}
return accessPermissions;
}
private Set<AccessPermission> getAllPermissionsImpl(NodeRef nodeRef, boolean includeTrue, boolean includeFalse)
{
String userName = authenticationComponent.getCurrentUserName();
@@ -331,6 +345,11 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
return permissionsDaoComponent.getPermissions(tenantService.getName(nodeRef));
}
public NodePermissionEntry getSetPermissions(StoreRef storeRef)
{
return permissionsDaoComponent.getPermissions(storeRef);
}
public AccessStatus hasPermission(final NodeRef nodeRefIn, final PermissionReference permIn)
{
// If the node ref is null there is no sensible test to do - and there
@@ -349,12 +368,20 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
return AccessStatus.DENIED;
}
// AVM nodes - test for existence underneath
if (nodeRef.getStoreRef().getProtocol().equals(StoreRef.PROTOCOL_AVM))
{
return doAvmCan(nodeRef, permIn);
}
// Allow permissions for nodes that do not exist
if (!nodeService.exists(nodeRef))
{
return AccessStatus.ALLOWED;
}
final PermissionReference perm;
if (permIn.equals(OLD_ALL_PERMISSIONS_REFERENCE))
{
@@ -436,6 +463,16 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
}
private AccessStatus doAvmCan(NodeRef nodeRef, PermissionReference permission)
{
org.alfresco.util.Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
int version = avmVersionPath.getFirst();
String path = avmVersionPath.getSecond();
boolean result = AVMRepository.GetInstance().can(nodeRef.getStoreRef().getIdentifier(), version, path, permission.getName());
AccessStatus status = result ? AccessStatus.ALLOWED : AccessStatus.DENIED;
return status;
}
/*
* (non-Javadoc)
*
@@ -493,11 +530,22 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
{
permission = getAllPermissionReference();
}
AclTest aclTest = new AclTest(permission, typeQname, aspectQNames);
boolean result = aclTest.evaluate(authorisations, aclId);
boolean result;
if (context.getStoreAcl() == null)
{
AclTest aclTest = new AclTest(permission, typeQname, aspectQNames);
result = aclTest.evaluate(authorisations, aclId);
}
else
{
Set<String> storeAuthorisations = getAuthorisations(auth, (PermissionContext)null);
AclTest aclTest = new AclTest(permission, typeQname, aspectQNames);
result = aclTest.evaluate(authorisations, aclId) && aclTest.evaluate(storeAuthorisations, context.getStoreAcl());
}
AccessStatus status = result ? AccessStatus.ALLOWED : AccessStatus.DENIED;
return status;
}
enum CacheType
@@ -608,6 +656,43 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
return null;
}
public void clearPermission(StoreRef storeRef, String authority)
{
permissionsDaoComponent.deletePermissions(storeRef, authority);
accessCache.clear();
}
public void deletePermission(StoreRef storeRef, String authority, String perm)
{
deletePermission(storeRef, authority, getPermissionReference(perm));
}
public void deletePermission(StoreRef storeRef, String authority, PermissionReference perm)
{
permissionsDaoComponent.deletePermission(storeRef, authority, perm);
accessCache.clear();
}
public void deletePermissions(StoreRef storeRef)
{
permissionsDaoComponent.deletePermissions(storeRef);
accessCache.clear();
}
public void setPermission(StoreRef storeRef, String authority, String perm, boolean allow)
{
setPermission(storeRef, authority, getPermissionReference(perm), allow);
}
public void setPermission(StoreRef storeRef, String authority, PermissionReference permission, boolean allow)
{
permissionsDaoComponent.setPermission(storeRef, authority, permission, allow);
accessCache.clear();
}
public void deletePermissions(NodeRef nodeRef)
{
permissionsDaoComponent.deletePermissions(tenantService.getName(nodeRef));

View File

@@ -949,7 +949,42 @@ public class PermissionServiceTest extends AbstractPermissionTest
assertFalse(permissionService.hasPermission(rootNodeRef, getPermission(PermissionService.READ_CHILDREN)) == AccessStatus.ALLOWED);
assertFalse(permissionService.hasPermission(rootNodeRef, getPermission(PermissionService.READ_CONTENT)) == AccessStatus.ALLOWED);
}
public void testPerformance() throws Exception
{
runAs("admin");
// TransactionService transactionService = serviceRegistry.getTransactionService();
// UserTransaction tx = transactionService.getUserTransaction();
// tx.begin();
NodeRef n1 = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}one"), ContentModel.TYPE_FOLDER).getChildRef();
NodeRef n2 = nodeService.createNode(n1, ContentModel.ASSOC_CONTAINS, QName.createQName("{namespace}two"), ContentModel.TYPE_FOLDER).getChildRef();
NodeRef n3 = nodeService.createNode(n2, ContentModel.ASSOC_CONTAINS, QName.createQName("{namespace}three"), ContentModel.TYPE_FOLDER).getChildRef();
NodeRef n4 = nodeService.createNode(n3, ContentModel.ASSOC_CONTAINS, QName.createQName("{namespace}four"), ContentModel.TYPE_FOLDER).getChildRef();
NodeRef n5 = nodeService.createNode(n4, ContentModel.ASSOC_CONTAINS, QName.createQName("{namespace}five"), ContentModel.TYPE_FOLDER).getChildRef();
NodeRef n6 = nodeService.createNode(n5, ContentModel.ASSOC_CONTAINS, QName.createQName("{namespace}six"), ContentModel.TYPE_FOLDER).getChildRef();
NodeRef n7 = nodeService.createNode(n6, ContentModel.ASSOC_CONTAINS, QName.createQName("{namespace}seven"), ContentModel.TYPE_FOLDER).getChildRef();
NodeRef n8 = nodeService.createNode(n7, ContentModel.ASSOC_CONTAINS, QName.createQName("{namespace}eight"), ContentModel.TYPE_FOLDER).getChildRef();
NodeRef n9 = nodeService.createNode(n8, ContentModel.ASSOC_CONTAINS, QName.createQName("{namespace}nine"), ContentModel.TYPE_FOLDER).getChildRef();
NodeRef n10 = nodeService.createNode(n9, ContentModel.ASSOC_CONTAINS, QName.createQName("{namespace}ten"), ContentModel.TYPE_FOLDER).getChildRef();
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
runAs("andy");
permissionService.hasPermission(n5, PermissionService.READ);
long start = System.nanoTime();
for(int i = 0; i < 10000; i++)
{
permissionService.hasPermission(n5, PermissionService.READ);
}
long end = System.nanoTime();
System.out.println("Can in "+((end-start)/10e9f/10000));
System.out.println("Can per second "+(1/((end-start)/10e9f/10000)));
}
public void testPerf() throws Exception
{
runAs("admin");
@@ -1527,6 +1562,8 @@ public class PermissionServiceTest extends AbstractPermissionTest
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ_PROPERTIES), "ANDY", AccessStatus.ALLOWED));
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ_CONTENT), "AnDy", AccessStatus.ALLOWED));
permissionService.getAllSetPermissions(rootNodeRef);
runAs("andy");
assertFalse(permissionService.hasPermission(rootNodeRef, getPermission(PermissionService.READ)) == AccessStatus.ALLOWED);
assertFalse(permissionService.hasPermission(rootNodeRef, getPermission(PermissionService.READ_PROPERTIES)) == AccessStatus.ALLOWED);

View File

@@ -31,6 +31,7 @@ import org.alfresco.repo.security.permissions.NodePermissionEntry;
import org.alfresco.repo.security.permissions.PermissionEntry;
import org.alfresco.repo.security.permissions.PermissionReference;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AccessPermission;
/**
@@ -137,4 +138,45 @@ public interface PermissionsDaoComponent
* @return - the set of matching nodes
*/
public Set<NodeRef> findNodeByPermission(String authority, PermissionReference permission, boolean allow);
/**
* Delete entries from a permission mask on a store by authority
*
* @param storeRef
* @param authority
*/
public void deletePermissions(StoreRef storeRef, String authority);
/**
* Remove part of a permission mask from a store
*
* @param storeRef
* @param authority
* @param perm
*/
public void deletePermission(StoreRef storeRef, String authority, PermissionReference perm);
/**
* Remove all permission masks from a store
*
* @param storeRef
*/
public void deletePermissions(StoreRef storeRef);
/**
* Set part of a permission mask on a store.
*
* @param storeRef
* @param authority
* @param permission
* @param allow
*/
public void setPermission(StoreRef storeRef, String authority, PermissionReference permission, boolean allow);
/**
* Get permission masks set on a store
* @param storeRef
* @return
*/
public NodePermissionEntry getPermissions(StoreRef storeRef);
}

View File

@@ -27,6 +27,7 @@ package org.alfresco.repo.security.permissions.impl.model;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -97,7 +98,7 @@ public class PermissionModel implements ModelDAO, InitializingBean
private String model;
// Aprrox 6 - default size OK
private Map<QName, PermissionSet> permissionSets = new HashMap<QName, PermissionSet>();
private Map<QName, PermissionSet> permissionSets = new HashMap<QName, PermissionSet>(128, 1.0f);
// Global permissions - default size OK
private Set<GlobalPermissionEntry> globalPermissions = new HashSet<GlobalPermissionEntry>();
@@ -105,13 +106,13 @@ public class PermissionModel implements ModelDAO, InitializingBean
private AccessStatus defaultPermission;
// Cache granting permissions
private HashMap<PermissionReference, Set<PermissionReference>> grantingPermissions = new HashMap<PermissionReference, Set<PermissionReference>>(128, 1.0f);
private HashMap<PermissionReference, Set<PermissionReference>> grantingPermissions = new HashMap<PermissionReference, Set<PermissionReference>>(256, 1.0f);
// Cache grantees
private HashMap<PermissionReference, Set<PermissionReference>> granteePermissions = new HashMap<PermissionReference, Set<PermissionReference>>(128, 1.0f);
private HashMap<PermissionReference, Set<PermissionReference>> granteePermissions = new HashMap<PermissionReference, Set<PermissionReference>>(256, 1.0f);
// Cache the mapping of extended groups to the base
private HashMap<PermissionGroup, PermissionGroup> groupsToBaseGroup = new HashMap<PermissionGroup, PermissionGroup>(128, 1.0f);
private HashMap<PermissionGroup, PermissionGroup> groupsToBaseGroup = new HashMap<PermissionGroup, PermissionGroup>(256, 1.0f);
private HashMap<String, PermissionReference> uniqueMap;
@@ -121,9 +122,11 @@ public class PermissionModel implements ModelDAO, InitializingBean
private HashMap<String, PermissionReference> permissionReferenceMap;
private Map<QName, Set<PermissionReference>> cachedTypePermissionsExposed = new HashMap<QName, Set<PermissionReference>>(128, 1.0f);
private Map<QName, Set<PermissionReference>> cachedTypePermissionsExposed = new HashMap<QName, Set<PermissionReference>>(256, 1.0f);
private Map<QName, Set<PermissionReference>> cachedTypePermissionsUnexposed = new HashMap<QName, Set<PermissionReference>>(128, 1.0f);
private Map<QName, Set<PermissionReference>> cachedTypePermissionsUnexposed = new HashMap<QName, Set<PermissionReference>>(256, 1.0f);
private Collection<QName> allAspects;
public PermissionModel()
{
@@ -226,6 +229,10 @@ public class PermissionModel implements ModelDAO, InitializingBean
globalPermissions.add(globalPermission);
}
// Cache all aspect list
allAspects = dictionaryService.getAllAspects();
}
/*
@@ -308,7 +315,7 @@ public class PermissionModel implements ModelDAO, InitializingBean
Set<PermissionReference> permissions = cache.get(type);
if (permissions == null)
{
permissions = new LinkedHashSet<PermissionReference>(128, 1.0f);
permissions = new LinkedHashSet<PermissionReference>(256, 1.0f);
ClassDefinition cd = dictionaryService.getClass(type);
if (cd != null)
{
@@ -428,12 +435,12 @@ public class PermissionModel implements ModelDAO, InitializingBean
private void mergeGeneralAspectPermissions(Set<PermissionReference> target, boolean exposedOnly)
{
for (QName aspect : dictionaryService.getAllAspects())
for (QName aspect : allAspects)
{
mergePermissions(target, aspect, exposedOnly, false);
}
}
public Set<PermissionReference> getAllPermissions(NodeRef nodeRef)
{
return getAllPermissionsImpl(nodeService.getType(nodeRef), nodeService.getAspects(nodeRef), false);
@@ -451,20 +458,14 @@ public class PermissionModel implements ModelDAO, InitializingBean
private Set<PermissionReference> getAllPermissionsImpl(QName typeName, Set<QName> aspects, boolean exposedOnly)
{
Set<PermissionReference> permissions = new LinkedHashSet<PermissionReference>(128, 1.0f);
Set<PermissionReference> permissions = new LinkedHashSet<PermissionReference>(256, 1.0f);
ClassDefinition cd = dictionaryService.getClass(typeName);
permissions.addAll(getAllPermissionsImpl(typeName, exposedOnly));
ClassDefinition cd = dictionaryService.getClass(typeName);
if (cd != null)
{
if (cd.isAspect())
{
// Do not merge in all general aspects
}
else
{
mergeGeneralAspectPermissions(permissions, exposedOnly);
}
Set<QName> defaultAspects = new HashSet<QName>();
for (AspectDefinition aspDef : cd.getDefaultAspects())
{
@@ -500,7 +501,7 @@ public class PermissionModel implements ModelDAO, InitializingBean
private Set<PermissionReference> getGrantingPermissionsImpl(PermissionReference permissionReference)
{
// Query the model
HashSet<PermissionReference> permissions = new HashSet<PermissionReference>(128, 1.0f);
HashSet<PermissionReference> permissions = new HashSet<PermissionReference>(256, 1.0f);
permissions.add(permissionReference);
for (PermissionSet ps : permissionSets.values())
{
@@ -573,7 +574,7 @@ public class PermissionModel implements ModelDAO, InitializingBean
private Set<PermissionReference> getGranteePermissionsImpl(PermissionReference permissionReference)
{
// Query the model
HashSet<PermissionReference> permissions = new HashSet<PermissionReference>(128, 1.0f);
HashSet<PermissionReference> permissions = new HashSet<PermissionReference>(256, 1.0f);
permissions.add(permissionReference);
for (PermissionSet ps : permissionSets.values())
{
@@ -636,7 +637,7 @@ public class PermissionModel implements ModelDAO, InitializingBean
private Set<PermissionReference> getAllPermissions()
{
HashSet<PermissionReference> permissions = new HashSet<PermissionReference>(128, 1.0f);
HashSet<PermissionReference> permissions = new HashSet<PermissionReference>(256, 1.0f);
for (PermissionSet ps : permissionSets.values())
{
for (PermissionGroup pg : ps.getPermissionGroups())
@@ -817,7 +818,7 @@ public class PermissionModel implements ModelDAO, InitializingBean
*/
private Set<PermissionReference> getRequirementsForPermissionGroup(PermissionGroup target, RequiredPermission.On on, QName qName, Set<QName> aspectQNames)
{
HashSet<PermissionReference> requiredPermissions = new HashSet<PermissionReference>(8, 1.0f);
HashSet<PermissionReference> requiredPermissions = new HashSet<PermissionReference>(16, 1.0f);
if (target == null)
{
return requiredPermissions;
@@ -960,11 +961,11 @@ public class PermissionModel implements ModelDAO, InitializingBean
private void buildUniquePermissionMap()
{
Set<String> excluded = new HashSet<String>(64, 1.0f);
uniqueMap = new HashMap<String, PermissionReference>(128, 1.0f);
permissionReferenceMap = new HashMap<String, PermissionReference>(128, 1.0f);
permissionGroupMap = new HashMap<PermissionReference, PermissionGroup>(64, 1.0f);
permissionMap = new HashMap<PermissionReference, Permission>(32, 1.0f);
Set<String> excluded = new HashSet<String>(128, 1.0f);
uniqueMap = new HashMap<String, PermissionReference>(256, 1.0f);
permissionReferenceMap = new HashMap<String, PermissionReference>(256, 1.0f);
permissionGroupMap = new HashMap<PermissionReference, PermissionGroup>(128, 1.0f);
permissionMap = new HashMap<PermissionReference, Permission>(64, 1.0f);
for (PermissionSet ps : permissionSets.values())
{
for (PermissionGroup pg : ps.getPermissionGroups())

View File

@@ -36,6 +36,7 @@ import org.alfresco.repo.security.permissions.PermissionServiceSPI;
import org.alfresco.repo.security.permissions.impl.PermissionReferenceImpl;
import org.alfresco.repo.security.permissions.impl.SimpleNodePermissionEntry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AccessPermission;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionContext;
@@ -258,4 +259,31 @@ public class PermissionServiceNOOPImpl
{
return Collections.<NodeRef>emptySet();
}
public void clearPermission(StoreRef storeRef, String authority)
{
}
public void deletePermission(StoreRef storeRef, String authority, String permission)
{
}
public void deletePermissions(StoreRef storeRef)
{
}
public void setPermission(StoreRef storeRef, String authority, String permission, boolean allow)
{
}
public Set<AccessPermission> getAllSetPermissions(StoreRef storeRef)
{
return Collections.<AccessPermission>emptySet();
}
}