From bcd6a044f720f03af0c9514199b06805e853a2e9 Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Mon, 26 Nov 2012 23:40:35 +0000 Subject: [PATCH] RM: Post merge fixes * build scripts updated so generated eclipse projects don't double up dependancies * demo code removed entirely * permission service override replaced with extended class based on updated core permission service implementation * unit test juggling git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@44009 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- build.gradle | 6 +- rm-server/build.gradle | 6 +- .../demo/demo-context.xml | 15 - .../demo/demo-model.xml | 64 - .../org_alfresco_module_rm/module-context.xml | 5 +- .../permission/PermissionServiceImpl.java | 2776 ----------------- .../impl/RMPermissionServiceImpl.java | 107 + ...ordsManagementSecurityServiceImplTest.java | 151 - ...ordsManagementSecurityServiceImplTest.java | 793 +---- 9 files changed, 241 insertions(+), 3682 deletions(-) delete mode 100644 rm-server/config/alfresco/module/org_alfresco_module_rm/demo/demo-context.xml delete mode 100644 rm-server/config/alfresco/module/org_alfresco_module_rm/demo/demo-model.xml delete mode 100644 rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/permission/PermissionServiceImpl.java create mode 100644 rm-server/source/java/org/alfresco/repo/security/permissions/impl/RMPermissionServiceImpl.java delete mode 100644 rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/NewRecordsManagementSecurityServiceImplTest.java diff --git a/build.gradle b/build.gradle index 8b338c3956..d37ed7e726 100644 --- a/build.gradle +++ b/build.gradle @@ -109,6 +109,10 @@ subprojects { } } + configurations { + alfrescoDeps + } + configurations.all { exclude group: 'com.sun.jdmk', module: 'jmxtools' exclude group: 'com.sun.jmx', module: 'jmxri' @@ -143,7 +147,7 @@ subprojects { /** --- Dependancy tasks --- */ task fetchWarFile(type:Copy) { - from configurations.testRuntime + from configurations.alfrescoDeps into '.' include '*.war' rename { String filename -> warFile } diff --git a/rm-server/build.gradle b/rm-server/build.gradle index 5ce73c2b82..f3a74f00d5 100644 --- a/rm-server/build.gradle +++ b/rm-server/build.gradle @@ -12,12 +12,12 @@ dependencies { testRuntime files(configDir) testRuntime files(testResourceDir) - testRuntime group: alfrescoGroupId, name: 'alfresco', version: alfrescoBaseVersion, type: 'war' - testRuntime group: alfrescoGroupId, name: 'alfresco-solr', version: alfrescoBaseVersion, type: 'zip' + alfrescoDeps group: alfrescoGroupId, name: 'alfresco', version: alfrescoBaseVersion, type: 'war' + alfrescoDeps group: alfrescoGroupId, name: 'alfresco-solr', version: alfrescoBaseVersion, type: 'zip' } task fetchSOLR(type:Copy) { - from configurations.testRuntime + from configurations.alfrescoDeps into '.' include '*.zip' rename { String filename -> solrFile } diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/demo/demo-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/demo/demo-context.xml deleted file mode 100644 index fc82db086e..0000000000 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/demo/demo-context.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - alfresco/module/org_alfresco_module_rm/demo/demo-model.xml - - - - - \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/demo/demo-model.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/demo/demo-model.xml deleted file mode 100644 index 1168b571d7..0000000000 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/demo/demo-model.xml +++ /dev/null @@ -1,64 +0,0 @@ - - - - - Demo Model - Roy Wetherall - 1.0 - - - - - - - - - - - - - - - - - - - - - - - - Purchase Order - cm:content - - - - - Order Id - d:text - - - - Customer Id - d:text - - - - Order Quantity - d:int - - - - Delivery Date - d:date - - - - Sales Confirmation Sent - d:boolean - - - - - - \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml index bc66c31842..b7755dade8 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml @@ -2,7 +2,7 @@ - + @@ -132,9 +132,6 @@ - - - diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/permission/PermissionServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/permission/PermissionServiceImpl.java deleted file mode 100644 index 4a0ed61f9e..0000000000 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/permission/PermissionServiceImpl.java +++ /dev/null @@ -1,2776 +0,0 @@ -/* - * Copyright (C) 2005-2012 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.module.org_alfresco_module_rm.permission; - -import java.io.Serializable; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import net.sf.acegisecurity.Authentication; -import net.sf.acegisecurity.GrantedAuthority; -import net.sf.acegisecurity.providers.dao.User; - -import org.alfresco.model.ContentModel; -import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; -import org.alfresco.repo.avm.AVMNodeConverter; -import org.alfresco.repo.avm.AVMRepository; -import org.alfresco.repo.cache.SimpleCache; -import org.alfresco.repo.domain.permissions.AclDAO; -import org.alfresco.repo.policy.JavaBehaviour; -import org.alfresco.repo.policy.PolicyComponent; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; -import org.alfresco.repo.security.authority.AuthorityServiceImpl; -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.AccessControlListProperties; -import org.alfresco.repo.security.permissions.DynamicAuthority; -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.PermissionServiceSPI; -import org.alfresco.repo.security.permissions.impl.AccessPermissionImpl; -import org.alfresco.repo.security.permissions.impl.ModelDAO; -import org.alfresco.repo.security.permissions.impl.PermissionsDaoComponent; -import org.alfresco.repo.security.permissions.impl.RequiredPermission; -import org.alfresco.repo.security.permissions.impl.SimplePermissionReference; -import org.alfresco.repo.tenant.TenantService; -import org.alfresco.repo.transaction.AlfrescoTransactionSupport; -import org.alfresco.repo.version.Version2Model; -import org.alfresco.repo.version.VersionModel; -import org.alfresco.repo.version.common.VersionUtil; -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; -import org.alfresco.service.cmr.security.OwnableService; -import org.alfresco.service.cmr.security.PermissionContext; -import org.alfresco.service.cmr.security.PermissionService; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.namespace.QName; -import org.alfresco.util.EqualsHelper; -import org.alfresco.util.Pair; -import org.alfresco.util.PropertyCheck; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.context.ApplicationEvent; -import org.springframework.extensions.surf.util.AbstractLifecycleBean; - -/** - * @author Roy Wetherall - */ -public class PermissionServiceImpl extends AbstractLifecycleBean implements PermissionServiceSPI -{ - static SimplePermissionReference OLD_ALL_PERMISSIONS_REFERENCE = SimplePermissionReference.getPermissionReference( - QName.createQName("", PermissionService.ALL_PERMISSIONS), - PermissionService.ALL_PERMISSIONS); - - private static Log log = LogFactory.getLog(PermissionServiceImpl.class); - - /** a transactionally-safe cache to be injected */ - private SimpleCache accessCache; - - private SimpleCache> readersCache; - - private SimpleCache> readersDeniedCache; - - /* - * Access to the model - */ - private ModelDAO modelDAO; - - /* - * Access to permissions - */ - private PermissionsDaoComponent permissionsDaoComponent; - - /* - * Access to the node service - */ - private NodeService nodeService; - - /* - * Access to the tenant service - */ - private TenantService tenantService; - - /* - * Access to the data dictionary - */ - private DictionaryService dictionaryService; - - /* - * Access to the ownable service - */ - private OwnableService ownableService; - - /* - * Access to the authority component - */ - private AuthorityService authorityService; - - /* - * Dynamic authorities providers - */ - private List dynamicAuthorities; - - private PolicyComponent policyComponent; - - private AclDAO aclDaoComponent; - - private PermissionReference allPermissionReference; - - private boolean anyDenyDenies = false; - - /** - * Standard spring construction. - */ - public PermissionServiceImpl() - { - super(); - } - - // - // Inversion of control - // - - - - /** - * Set the dictionary service - * @param dictionaryService - */ - public void setDictionaryService(DictionaryService dictionaryService) - { - this.dictionaryService = dictionaryService; - } - - /** - * @param anyDenyDenies the anyDenyDenies to set - */ - public void setAnyDenyDenies(boolean anyDenyDenies) - { - this.anyDenyDenies = anyDenyDenies; - accessCache.clear(); - readersCache.clear(); - readersDeniedCache.clear(); - } - - public boolean getAnyDenyDenies() - { - return anyDenyDenies; - } - - /** - * Set the permissions model dao - * - * @param modelDAO - */ - public void setModelDAO(ModelDAO modelDAO) - { - this.modelDAO = modelDAO; - } - - /** - * Set the node service. - * - * @param nodeService - */ - public void setNodeService(NodeService nodeService) - { - this.nodeService = nodeService; - } - - /** - * Set the ownable service. - * - * @param ownableService - */ - public void setOwnableService(OwnableService ownableService) - { - this.ownableService = ownableService; - } - - /** - * Set the tenant service. - * @param tenantService - */ - public void setTenantService(TenantService tenantService) - { - this.tenantService = tenantService; - } - - /** - * Set the permissions dao component - * - * @param permissionsDaoComponent - */ - public void setPermissionsDaoComponent(PermissionsDaoComponent permissionsDaoComponent) - { - this.permissionsDaoComponent = permissionsDaoComponent; - } - - /** - * Set the authority service. - * - * @param authorityService - */ - public void setAuthorityService(AuthorityService authorityService) - { - this.authorityService = authorityService; - } - - /** - * Set the dynamic authorities - * - * @param dynamicAuthorities - */ - public void setDynamicAuthorities(List dynamicAuthorities) - { - this.dynamicAuthorities = dynamicAuthorities; - } - - /** - * Set the ACL DAO component. - * - * @param aclDaoComponent - */ - public void setAclDAO(AclDAO aclDaoComponent) - { - this.aclDaoComponent = aclDaoComponent; - } - - /** - * Set the permissions access cache. - * - * @param accessCache - * a transactionally safe cache - */ - public void setAccessCache(SimpleCache accessCache) - { - this.accessCache = accessCache; - } - - /** - * @param readersCache the readersCache to set - */ - public void setReadersCache(SimpleCache> readersCache) - { - this.readersCache = readersCache; - } - - - /** - * @param readersDeniedCache the readersDeniedCache to set - */ - public void setReadersDeniedCache(SimpleCache> readersDeniedCache) - { - this.readersDeniedCache = readersDeniedCache; - } - - /** - * Set the policy component - * - * @param policyComponent - */ - public void setPolicyComponent(PolicyComponent policyComponent) - { - this.policyComponent = policyComponent; - } - - /** - * Cache clear on move node - * - * @param oldChildAssocRef - * @param newChildAssocRef - */ - public void onMoveNode(ChildAssociationRef oldChildAssocRef, ChildAssociationRef newChildAssocRef) - { - accessCache.clear(); - } - - /** - * Cache clear on create of a child association from an authority container. - * - * @param childAssocRef - */ - public void onCreateChildAssociation(ChildAssociationRef childAssocRef) - { - accessCache.clear(); - } - - /** - * Cache clear on delete of a child association from an authority container. - * - * @param childAssocRef - */ - public void beforeDeleteChildAssociation(ChildAssociationRef childAssocRef) - { - accessCache.clear(); - } - - @Override - protected void onBootstrap(ApplicationEvent event) - { - PropertyCheck.mandatory(this, "dictionaryService", dictionaryService); - PropertyCheck.mandatory(this, "modelDAO", modelDAO); - PropertyCheck.mandatory(this, "nodeService", nodeService); - PropertyCheck.mandatory(this, "ownableService", ownableService); - PropertyCheck.mandatory(this, "permissionsDaoComponent", permissionsDaoComponent); - PropertyCheck.mandatory(this, "authorityService", authorityService); - PropertyCheck.mandatory(this, "accessCache", accessCache); - PropertyCheck.mandatory(this, "readersCache", readersCache); - PropertyCheck.mandatory(this, "policyComponent", policyComponent); - PropertyCheck.mandatory(this, "aclDaoComponent", aclDaoComponent); - - allPermissionReference = getPermissionReference(ALL_PERMISSIONS); - } - - /** - * No-op - */ - @Override - protected void onShutdown(ApplicationEvent event) - { - } - - public void init() - { - policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onMoveNode"), ContentModel.TYPE_BASE, new JavaBehaviour(this, "onMoveNode")); - - policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateChildAssociation"), ContentModel.TYPE_AUTHORITY_CONTAINER, new JavaBehaviour(this, "onCreateChildAssociation")); - policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "beforeDeleteChildAssociation"), ContentModel.TYPE_AUTHORITY_CONTAINER, new JavaBehaviour(this, "beforeDeleteChildAssociation")); - } - - // - // Permissions Service - // - - public String getOwnerAuthority() - { - return OWNER_AUTHORITY; - } - - public String getAllAuthorities() - { - return ALL_AUTHORITIES; - } - - public String getAllPermission() - { - return ALL_PERMISSIONS; - } - - public Set getPermissions(NodeRef nodeRef) - { - return getAllPermissionsImpl(nodeRef, true, true); - } - - public Set getAllSetPermissions(NodeRef nodeRef) - { - HashSet accessPermissions = new HashSet(); - NodePermissionEntry nodePremissionEntry = getSetPermissions(nodeRef); - for (PermissionEntry pe : nodePremissionEntry.getPermissionEntries()) - { - accessPermissions.add(new AccessPermissionImpl(getPermission(pe.getPermissionReference()), pe.getAccessStatus(), pe.getAuthority(), pe.getPosition())); - } - return accessPermissions; - } - - public Set getAllSetPermissions(StoreRef storeRef) - { - HashSet accessPermissions = new HashSet(); - NodePermissionEntry nodePremissionEntry = getSetPermissions(storeRef); - for (PermissionEntry pe : nodePremissionEntry.getPermissionEntries()) - { - accessPermissions.add(new AccessPermissionImpl(getPermission(pe.getPermissionReference()), pe.getAccessStatus(), pe.getAuthority(), pe.getPosition())); - } - return accessPermissions; - } - - private Set getAllPermissionsImpl(NodeRef nodeRef, boolean includeTrue, boolean includeFalse) - { - String userName = AuthenticationUtil.getRunAsUser(); - HashSet accessPermissions = new HashSet(); - for (PermissionReference pr : getSettablePermissionReferences(nodeRef)) - { - if (hasPermission(nodeRef, pr) == AccessStatus.ALLOWED) - { - accessPermissions.add(new AccessPermissionImpl(getPermission(pr), AccessStatus.ALLOWED, userName, -1)); - } - else - { - if (includeFalse) - { - accessPermissions.add(new AccessPermissionImpl(getPermission(pr), AccessStatus.DENIED, userName, -1)); - } - } - } - return accessPermissions; - } - - public Set getSettablePermissions(NodeRef nodeRef) - { - Set settable = getSettablePermissionReferences(nodeRef); - Set strings = new HashSet(settable.size()); - for (PermissionReference pr : settable) - { - strings.add(getPermission(pr)); - } - return strings; - } - - public Set getSettablePermissions(QName type) - { - Set settable = getSettablePermissionReferences(type); - Set strings = new LinkedHashSet(settable.size()); - for (PermissionReference pr : settable) - { - strings.add(getPermission(pr)); - } - return strings; - } - - public NodePermissionEntry getSetPermissions(NodeRef nodeRef) - { - return permissionsDaoComponent.getPermissions(tenantService.getName(nodeRef)); - } - - public NodePermissionEntry getSetPermissions(StoreRef storeRef) - { - return permissionsDaoComponent.getPermissions(storeRef); - } - - public AccessStatus hasPermission(NodeRef passedNodeRef, final PermissionReference permIn) - { - // If the node ref is null there is no sensible test to do - and there - // must be no permissions - // - so we allow it - if (passedNodeRef == null) - { - return AccessStatus.ALLOWED; - } - - // If the permission is null we deny - if (permIn == null) - { - return AccessStatus.DENIED; - } - - // AVM nodes - test for existence underneath - if (passedNodeRef.getStoreRef().getProtocol().equals(StoreRef.PROTOCOL_AVM)) - { - return doAvmCan(passedNodeRef, permIn); - } - - // Note: if we're directly accessing a frozen state (version) node (ie. in the 'version' store) we need to check permissions for the versioned node (ie. in the 'live' store) - if (isVersionNodeRef(passedNodeRef)) - { - passedNodeRef = convertVersionNodeRefToVersionedNodeRef(VersionUtil.convertNodeRef(passedNodeRef)); - } - - // Allow permissions for nodes that do not exist - if (!nodeService.exists(passedNodeRef)) - { - return AccessStatus.ALLOWED; - } - - final NodeRef nodeRef = tenantService.getName(passedNodeRef); - - final PermissionReference perm; - if (permIn.equals(OLD_ALL_PERMISSIONS_REFERENCE)) - { - perm = getAllPermissionReference(); - } - else - { - perm = permIn; - } - - if (AuthenticationUtil.getRunAsUser() == null) - { - return AccessStatus.DENIED; - } - - if (AuthenticationUtil.isRunAsUserTheSystemUser()) - { - return AccessStatus.ALLOWED; - } - - // New ACLs - - AccessControlListProperties properties = permissionsDaoComponent.getAccessControlListProperties(nodeRef); - if ((properties != null) && (properties.getAclType() != null) && (properties.getAclType() != ACLType.OLD)) - { - QName typeQname = nodeService.getType(nodeRef); - Set aspectQNames = nodeService.getAspects(nodeRef); - PermissionContext context = new PermissionContext(typeQname); - context.getAspects().addAll(aspectQNames); - Authentication auth = AuthenticationUtil.getRunAsAuthentication(); - if (auth != null) - { - String user = AuthenticationUtil.getRunAsUser(); - for (String dynamicAuthority : getDynamicAuthorities(auth, nodeRef, perm)) - { - context.addDynamicAuthorityAssignment(user, dynamicAuthority); - } - } - return hasPermission(properties.getId(), context, perm); - } - - // Get the current authentications - // Use the smart authentication cache to improve permissions performance - Authentication auth = AuthenticationUtil.getRunAsAuthentication(); - final Set authorisations = getAuthorisations(auth, nodeRef, perm); - - // If the node does not support the given permission there is no point - // doing the test - Set available = AuthenticationUtil.runAs(new RunAsWork>() - { - public Set doWork() throws Exception - { - return modelDAO.getAllPermissions(nodeRef); - } - - }, AuthenticationUtil.getSystemUserName()); - - available.add(getAllPermissionReference()); - available.add(OLD_ALL_PERMISSIONS_REFERENCE); - - final Serializable key = generateKey(authorisations, nodeRef, perm, CacheType.HAS_PERMISSION); - if (!(available.contains(perm))) - { - accessCache.put(key, AccessStatus.DENIED); - return AccessStatus.DENIED; - } - - if (AuthenticationUtil.isRunAsUserTheSystemUser()) - { - return AccessStatus.ALLOWED; - } - - return AuthenticationUtil.runAs(new RunAsWork() - { - - public AccessStatus doWork() throws Exception - { - - AccessStatus status = accessCache.get(key); - if (status != null) - { - return status; - } - - // - // TODO: Dynamic permissions via evaluators - // - - /* - * Does the current authentication have the supplied permission on the given node. - */ - - QName typeQname = nodeService.getType(nodeRef); - Set aspectQNames = nodeService.getAspects(nodeRef); - - NodeTest nt = new NodeTest(perm, typeQname, aspectQNames); - boolean result = nt.evaluate(authorisations, nodeRef); - if (log.isDebugEnabled()) - { - log.debug("Permission <" - + perm + "> is " + (result ? "allowed" : "denied") + " for " + AuthenticationUtil.getRunAsUser() + " on node " - + nodeService.getPath(nodeRef)); - } - - status = result ? AccessStatus.ALLOWED : AccessStatus.DENIED; - accessCache.put(key, status); - return status; - } - }, AuthenticationUtil.getSystemUserName()); - - } - - private AccessStatus doAvmCan(NodeRef nodeRef, PermissionReference permission) - { - org.alfresco.util.Pair 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) - * - * @see org.alfresco.service.cmr.security.PermissionService#hasPermission(java.lang.Long, java.lang.String, - * java.lang.String) - */ - public AccessStatus hasPermission(Long aclID, PermissionContext context, String permission) - { - return hasPermission(aclID, context, getPermissionReference(permission)); - } - - - private AccessStatus hasPermission(Long aclId, PermissionContext context, PermissionReference permission) - { - if (aclId == null) - { - // Enforce store ACLs if set - the AVM default was to "allow" if there are no permissions set ... - if (context.getStoreAcl() == null) - { - return AccessStatus.ALLOWED; - } - else - { - if (AuthenticationUtil.isRunAsUserTheSystemUser()) - { - return AccessStatus.ALLOWED; - } - - Authentication auth = AuthenticationUtil.getRunAsAuthentication(); - if (auth == null) - { - throw new IllegalStateException("Unauthenticated"); - } - Set storeAuthorisations = getAuthorisations(auth, (PermissionContext) null); - QName typeQname = context.getType(); - Set aspectQNames = context.getAspects(); - AclTest aclTest = new AclTest(permission, typeQname, aspectQNames); - boolean result = aclTest.evaluate(storeAuthorisations, context.getStoreAcl(), context); - AccessStatus status = result ? AccessStatus.ALLOWED : AccessStatus.DENIED; - return status; - } - } - - if (permission == null) - { - return AccessStatus.DENIED; - } - - if (AuthenticationUtil.getRunAsUser() == null) - { - return AccessStatus.DENIED; - } - - if (AuthenticationUtil.getRunAsUser().equals(AuthenticationUtil.getSystemUserName())) - { - return AccessStatus.ALLOWED; - } - - // Get the current authentications - // Use the smart authentication cache to improve permissions performance - Authentication auth = AuthenticationUtil.getRunAsAuthentication(); - if (auth == null) - { - throw new IllegalStateException("Unauthenticated"); - } - - Set authorisations = getAuthorisations(auth, context); - - // If the node does not support the given permission there is no point - // doing the test - - final QName typeQname = context.getType(); - final Set aspectQNames = context.getAspects(); - - Set available = AuthenticationUtil.runAs(new RunAsWork>() - { - public Set doWork() throws Exception - { - return modelDAO.getAllPermissions(typeQname, aspectQNames); - } - - }, AuthenticationUtil.getSystemUserName()); - available.add(getAllPermissionReference()); - available.add(OLD_ALL_PERMISSIONS_REFERENCE); - - if (!(available.contains(permission))) - { - return AccessStatus.DENIED; - } - - if (AuthenticationUtil.isRunAsUserTheSystemUser()) - { - return AccessStatus.ALLOWED; - } - - if (permission.equals(OLD_ALL_PERMISSIONS_REFERENCE)) - { - permission = getAllPermissionReference(); - } - - boolean result; - if (context.getStoreAcl() == null) - { - AclTest aclTest = new AclTest(permission, typeQname, aspectQNames); - result = aclTest.evaluate(authorisations, aclId, context); - } - else - { - Set storeAuthorisations = getAuthorisations(auth, (PermissionContext) null); - AclTest aclTest = new AclTest(permission, typeQname, aspectQNames); - result = aclTest.evaluate(authorisations, aclId, context) && aclTest.evaluate(storeAuthorisations, context.getStoreAcl(), context); - } - AccessStatus status = result ? AccessStatus.ALLOWED : AccessStatus.DENIED; - return status; - - } - - /** - * Control permissions cache - only used when we do old style permission evaluations - * - which should only be in DM stores where no permissions have been set - * - * @author andyh - * - */ - enum CacheType - { - /** - * cache full check - */ - HAS_PERMISSION, - /** - * Cache single permission check - */ - SINGLE_PERMISSION, - /** - * Cache single permission check for global permission checks - */ - SINGLE_PERMISSION_GLOBAL; - } - - /** - * Key for a cache object is built from all the known Authorities (which can change dynamically so they must all be - * used) the NodeRef ID and the permission reference itself. This gives a unique key for each permission test. - */ - static Serializable generateKey(Set auths, NodeRef nodeRef, PermissionReference perm, CacheType type) - { - LinkedHashSet key = new LinkedHashSet(); - key.add(perm.toString()); - // We will just have to key our dynamic sets by username. We wrap it so as not to be confused with a static set - if (auths instanceof AuthorityServiceImpl.UserAuthoritySet) - { - key.add((Serializable)Collections.singleton(((AuthorityServiceImpl.UserAuthoritySet)auths).getUsername())); - } - else - { - key.addAll(auths); - } - key.add(nodeRef); - key.add(type); - return key; - } - - /** - * Get the core authorisations for this {@code auth}. If {@code null} this - * will be an empty set. Otherwise it will be a Lazy loaded Set of authorities - * from the authority node structure PLUS any granted authorities. - */ - private Set getCoreAuthorisations(Authentication auth) - { - if (auth == null) - { - return Collections.emptySet(); - } - - User user = (User) auth.getPrincipal(); - String username = user.getUsername(); - Set auths = authorityService.getAuthoritiesForUser(username); - - auths.add(username); - - for (GrantedAuthority grantedAuthority : auth.getAuthorities()) - { - auths.add(grantedAuthority.getAuthority()); - } - return auths; - } - - /** - * Get the authorisations for the currently authenticated user - * - * @param auth - * @return the set of authorisations - */ - private Set getAuthorisations(Authentication auth, NodeRef nodeRef, PermissionReference required) - { - Set auths = getCoreAuthorisations(auth); - if (auth != null) - { - auths.addAll(getDynamicAuthorities(auth, nodeRef, required)); - } - return auths; - } - - private Set getDynamicAuthorities(Authentication auth, NodeRef nodeRef, PermissionReference required) - { - Set dynAuths = new HashSet(64); - User user = (User) auth.getPrincipal(); - String username = user.getUsername(); - - nodeRef = tenantService.getName(nodeRef); - if (nodeRef != null) - { - if (dynamicAuthorities != null) - { - for (DynamicAuthority da : dynamicAuthorities) - { - Set requiredFor = da.requiredFor(); - if ((requiredFor == null) || (requiredFor.contains(required))) - { - if (da.hasAuthority(nodeRef, username)) - { - dynAuths.add(da.getAuthority()); - } - } - } - } - } - return dynAuths; - } - - private Set getAuthorisations(Authentication auth, PermissionContext context) - { - Set auths = getCoreAuthorisations(auth); - if (auth != null) - { - if (context != null) - { - auths.addAll(getDynamicAuthorities(auth, context, auths)); - } - } - return auths; - } - - private Set getDynamicAuthorities(Authentication auth, PermissionContext context, Set auths) - { - Set dynAuths = new HashSet(); - Map> dynamicAuthorityAssignments = context.getDynamicAuthorityAssignment(); - for (String dynKey : dynamicAuthorityAssignments.keySet()) - { - if (auths.contains(dynKey)) - { - Set dynos = dynamicAuthorityAssignments.get(dynKey); - if (dynos != null) - { - dynAuths.addAll(dynos); - } - } - } - return dynAuths; - } - - public NodePermissionEntry explainPermission(NodeRef nodeRef, PermissionReference perm) - { - // TODO Auto-generated method stub - 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)); - } - - private 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); - } - - private 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)); - accessCache.clear(); - } - - public void deletePermissions(NodePermissionEntry nodePermissionEntry) - { - permissionsDaoComponent.deletePermissions(tenantService.getName(nodePermissionEntry.getNodeRef())); - accessCache.clear(); - } - - /** - * @see #deletePermission(NodeRef, String, PermissionReference) - */ - public void deletePermission(PermissionEntry permissionEntry) - { - NodeRef nodeRef = permissionEntry.getNodeRef(); - String authority = permissionEntry.getAuthority(); - PermissionReference permission = permissionEntry.getPermissionReference(); - deletePermission(nodeRef, authority, permission); - } - - private void deletePermission(NodeRef nodeRef, String authority, PermissionReference perm) - { - permissionsDaoComponent.deletePermission(tenantService.getName(nodeRef), authority, perm); - accessCache.clear(); - } - - public void clearPermission(NodeRef nodeRef, String authority) - { - permissionsDaoComponent.deletePermissions(tenantService.getName(nodeRef), authority); - accessCache.clear(); - } - - private void setPermission(NodeRef nodeRef, String authority, PermissionReference perm, boolean allow) - { - permissionsDaoComponent.setPermission(tenantService.getName(nodeRef), authority, perm, allow); - accessCache.clear(); - } - - public void setPermission(PermissionEntry permissionEntry) - { - // TODO - not MT-enabled nodeRef - currently only used by tests - permissionsDaoComponent.setPermission(permissionEntry); - accessCache.clear(); - } - - public void setPermission(NodePermissionEntry nodePermissionEntry) - { - // TODO - not MT-enabled nodeRef- currently only used by tests - permissionsDaoComponent.setPermission(nodePermissionEntry); - accessCache.clear(); - } - - public void setInheritParentPermissions(NodeRef nodeRef, boolean inheritParentPermissions) - { - NodeRef actualRef = tenantService.getName(nodeRef); - permissionsDaoComponent.setInheritParentPermissions(actualRef, inheritParentPermissions); - accessCache.clear(); - } - - /** - * @see org.alfresco.service.cmr.security.PermissionService#getInheritParentPermissions(org.alfresco.service.cmr.repository.NodeRef) - */ - public boolean getInheritParentPermissions(NodeRef nodeRef) - { - return permissionsDaoComponent.getInheritParentPermissions(tenantService.getName(nodeRef)); - } - - public PermissionReference getPermissionReference(QName qname, String permissionName) - { - return modelDAO.getPermissionReference(qname, permissionName); - } - - public PermissionReference getAllPermissionReference() - { - return allPermissionReference; - } - - public String getPermission(PermissionReference permissionReference) - { - if (modelDAO.isUnique(permissionReference)) - { - return permissionReference.getName(); - } - else - { - return permissionReference.toString(); - } - } - - public PermissionReference getPermissionReference(String permissionName) - { - return modelDAO.getPermissionReference(null, permissionName); - } - - public Set getSettablePermissionReferences(QName type) - { - return modelDAO.getExposedPermissions(type); - } - - public Set getSettablePermissionReferences(NodeRef nodeRef) - { - return modelDAO.getExposedPermissions(tenantService.getName(nodeRef)); - } - - public void deletePermission(NodeRef nodeRef, String authority, String perm) - { - deletePermission(nodeRef, authority, getPermissionReference(perm)); - } - - public AccessStatus hasPermission(NodeRef nodeRef, String perm) - { - return hasPermission(nodeRef, getPermissionReference(perm)); - } - - public void setPermission(NodeRef nodeRef, String authority, String perm, boolean allow) - { - setPermission(nodeRef, authority, getPermissionReference(perm), allow); - } - - public void deletePermissions(String recipient) - { - permissionsDaoComponent.deletePermissions(recipient); - accessCache.clear(); - } - - /** - * Optimised read permission evaluation - * caveats: - * doesn't take into account dynamic authorities/groups - * doesn't take into account node types/aspects for permissions - * - */ - public AccessStatus hasReadPermission(NodeRef nodeRef) - { - AccessStatus status = AccessStatus.DENIED; - - // If the node ref is null there is no sensible test to do - and there - // must be no permissions - // - so we allow it - if (nodeRef == null) - { - return AccessStatus.ALLOWED; - } - - // Allow permissions for nodes that do not exist - if (!nodeService.exists(nodeRef)) - { - return AccessStatus.ALLOWED; - } - - String runAsUser = AuthenticationUtil.getRunAsUser(); - if (runAsUser == null) - { - return AccessStatus.DENIED; - } - - if (AuthenticationUtil.isRunAsUserTheSystemUser()) - { - return AccessStatus.ALLOWED; - } - - // any dynamic authorities other than those defined in the default permissions model with full - // control or read permission force hasPermission check - Boolean forceHasPermission = (Boolean)AlfrescoTransactionSupport.getResource("forceHasPermission"); - if(forceHasPermission == null) - { - for(DynamicAuthority dynamicAuthority : dynamicAuthorities) - { - String authority = dynamicAuthority.getAuthority(); - Set requiredFor = dynamicAuthority.requiredFor(); - if(authority != PermissionService.OWNER_AUTHORITY && - authority != PermissionService.ADMINISTRATOR_AUTHORITY && - authority != PermissionService.LOCK_OWNER_AUTHORITY && - (requiredFor == null || - requiredFor.contains(modelDAO.getPermissionReference(null, PermissionService.FULL_CONTROL)) || - requiredFor.contains(modelDAO.getPermissionReference(null, PermissionService.READ)))) - { - forceHasPermission = Boolean.TRUE; - break; - } - } - AlfrescoTransactionSupport.bindResource("forceHasPermission", forceHasPermission); - } - - if(forceHasPermission == Boolean.TRUE) - { - return hasPermission(nodeRef, PermissionService.READ); - } - - Long aclID = nodeService.getNodeAclId(nodeRef); - if(aclID == null) - { - // ACLID is null - need to call default permissions evaluation - // This will end up calling the old-style ACL code that walks up the ACL tree - status = hasPermission(nodeRef, getPermissionReference(null, PermissionService.READ)); - } - else - { - status = (canRead(aclID) == AccessStatus.ALLOWED || - adminRead() == AccessStatus.ALLOWED || - ownerRead(runAsUser, nodeRef) == AccessStatus.ALLOWED) ? AccessStatus.ALLOWED : AccessStatus.DENIED; - } - - return status; - } - - private AccessStatus adminRead() - { - AccessStatus result = AccessStatus.DENIED; - - Set authorisations = getAuthorisations(); - if(authorisations.contains(AuthenticationUtil.getAdminRoleName())) - { - result = AccessStatus.ALLOWED; - } - - // ROLE_ADMINISTRATOR authority has FULL_CONTROL in permissionDefinitions - // so we don't need to check node requirements - return result; - } - - private AccessStatus ownerRead(String username, NodeRef nodeRef) - { - // Reviewed the behaviour of deny and ownership with Mike F - // ATM ownership takes precendence over READ deny - // TODO: check that global owner rights are set - - AccessStatus result = AccessStatus.DENIED; - - String owner = ownableService.getOwner(nodeRef); - if(owner == null) - { - // TODO node may not have auditable aspect and hence creator property - result = AccessStatus.DENIED; - } - - // is the user the owner of the node? - if(EqualsHelper.nullSafeEquals(username, owner)) - { - // ROLE_OWNER authority has FULL_CONTROL in permissionDefinitions - // so we don't need to check node requirements - return AccessStatus.ALLOWED; - } - - return result; - } - - /** - * {@inheritDoc} - */ - @Override - public Set getReaders(Long aclId) - { - Set aclReaders = readersCache.get(aclId); - if (aclReaders == null) - { - aclReaders = buildReaders(aclId); - readersCache.put(aclId, aclReaders); - } - return aclReaders; - } - - /** - * Builds the set of authorities who can read the given ACL. No caching is done here. - * - * @return an unmodifiable set of authorities - */ - private Set buildReaders(Long aclId) - { - AccessControlList acl = aclDaoComponent.getAccessControlList(aclId); - if (acl == null) - { - return Collections.emptySet(); - } - - HashSet assigned = new HashSet(); - HashSet readers = new HashSet(); - - for (AccessControlEntry ace : acl.getEntries()) - { - assigned.add(ace.getAuthority()); - } - - for (String authority : assigned) - { - UnconditionalAclTest test = new UnconditionalAclTest(getPermissionReference(PermissionService.READ)); - UnconditionalAclTest rmTest = new UnconditionalAclTest(getPermissionReference(RMPermissionModel.READ_RECORDS)); - if (test.evaluate(authority, aclId) || rmTest.evaluate(authority, aclId)) - { - readers.add(authority); - } - } - - return Collections.unmodifiableSet(readers); - } - - /** - * @param aclId - * @return set of authorities with read permission on the ACL - */ - private Set buildReadersDenied(Long aclId) - { - HashSet assigned = new HashSet(); - HashSet denied = new HashSet(); - AccessControlList acl = aclDaoComponent.getAccessControlList(aclId); - - if (acl == null) - { - return denied; - } - - for (AccessControlEntry ace : acl.getEntries()) - { - assigned.add(ace.getAuthority()); - } - - for(String authority : assigned) - { - UnconditionalDeniedAclTest test = new UnconditionalDeniedAclTest(getPermissionReference(PermissionService.READ)); - if(test.evaluate(authority, aclId)) - { - denied.add(authority); - } - } - - return denied; - } - - private AccessStatus canRead(Long aclId) - { - Set authorities = getAuthorisations(); - - // test denied - - if(anyDenyDenies) - { - - Set aclReadersDenied = readersDeniedCache.get(aclId); - if(aclReadersDenied == null) - { - aclReadersDenied = buildReadersDenied(aclId); - readersDeniedCache.put(aclId, aclReadersDenied); - } - - for(String auth : aclReadersDenied) - { - if(authorities.contains(auth)) - { - return AccessStatus.DENIED; - } - } - - } - - - - // test acl readers - Set aclReaders = getReaders(aclId); - - for(String auth : aclReaders) - { - if(authorities.contains(auth)) - { - return AccessStatus.ALLOWED; - } - } - - return AccessStatus.DENIED; - } - - // - // SUPPORT CLASSES - // - - /** - * Support class to test the permission on a node. - * - * Not fixed up for deny as should not be used - * - * @author Andy Hind - */ - private class NodeTest - { - /* - * The required permission. - */ - PermissionReference required; - - /* - * Granters of the permission - */ - Set granters; - - /* - * The additional permissions required at the node level. - */ - Set nodeRequirements = new HashSet(); - - /* - * The additional permissions required on the parent. - */ - Set parentRequirements = new HashSet(); - - /* - * The permissions required on all children . - */ - Set childrenRequirements = new HashSet(); - - /* - * The type name of the node. - */ - QName typeQName; - - /* - * The aspects set on the node. - */ - Set aspectQNames; - - /* - * Constructor just gets the additional requirements - */ - NodeTest(PermissionReference required, QName typeQName, Set aspectQNames) - { - this.required = required; - this.typeQName = typeQName; - this.aspectQNames = aspectQNames; - - // Set the required node permissions - if (required.equals(getPermissionReference(ALL_PERMISSIONS))) - { - nodeRequirements = modelDAO.getRequiredPermissions(getPermissionReference(PermissionService.FULL_CONTROL), typeQName, aspectQNames, RequiredPermission.On.NODE); - } - else - { - nodeRequirements = modelDAO.getRequiredPermissions(required, typeQName, aspectQNames, RequiredPermission.On.NODE); - } - - parentRequirements = modelDAO.getRequiredPermissions(required, typeQName, aspectQNames, RequiredPermission.On.PARENT); - - childrenRequirements = modelDAO.getRequiredPermissions(required, typeQName, aspectQNames, RequiredPermission.On.CHILDREN); - - // Find all the permissions that grant the allowed permission - // All permissions are treated specially. - granters = new LinkedHashSet(128, 1.0f); - granters.addAll(modelDAO.getGrantingPermissions(required)); - granters.add(getAllPermissionReference()); - granters.add(OLD_ALL_PERMISSIONS_REFERENCE); - } - - /** - * External hook point - * @return true if allowed - */ - boolean evaluate(Set authorisations, NodeRef nodeRef) - { - Set> denied = new HashSet>(); - return evaluate(authorisations, nodeRef, denied, null); - } - - /** - * Internal hook point for recursion - * @return true if allowed - */ - boolean evaluate(Set authorisations, NodeRef nodeRef, Set> denied, MutableBoolean recursiveIn) - { - // Do we defer our required test to a parent (yes if not null) - MutableBoolean recursiveOut = null; - - Set> locallyDenied = new HashSet>(); - locallyDenied.addAll(denied); - locallyDenied.addAll(getDenied(nodeRef)); - - // Start out true and "and" all other results - boolean success = true; - - // Check the required permissions but not for sets they rely on - // their underlying permissions - if (modelDAO.checkPermission(required)) - { - if (parentRequirements.contains(required)) - { - if (checkGlobalPermissions(authorisations) || checkRequired(authorisations, nodeRef, locallyDenied)) - { - // No need to do the recursive test as it has been found - if (recursiveIn != null) - { - recursiveIn.setValue(true); - } - } - else - { - // Much cheaper to do this as we go then check all the - // stack values for each parent - recursiveOut = new MutableBoolean(false); - } - } - else - { - // We have to do the test as no parent will help us out - success &= hasSinglePermission(authorisations, nodeRef); - } - if (!success) - { - return false; - } - } - - // Check the other permissions required on the node - for (PermissionReference pr : nodeRequirements) - { - // Build a new test - NodeTest nt = new NodeTest(pr, typeQName, aspectQNames); - success &= nt.evaluate(authorisations, nodeRef, locallyDenied, null); - if (!success) - { - return false; - } - } - - // Check the permission required of the parent - - if (success) - { - ChildAssociationRef car = nodeService.getPrimaryParent(nodeRef); - if (car.getParentRef() != null) - { - - NodePermissionEntry nodePermissions = permissionsDaoComponent.getPermissions(car.getChildRef()); - if ((nodePermissions == null) || (nodePermissions.inheritPermissions())) - { - - locallyDenied.addAll(getDenied(car.getParentRef())); - for (PermissionReference pr : parentRequirements) - { - if (pr.equals(required)) - { - // Recursive permission - success &= this.evaluate(authorisations, car.getParentRef(), locallyDenied, recursiveOut); - if ((recursiveOut != null) && recursiveOut.getValue()) - { - if (recursiveIn != null) - { - recursiveIn.setValue(true); - } - } - } - else - { - NodeTest nt = new NodeTest(pr, typeQName, aspectQNames); - success &= nt.evaluate(authorisations, car.getParentRef(), locallyDenied, null); - } - - if (!success) - { - return false; - } - } - } - } - } - - if ((recursiveOut != null) && (!recursiveOut.getValue())) - { - // The required authentication was not resolved in recursion - return false; - } - - // Check permissions required of children - if (childrenRequirements.size() > 0) - { - List childAssocRefs = nodeService.getChildAssocs(nodeRef); - for (PermissionReference pr : childrenRequirements) - { - for (ChildAssociationRef child : childAssocRefs) - { - success &= (hasPermission(child.getChildRef(), pr) == AccessStatus.ALLOWED); - if (!success) - { - return false; - } - } - } - } - - return success; - } - - boolean hasSinglePermission(Set authorisations, NodeRef nodeRef) - { - nodeRef = tenantService.getName(nodeRef); - - Serializable key = generateKey(authorisations, nodeRef, this.required, CacheType.SINGLE_PERMISSION_GLOBAL); - - AccessStatus status = accessCache.get(key); - if (status != null) - { - return status == AccessStatus.ALLOWED; - } - - // Check global permission - - if (checkGlobalPermissions(authorisations)) - { - accessCache.put(key, AccessStatus.ALLOWED); - return true; - } - - Set> denied = new HashSet>(); - - return hasSinglePermission(authorisations, nodeRef, denied); - - } - - boolean hasSinglePermission(Set authorisations, NodeRef nodeRef, Set> denied) - { - nodeRef = tenantService.getName(nodeRef); - - // Add any denied permission to the denied list - these can not - // then - // be used to given authentication. - // A -> B -> C - // If B denies all permissions to any - allowing all permissions - // to - // andy at node A has no effect - - denied.addAll(getDenied(nodeRef)); - - // Cache non denied - Serializable key = null; - if (denied.size() == 0) - { - key = generateKey(authorisations, nodeRef, this.required, CacheType.SINGLE_PERMISSION); - } - if (key != null) - { - AccessStatus status = accessCache.get(key); - if (status != null) - { - return status == AccessStatus.ALLOWED; - } - } - - // If the current node allows the permission we are done - // The test includes any parent or ancestor requirements - if (checkRequired(authorisations, nodeRef, denied)) - { - if (key != null) - { - accessCache.put(key, AccessStatus.ALLOWED); - } - return true; - } - - // Permissions are only evaluated up the primary parent chain - // TODO: Do not ignore non primary permissions - ChildAssociationRef car = nodeService.getPrimaryParent(nodeRef); - - // Build the next element of the evaluation chain - if (car.getParentRef() != null) - { - NodePermissionEntry nodePermissions = permissionsDaoComponent.getPermissions(nodeRef); - if ((nodePermissions == null) || (nodePermissions.inheritPermissions())) - { - if (hasSinglePermission(authorisations, car.getParentRef(), denied)) - { - if (key != null) - { - accessCache.put(key, AccessStatus.ALLOWED); - } - return true; - } - else - { - if (key != null) - { - accessCache.put(key, AccessStatus.DENIED); - } - return false; - } - } - else - { - if (key != null) - { - accessCache.put(key, AccessStatus.DENIED); - } - return false; - } - } - else - { - if (key != null) - { - accessCache.put(key, AccessStatus.DENIED); - } - return false; - } - } - - /** - * Check if we have a global permission - * - * @return true if allowed - */ - private boolean checkGlobalPermissions(Set authorisations) - { - for (PermissionEntry pe : modelDAO.getGlobalPermissionEntries()) - { - if (isGranted(pe, authorisations, null)) - { - return true; - } - } - return false; - } - - /** - * Get the list of permissions denied for this node. - * - * @return the list of denied permissions - */ - Set> getDenied(NodeRef nodeRef) - { - Set> deniedSet = new HashSet>(); - - // Loop over all denied permissions - NodePermissionEntry nodeEntry = permissionsDaoComponent.getPermissions(nodeRef); - if (nodeEntry != null) - { - for (PermissionEntry pe : nodeEntry.getPermissionEntries()) - { - if (pe.isDenied()) - { - // All the sets that grant this permission must be - // denied - // Note that granters includes the orginal permission - Set granters = modelDAO.getGrantingPermissions(pe.getPermissionReference()); - for (PermissionReference granter : granters) - { - deniedSet.add(new Pair(pe.getAuthority(), granter)); - } - - // All the things granted by this permission must be - // denied - Set grantees = modelDAO.getGranteePermissions(pe.getPermissionReference()); - for (PermissionReference grantee : grantees) - { - deniedSet.add(new Pair(pe.getAuthority(), grantee)); - } - - // All permission excludes all permissions available for - // the node. - if (pe.getPermissionReference().equals(getAllPermissionReference()) || pe.getPermissionReference().equals(OLD_ALL_PERMISSIONS_REFERENCE)) - { - for (PermissionReference deny : modelDAO.getAllPermissions(nodeRef)) - { - deniedSet.add(new Pair(pe.getAuthority(), deny)); - } - } - } - } - } - return deniedSet; - } - - /** - * Check that a given authentication is available on a node - * - * @return true if the check is required - */ - boolean checkRequired(Set authorisations, NodeRef nodeRef, Set> denied) - { - NodePermissionEntry nodeEntry = permissionsDaoComponent.getPermissions(nodeRef); - - // No permissions set - short cut to deny - if (nodeEntry == null) - { - return false; - } - - // Check if each permission allows - the first wins. - // We could have other voting style mechanisms here - for (PermissionEntry pe : nodeEntry.getPermissionEntries()) - { - if (isGranted(pe, authorisations, denied)) - { - return true; - } - } - return false; - } - - /** - * Is a permission granted - * - * @param pe - - * the permissions entry to consider - * @param granters - - * the set of granters - * @param authorisations - - * the set of authorities - * @param denied - - * the set of denied permissions/authority pais - * @return true if granted - */ - private boolean isGranted(PermissionEntry pe, Set authorisations, Set> denied) - { - // If the permission entry denies then we just deny - if (pe.isDenied()) - { - return false; - } - - // The permission is allowed but we deny it as it is in the denied - // set - - if (denied != null) - { - Pair specific = new Pair(pe.getAuthority(), required); - if (denied.contains(specific)) - { - return false; - } - } - - // any deny denies - - if (anyDenyDenies) - { - if (denied != null) - { - for (String auth : authorisations) - { - Pair specific = new Pair(auth, required); - if (denied.contains(specific)) - { - return false; - } - for (PermissionReference perm : granters) - { - specific = new Pair(auth, perm); - if (denied.contains(specific)) - { - return false; - } - } - } - } - } - - // If the permission has a match in both the authorities and - // granters list it is allowed - // It applies to the current user and it is granted - if (authorisations.contains(pe.getAuthority()) && granters.contains(pe.getPermissionReference())) - { - { - return true; - } - } - - // Default deny - return false; - } - - } - - /** - * Test a permission in the context of the new ACL implementation. All components of the ACL are in the object - - * there is no need to walk up the parent chain. Parent conditions cna not be applied as there is no context to do - * this. Child conditions can not be applied as there is no context to do this - * - * @author andyh - */ - - private class AclTest - { - /* - * The required permission. - */ - PermissionReference required; - - /* - * Granters of the permission - */ - Set granters; - - /* - * The additional permissions required at the node level. - */ - Set nodeRequirements = new HashSet(); - - /* - * The type name of the node. - */ - QName typeQName; - - /* - * The aspects set on the node. - */ - Set aspectQNames; - - /* - * Constructor just gets the additional requirements - */ - AclTest(PermissionReference required, QName typeQName, Set aspectQNames) - { - this.required = required; - this.typeQName = typeQName; - this.aspectQNames = aspectQNames; - - // Set the required node permissions - if (required.equals(getPermissionReference(ALL_PERMISSIONS))) - { - nodeRequirements = modelDAO.getRequiredPermissions(getPermissionReference(PermissionService.FULL_CONTROL), typeQName, aspectQNames, RequiredPermission.On.NODE); - } - else - { - nodeRequirements = modelDAO.getRequiredPermissions(required, typeQName, aspectQNames, RequiredPermission.On.NODE); - } - - if (modelDAO.getRequiredPermissions(required, typeQName, aspectQNames, RequiredPermission.On.PARENT).size() > 0) - { - throw new IllegalStateException("Parent permissions can not be checked for an acl"); - } - - if (modelDAO.getRequiredPermissions(required, typeQName, aspectQNames, RequiredPermission.On.CHILDREN).size() > 0) - { - throw new IllegalStateException("Child permissions can not be checked for an acl"); - } - - // Find all the permissions that grant the allowed permission - // All permissions are treated specially. - granters = new LinkedHashSet(128, 1.0f); - granters.addAll(modelDAO.getGrantingPermissions(required)); - granters.add(getAllPermissionReference()); - granters.add(OLD_ALL_PERMISSIONS_REFERENCE); - } - - /** - * Internal hook point for recursion - * - * @param authorisations - * @param nodeRef - * @param denied - * @param recursiveIn - * @return true if granted - */ - boolean evaluate(Set authorisations, Long aclId, PermissionContext context) - { - // Start out true and "and" all other results - boolean success = true; - - // Check the required permissions but not for sets they rely on - // their underlying permissions - if (modelDAO.checkPermission(required)) - { - - // We have to do the test as no parent will help us out - success &= hasSinglePermission(authorisations, aclId, context); - - if (!success) - { - return false; - } - } - - // Check the other permissions required on the node - for (PermissionReference pr : nodeRequirements) - { - // Build a new test - AclTest nt = new AclTest(pr, typeQName, aspectQNames); - success &= nt.evaluate(authorisations, aclId, context); - if (!success) - { - return false; - } - } - - return success; - } - - boolean hasSinglePermission(Set authorisations, Long aclId, PermissionContext context) - { - // Check global permission - - if (checkGlobalPermissions(authorisations)) - { - return true; - } - - return checkRequired(authorisations, aclId, context); - - } - - /** - * Check if we have a global permission - * - * @param authorisations - * @return true if granted - */ - private boolean checkGlobalPermissions(Set authorisations) - { - for (PermissionEntry pe : modelDAO.getGlobalPermissionEntries()) - { - if (isGranted(pe, authorisations)) - { - return true; - } - } - return false; - } - - /** - * Check that a given authentication is available on a node - * - * @param authorisations - * @param nodeRef - * @param denied - * @return true if a check is required - */ - boolean checkRequired(Set authorisations, Long aclId, PermissionContext context) - { - AccessControlList acl = aclDaoComponent.getAccessControlList(aclId); - - if (acl == null) - { - return false; - } - - if(anyDenyDenies) - { - Set> allowed = new HashSet>(); - - // Check if each permission allows - the first wins. - // We could have other voting style mechanisms here - for (AccessControlEntry ace : acl.getEntries()) - { - if (isDenied(ace, authorisations, allowed, context)) - { - return false; - } - } - } - - Set> denied = new HashSet>(); - - // Check if each permission allows - the first wins. - // We could have other voting style mechanisms here - for (AccessControlEntry ace : acl.getEntries()) - { - if (isGranted(ace, authorisations, denied, context)) - { - return true; - } - } - return false; - } - - /** - * Is a permission granted - * - * @param pe - - * the permissions entry to consider - * @param granters - - * the set of granters - * @param authorisations - - * the set of authorities - * @param denied - - * the set of denied permissions/authority pais - * @return true if granted - */ - private boolean isGranted(AccessControlEntry ace, Set authorisations, Set> denied, PermissionContext context) - { - // If the permission entry denies then we just deny - if (ace.getAccessStatus() == AccessStatus.DENIED) - { - denied.add(new Pair(ace.getAuthority(), ace.getPermission())); - - Set granters = modelDAO.getGrantingPermissions(ace.getPermission()); - for (PermissionReference granter : granters) - { - denied.add(new Pair(ace.getAuthority(), granter)); - } - - // All the things granted by this permission must be - // denied - Set grantees = modelDAO.getGranteePermissions(ace.getPermission()); - for (PermissionReference grantee : grantees) - { - denied.add(new Pair(ace.getAuthority(), grantee)); - } - - // All permission excludes all permissions available for - // the node. - if (ace.getPermission().equals(getAllPermissionReference()) || ace.getPermission().equals(OLD_ALL_PERMISSIONS_REFERENCE)) - { - for (PermissionReference deny : modelDAO.getAllPermissions(context.getType(), context.getAspects())) - { - denied.add(new Pair(ace.getAuthority(), deny)); - } - } - - return false; - } - - // The permission is allowed but we deny it as it is in the denied - // set - - if (denied != null) - { - Pair specific = new Pair(ace.getAuthority(), required); - if (denied.contains(specific)) - { - return false; - } - } - - // If the permission has a match in both the authorities and - // granters list it is allowed - // It applies to the current user and it is granted - if (authorisations.contains(ace.getAuthority()) && granters.contains(ace.getPermission())) - { - { - return true; - } - } - - // Default deny - return false; - } - - /** - * Is a permission granted - * - * @param pe - - * the permissions entry to consider - * @param granters - - * the set of granters - * @param authorisations - - * the set of authorities - * @param denied - - * the set of denied permissions/authority pais - * @return true if granted - */ - private boolean isDenied(AccessControlEntry ace, Set authorisations, Set> allowed, PermissionContext context) - { - // If the permission entry denies then we just deny - if (ace.getAccessStatus() == AccessStatus.ALLOWED) - { - allowed.add(new Pair(ace.getAuthority(), ace.getPermission())); - - Set granters = modelDAO.getGrantingPermissions(ace.getPermission()); - for (PermissionReference granter : granters) - { - allowed.add(new Pair(ace.getAuthority(), granter)); - } - - // All the things granted by this permission must be - // denied - Set grantees = modelDAO.getGranteePermissions(ace.getPermission()); - for (PermissionReference grantee : grantees) - { - allowed.add(new Pair(ace.getAuthority(), grantee)); - } - - // All permission excludes all permissions available for - // the node. - if (ace.getPermission().equals(getAllPermissionReference()) || ace.getPermission().equals(OLD_ALL_PERMISSIONS_REFERENCE)) - { - for (PermissionReference deny : modelDAO.getAllPermissions(context.getType(), context.getAspects())) - { - allowed.add(new Pair(ace.getAuthority(), deny)); - } - } - - return false; - } - - // The permission is denied but we allow it as it is in the allowed - // set - - if (allowed != null) - { - Pair specific = new Pair(ace.getAuthority(), required); - if (allowed.contains(specific)) - { - return false; - } - } - - - // If the permission has a match in both the authorities and - // granters list it is allowed - // It applies to the current user and it is granted - if (authorisations.contains(ace.getAuthority()) && granters.contains(ace.getPermission())) - { - { - return true; - } - } - - // Default allow - return false; - } - - - private boolean isGranted(PermissionEntry pe, Set authorisations) - { - // If the permission entry denies then we just deny - if (pe.isDenied()) - { - return false; - } - - // If the permission has a match in both the authorities and - // granters list it is allowed - // It applies to the current user and it is granted - if (granters.contains(pe.getPermissionReference()) && authorisations.contains(pe.getAuthority())) - { - { - return true; - } - } - - // Default deny - return false; - } - - } - - /** - * Ignores type and aspect requirements on the node - * - */ - private class UnconditionalAclTest - { - /* - * The required permission. - */ - PermissionReference required; - - /* - * Granters of the permission - */ - Set granters; - - /* - * The additional permissions required at the node level. - */ - Set nodeRequirements = new HashSet(); - - /* - * Constructor just gets the additional requirements - */ - UnconditionalAclTest(PermissionReference required) - { - this.required = required; - - // Set the required node permissions - if (required.equals(getPermissionReference(ALL_PERMISSIONS))) - { - nodeRequirements = modelDAO.getUnconditionalRequiredPermissions(getPermissionReference(PermissionService.FULL_CONTROL), RequiredPermission.On.NODE); - } - else - { - nodeRequirements = modelDAO.getUnconditionalRequiredPermissions(required, RequiredPermission.On.NODE); - } - - if (modelDAO.getUnconditionalRequiredPermissions(required, RequiredPermission.On.PARENT).size() > 0) - { - throw new IllegalStateException("Parent permissions can not be checked for an acl"); - } - - if (modelDAO.getUnconditionalRequiredPermissions(required, RequiredPermission.On.CHILDREN).size() > 0) - { - throw new IllegalStateException("Child permissions can not be checked for an acl"); - } - - // Find all the permissions that grant the allowed permission - // All permissions are treated specially. - granters = new LinkedHashSet(128, 1.0f); - granters.addAll(modelDAO.getGrantingPermissions(required)); - granters.add(getAllPermissionReference()); - granters.add(OLD_ALL_PERMISSIONS_REFERENCE); - } - - /** - * Internal hook point for recursion - * - * @param authorisations - * @param nodeRef - * @param denied - * @param recursiveIn - * @return true if granted - */ - boolean evaluate(String authority, Long aclId) - { - // Start out true and "and" all other results - boolean success = true; - - // Check the required permissions but not for sets they rely on - // their underlying permissions - //if (modelDAO.checkPermission(required)) - //{ - - // We have to do the test as no parent will help us out - success &= hasSinglePermission(authority, aclId); - - if (!success) - { - return false; - } - //} - - // Check the other permissions required on the node - for (PermissionReference pr : nodeRequirements) - { - // Build a new test - UnconditionalAclTest nt = new UnconditionalAclTest(pr); - success &= nt.evaluate(authority, aclId); - if (!success) - { - return false; - } - } - - return success; - } - - boolean hasSinglePermission(String authority, Long aclId) - { - // Check global permission - - if (checkGlobalPermissions(authority)) - { - return true; - } - - if(aclId == null) - { - return false; - } - else - { - return checkRequired(authority, aclId); - } - - } - - /** - * Check if we have a global permission - * - * @param authorisations - * @return true if granted - */ - private boolean checkGlobalPermissions(String authority) - { - for (PermissionEntry pe : modelDAO.getGlobalPermissionEntries()) - { - if (isGranted(pe, authority)) - { - return true; - } - } - return false; - } - - /** - * Check that a given authentication is available on a node - * - * @param authorisations - * @param nodeRef - * @param denied - * @return true if a check is required - */ - boolean checkRequired(String authority, Long aclId) - { - AccessControlList acl = aclDaoComponent.getAccessControlList(aclId); - - if (acl == null) - { - return false; - } - - Set> denied = new HashSet>(); - - // Check if each permission allows - the first wins. - // We could have other voting style mechanisms here - for (AccessControlEntry ace : acl.getEntries()) - { - if (isGranted(ace, authority, denied)) - { - return true; - } - } - return false; - } - - /** - * Is a permission granted - * - * @param pe - - * the permissions entry to consider - * @param granters - - * the set of granters - * @param authorisations - - * the set of authorities - * @param denied - - * the set of denied permissions/authority pais - * @return true if granted - */ - private boolean isGranted(AccessControlEntry ace, String authority, Set> denied) - { - // If the permission entry denies then we just deny - if (ace.getAccessStatus() == AccessStatus.DENIED) - { - denied.add(new Pair(ace.getAuthority(), ace.getPermission())); - - Set granters = modelDAO.getGrantingPermissions(ace.getPermission()); - for (PermissionReference granter : granters) - { - denied.add(new Pair(ace.getAuthority(), granter)); - } - - // All the things granted by this permission must be - // denied - Set grantees = modelDAO.getGranteePermissions(ace.getPermission()); - for (PermissionReference grantee : grantees) - { - denied.add(new Pair(ace.getAuthority(), grantee)); - } - - // All permission excludes all permissions available for - // the node. - if (ace.getPermission().equals(getAllPermissionReference()) || ace.getPermission().equals(OLD_ALL_PERMISSIONS_REFERENCE)) - { - for (PermissionReference deny : modelDAO.getAllPermissions()) - { - denied.add(new Pair(ace.getAuthority(), deny)); - } - } - - return false; - } - - // The permission is allowed but we deny it as it is in the denied - // set - - if (denied != null) - { - Pair specific = new Pair(ace.getAuthority(), required); - if (denied.contains(specific)) - { - return false; - } - } - - // If the permission has a match in both the authorities and - // granters list it is allowed - // It applies to the current user and it is granted - if (authority.equals(ace.getAuthority()) && granters.contains(ace.getPermission())) - { - { - return true; - } - } - - // Default deny - return false; - } - - private boolean isGranted(PermissionEntry pe, String authority) - { - // If the permission entry denies then we just deny - if (pe.isDenied()) - { - return false; - } - - // If the permission has a match in both the authorities and - // granters list it is allowed - // It applies to the current user and it is granted - if (granters.contains(pe.getPermissionReference()) && authority.equals(pe.getAuthority())) - { - { - return true; - } - } - - // Default deny - return false; - } - } - - /** - * Ignores type and aspect requirements on the node - * - */ - private class UnconditionalDeniedAclTest - { - /* - * The required permission. - */ - PermissionReference required; - - /* - * Granters of the permission - */ - Set granters; - - /* - * The additional permissions required at the node level. - */ - Set nodeRequirements = new HashSet(); - - /* - * Constructor just gets the additional requirements - */ - UnconditionalDeniedAclTest(PermissionReference required) - { - this.required = required; - - // Set the required node permissions - if (required.equals(getPermissionReference(ALL_PERMISSIONS))) - { - nodeRequirements = modelDAO.getUnconditionalRequiredPermissions(getPermissionReference(PermissionService.FULL_CONTROL), RequiredPermission.On.NODE); - } - else - { - nodeRequirements = modelDAO.getUnconditionalRequiredPermissions(required, RequiredPermission.On.NODE); - } - - if (modelDAO.getUnconditionalRequiredPermissions(required, RequiredPermission.On.PARENT).size() > 0) - { - throw new IllegalStateException("Parent permissions can not be checked for an acl"); - } - - if (modelDAO.getUnconditionalRequiredPermissions(required, RequiredPermission.On.CHILDREN).size() > 0) - { - throw new IllegalStateException("Child permissions can not be checked for an acl"); - } - - // Find all the permissions that grant the allowed permission - // All permissions are treated specially. - granters = new LinkedHashSet(128, 1.0f); - granters.addAll(modelDAO.getGrantingPermissions(required)); - granters.add(getAllPermissionReference()); - granters.add(OLD_ALL_PERMISSIONS_REFERENCE); - } - - /** - * Internal hook point for recursion - * - * @param authorisations - * @param nodeRef - * @param denied - * @param recursiveIn - * @return true if granted - */ - boolean evaluate(String authority, Long aclId) - { - // Start out true and "and" all other results - boolean success = true; - - // Check the required permissions but not for sets they rely on - // their underlying permissions - //if (modelDAO.checkPermission(required)) - //{ - - // We have to do the test as no parent will help us out - success &= hasSinglePermission(authority, aclId); - - if (!success) - { - return false; - } - //} - - // Check the other permissions required on the node - for (PermissionReference pr : nodeRequirements) - { - // Build a new test - UnconditionalDeniedAclTest nt = new UnconditionalDeniedAclTest(pr); - success &= nt.evaluate(authority, aclId); - if (!success) - { - return false; - } - } - - return success; - } - - boolean hasSinglePermission(String authority, Long aclId) - { - // Check global permission - - if (checkGlobalPermissions(authority)) - { - return true; - } - - if(aclId == null) - { - return false; - } - else - { - return checkRequired(authority, aclId); - } - - } - - /** - * Check if we have a global permission - * - * @param authorisations - * @return true if granted - */ - private boolean checkGlobalPermissions(String authority) - { - for (PermissionEntry pe : modelDAO.getGlobalPermissionEntries()) - { - if (isDenied(pe, authority)) - { - return true; - } - } - return false; - } - - /** - * Check that a given authentication is available on a node - * - * @param authorisations - * @param nodeRef - * @param denied - * @return true if a check is required - */ - boolean checkRequired(String authority, Long aclId) - { - AccessControlList acl = aclDaoComponent.getAccessControlList(aclId); - - if (acl == null) - { - return false; - } - - Set> allowed = new HashSet>(); - - // Check if each permission allows - the first wins. - // We could have other voting style mechanisms here - for (AccessControlEntry ace : acl.getEntries()) - { - if (isDenied(ace, authority, allowed)) - { - return true; - } - } - return false; - } - - /** - * Is a permission granted - * - * @param pe - - * the permissions entry to consider - * @param granters - - * the set of granters - * @param authorisations - - * the set of authorities - * @param denied - - * the set of denied permissions/authority pais - * @return true if granted - */ - private boolean isDenied(AccessControlEntry ace, String authority, Set> allowed) - { - // If the permission entry denies then we just deny - if (ace.getAccessStatus() == AccessStatus.ALLOWED) - { - allowed.add(new Pair(ace.getAuthority(), ace.getPermission())); - - Set granters = modelDAO.getGrantingPermissions(ace.getPermission()); - for (PermissionReference granter : granters) - { - allowed.add(new Pair(ace.getAuthority(), granter)); - } - - // All the things granted by this permission must be - // denied - Set grantees = modelDAO.getGranteePermissions(ace.getPermission()); - for (PermissionReference grantee : grantees) - { - allowed.add(new Pair(ace.getAuthority(), grantee)); - } - - // All permission excludes all permissions available for - // the node. - if (ace.getPermission().equals(getAllPermissionReference()) || ace.getPermission().equals(OLD_ALL_PERMISSIONS_REFERENCE)) - { - for (PermissionReference deny : modelDAO.getAllPermissions()) - { - allowed.add(new Pair(ace.getAuthority(), deny)); - } - } - - return false; - } - - // The permission is allowed but we deny it as it is in the denied - // set - - if (allowed != null) - { - Pair specific = new Pair(ace.getAuthority(), required); - if (allowed.contains(specific)) - { - return false; - } - } - - // If the permission has a match in both the authorities and - // granters list it is allowed - // It applies to the current user and it is granted - if (authority.equals(ace.getAuthority()) && granters.contains(ace.getPermission())) - { - { - return true; - } - } - - // Default deny - return false; - } - - private boolean isDenied(PermissionEntry pe, String authority) - { - // If the permission entry denies then we just deny - if (pe.isAllowed()) - { - return false; - } - - // If the permission has a match in both the authorities and - // granters list it is allowed - // It applies to the current user and it is granted - if (granters.contains(pe.getPermissionReference()) && authority.equals(pe.getAuthority())) - { - { - return true; - } - } - - // Default deny - return false; - } - } - - - private static class MutableBoolean - { - private boolean value; - - MutableBoolean(boolean value) - { - this.value = value; - } - - void setValue(boolean value) - { - this.value = value; - } - - boolean getValue() - { - return value; - } - } - - /** - * This methods checks whether the specified nodeRef instance is a version nodeRef (ie. in the 'version' store) - * - * @param nodeRef - version nodeRef - * @return true if version nodeRef false otherwise - */ - private boolean isVersionNodeRef(NodeRef nodeRef) - { - return nodeRef.getStoreRef().getProtocol().equals(VersionModel.STORE_PROTOCOL); - } - - /** - * Converts specified version nodeRef (eg. versionStore://...) to versioned nodeRef (eg. workspace://SpacesStore/...) - * - * @param nodeRef - always version nodeRef (ie. in the 'version' store) - * @return versioned nodeRef (ie.in the 'live' store) - */ - @SuppressWarnings("deprecation") - private NodeRef convertVersionNodeRefToVersionedNodeRef(NodeRef versionNodeRef) - { - Map properties = nodeService.getProperties(versionNodeRef); - - NodeRef nodeRef = null; - - // Switch VersionStore depending on configured impl - if (versionNodeRef.getStoreRef().getIdentifier().equals(Version2Model.STORE_ID)) - { - // V2 version store (eg. workspace://version2Store) - nodeRef = (NodeRef)properties.get(Version2Model.PROP_QNAME_FROZEN_NODE_REF); - } - else if (versionNodeRef.getStoreRef().getIdentifier().equals(VersionModel.STORE_ID)) - { - // Deprecated V1 version store (eg. workspace://lightWeightVersionStore) - nodeRef = new NodeRef((String) properties.get(VersionModel.PROP_QNAME_FROZEN_NODE_STORE_PROTOCOL), - (String) properties.get(VersionModel.PROP_QNAME_FROZEN_NODE_STORE_ID), - (String) properties.get(VersionModel.PROP_QNAME_FROZEN_NODE_ID)); - } - - return nodeRef; - } - - /** - * {@inheritDoc} - */ - @Override - public Set getAuthorisations() - { - // Use TX cache - @SuppressWarnings("unchecked") - Set auths = (Set) AlfrescoTransactionSupport.getResource("MyAuthCache"); - Authentication auth = AuthenticationUtil.getRunAsAuthentication(); - if (auths != null) - { - if (auth == null || !auths.contains(((User)auth.getPrincipal()).getUsername())) - { - auths = null; - } - } - if (auths == null) - { - auths = getCoreAuthorisations(auth); - AlfrescoTransactionSupport.bindResource("MyAuthCache", auths); - } - return Collections.unmodifiableSet(auths); - } - -} diff --git a/rm-server/source/java/org/alfresco/repo/security/permissions/impl/RMPermissionServiceImpl.java b/rm-server/source/java/org/alfresco/repo/security/permissions/impl/RMPermissionServiceImpl.java new file mode 100644 index 0000000000..21649f23bc --- /dev/null +++ b/rm-server/source/java/org/alfresco/repo/security/permissions/impl/RMPermissionServiceImpl.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2005-2012 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.security.permissions.impl; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; +import org.alfresco.repo.security.permissions.AccessControlEntry; +import org.alfresco.repo.security.permissions.AccessControlList; +import org.alfresco.service.cmr.security.PermissionService; + +/** + * Extends the core permission service implementation allowing the consideration of the read records + * permission. + *

+ * This is required for SOLR support. + * + * @author Roy Wetherall + */ +public class RMPermissionServiceImpl extends PermissionServiceImpl +{ + + /** + * Builds the set of authorities who can read the given ACL. No caching is done here. + * + * @return an unmodifiable set of authorities + */ + protected Set buildReaders(Long aclId) + { + AccessControlList acl = aclDaoComponent.getAccessControlList(aclId); + if (acl == null) + { + return Collections.emptySet(); + } + + HashSet assigned = new HashSet(); + HashSet readers = new HashSet(); + + for (AccessControlEntry ace : acl.getEntries()) + { + assigned.add(ace.getAuthority()); + } + + for (String authority : assigned) + { + UnconditionalAclTest test = new UnconditionalAclTest(getPermissionReference(PermissionService.READ)); + UnconditionalAclTest rmTest = new UnconditionalAclTest(getPermissionReference(RMPermissionModel.READ_RECORDS)); + if (test.evaluate(authority, aclId) || rmTest.evaluate(authority, aclId)) + { + readers.add(authority); + } + } + + return Collections.unmodifiableSet(readers); + } + + /** + * @param aclId + * @return set of authorities with read permission on the ACL + */ + protected Set buildReadersDenied(Long aclId) + { + HashSet assigned = new HashSet(); + HashSet denied = new HashSet(); + AccessControlList acl = aclDaoComponent.getAccessControlList(aclId); + + if (acl == null) + { + return denied; + } + + for (AccessControlEntry ace : acl.getEntries()) + { + assigned.add(ace.getAuthority()); + } + + for(String authority : assigned) + { + UnconditionalDeniedAclTest test = new UnconditionalDeniedAclTest(getPermissionReference(PermissionService.READ)); + UnconditionalDeniedAclTest rmTest = new UnconditionalDeniedAclTest(getPermissionReference(RMPermissionModel.READ_RECORDS)); + if(test.evaluate(authority, aclId) || rmTest.evaluate(authority, aclId)) + { + denied.add(authority); + } + } + + return denied; + } +} diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/NewRecordsManagementSecurityServiceImplTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/NewRecordsManagementSecurityServiceImplTest.java deleted file mode 100644 index 938768a545..0000000000 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/NewRecordsManagementSecurityServiceImplTest.java +++ /dev/null @@ -1,151 +0,0 @@ - -package org.alfresco.module.org_alfresco_module_rm.test.service; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; -import org.alfresco.service.cmr.repository.NodeRef; - -/** - * Records management security service test. - * - * @author Roy Wetherall - */ -public class NewRecordsManagementSecurityServiceImplTest extends BaseRMTestCase -{ - private NodeRef record; - private NodeRef recordToo; - - @Override - protected boolean isUserTest() - { - return true; - } - - @Override - protected void setupTestDataImpl() - { - super.setupTestDataImpl(); - - record = utils.createRecord(rmFolder, "record.txt"); - recordToo = utils.createRecord(rmFolder, "recordToo.txt"); - } - - - // TODO testGetProtectedAspects - - // TODO getProtectedProperties - - // TODO bootstrapDefaultRoles - - // TODO getRoles - - // TODO getRolesByUser - - // TODO getRole - - // TODO existsRole - - // TODO hasRMAdminRole - - // TODO createRole - - // TODO updateRole - - // TODO deleteRole - - // TODO assignRoleToAuthority - - // TODO setPermission - - // TODO deletePermission - - public void testExtendedReaders() - { - doTestInTransaction(new Test() - { - public Void run() - { - assertFalse(hasExtendedReadersAspect(filePlan)); - assertFalse(hasExtendedReadersAspect(rmContainer)); - assertFalse(hasExtendedReadersAspect(rmFolder)); - assertFalse(hasExtendedReadersAspect(record)); - - assertNull(securityService.getExtendedReaders(record)); - - Set extendedReaders = new HashSet(2); - extendedReaders.add("monkey"); - extendedReaders.add("elephant"); - - securityService.setExtendedReaders(record, extendedReaders); - - Map testMap = new HashMap(2); - testMap.put("monkey", Integer.valueOf(1)); - testMap.put("elephant", Integer.valueOf(1)); - - test(filePlan, testMap); - test(rmContainer, testMap); - test(rmFolder, testMap); - test(record, testMap); - - Set extendedReadersToo = new HashSet(2); - extendedReadersToo.add("monkey"); - extendedReadersToo.add("snake"); - - securityService.setExtendedReaders(recordToo, extendedReadersToo); - - Map testMapToo = new HashMap(2); - testMapToo.put("monkey", Integer.valueOf(1)); - testMapToo.put("snake", Integer.valueOf(1)); - - Map testMapThree = new HashMap(3); - testMapThree.put("monkey", Integer.valueOf(2)); - testMapThree.put("elephant", Integer.valueOf(1)); - testMapThree.put("snake", Integer.valueOf(1)); - - test(filePlan, testMapThree); - test(rmContainer, testMapThree); - test(rmFolder, testMapThree); - test(recordToo, testMapToo); - - return null; - } - - private boolean hasExtendedReadersAspect(NodeRef nodeRef) - { - return nodeService.hasAspect(nodeRef, ASPECT_EXTENDED_READERS); - } - - private void test(NodeRef nodeRef, Map testMap) - { - assertTrue(hasExtendedReadersAspect(nodeRef)); - - Map readersMap = (Map)nodeService.getProperty(nodeRef, PROP_READERS); - assertNotNull(readersMap); - assertEquals(testMap.size(), readersMap.size()); - - for (Map.Entry entry: testMap.entrySet()) - { - assertTrue(readersMap.containsKey(entry.getKey())); - assertEquals(entry.getValue(), readersMap.get(entry.getKey())); - - } - - Set readers = securityService.getExtendedReaders(nodeRef); - assertNotNull(readers); - assertEquals(testMap.size(), readers.size()); - } - }); - } - - // TODO getExtendedReaders - - // TODO setExtendedReaders - - // TODO removeExtendedReaders - - // TODO removeAllExtendedReaders -} diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/RecordsManagementSecurityServiceImplTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/RecordsManagementSecurityServiceImplTest.java index a1872523a8..1268d30d11 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/RecordsManagementSecurityServiceImplTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/RecordsManagementSecurityServiceImplTest.java @@ -1,695 +1,152 @@ -/* - * Copyright (C) 2005-2011 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ + package org.alfresco.module.org_alfresco_module_rm.test.service; -import java.io.Serializable; -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.error.AlfrescoRuntimeException; -import org.alfresco.model.ContentModel; -import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementActionService; -import org.alfresco.module.org_alfresco_module_rm.capability.Capability; -import org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService; -import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; -import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; -import org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService; -import org.alfresco.module.org_alfresco_module_rm.security.Role; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.repo.transaction.RetryingTransactionHelper; -import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; -import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; 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; -import org.alfresco.service.cmr.security.AuthorityType; -import org.alfresco.service.cmr.security.MutableAuthenticationService; -import org.alfresco.service.cmr.security.PermissionService; -import org.alfresco.service.cmr.security.PersonService; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.namespace.QName; -import org.alfresco.util.BaseSpringTest; -import org.alfresco.util.GUID; -import org.alfresco.util.PropertyMap; /** - * Security service implementation unit test + * Records management security service test. * * @author Roy Wetherall */ -public class RecordsManagementSecurityServiceImplTest extends BaseSpringTest - implements RecordsManagementModel -{ - protected static StoreRef SPACES_STORE = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore"); +public class RecordsManagementSecurityServiceImplTest extends BaseRMTestCase +{ + private NodeRef record; + private NodeRef recordToo; - private NodeService nodeService; - private MutableAuthenticationService authenticationService; - private AuthorityService authorityService; - private PermissionService permissionService; - private PersonService personService; - private RecordsManagementSecurityService rmSecurityService; - private RecordsManagementActionService rmActionService; - private RetryingTransactionHelper transactionHelper; - private CapabilityService capabilityService; - - @Override - protected void onSetUpInTransaction() throws Exception - { - super.onSetUpInTransaction(); - - // Get the service required in the tests - this.nodeService = (NodeService)this.applicationContext.getBean("NodeService"); - this.authenticationService = (MutableAuthenticationService)this.applicationContext.getBean("AuthenticationService"); - this.personService = (PersonService)this.applicationContext.getBean("PersonService"); - this.authorityService = (AuthorityService)this.applicationContext.getBean("authorityService"); - this.rmSecurityService = (RecordsManagementSecurityService)this.applicationContext.getBean("RecordsManagementSecurityService"); - this.transactionHelper = (RetryingTransactionHelper)this.applicationContext.getBean("retryingTransactionHelper"); - this.permissionService = (PermissionService)this.applicationContext.getBean("PermissionService"); - this.rmActionService = (RecordsManagementActionService)this.applicationContext.getBean("RecordsManagementActionService"); - this.capabilityService = (CapabilityService)this.applicationContext.getBean("CapabilityService"); - - // Set the current security context as admin - AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName()); - } - - public void testRoles() - { - final NodeRef rmRootNode = createRMRootNodeRef(); - - setComplete(); - endTransaction(); - - transactionHelper.doInTransaction(new RetryingTransactionCallback() - { - public Object execute() throws Throwable - { - Set roles = rmSecurityService.getRoles(rmRootNode); - assertNotNull(roles); - assertEquals(5, roles.size()); - - rmSecurityService.createRole(rmRootNode, "MyRole", "My Role", getListOfCapabilities(5)); - - roles = rmSecurityService.getRoles(rmRootNode); - assertNotNull(roles); - assertEquals(6, roles.size()); - - Role role = findRole(roles, "MyRole"); - assertNotNull(role); - assertEquals("MyRole", role.getName()); - assertEquals("My Role", role.getDisplayLabel()); - assertNotNull(role.getCapabilities()); - assertEquals(5, role.getCapabilities().size()); - assertNotNull(role.getRoleGroupName()); - - // Add a user to the role - String userName = createAndAddUserToRole(role.getRoleGroupName()); - - // Check that we can retrieve the users roles - Set userRoles = rmSecurityService.getRolesByUser(rmRootNode, userName); - assertNotNull(userRoles); - assertEquals(1, userRoles.size()); - Role userRole = userRoles.iterator().next(); - assertEquals("MyRole", userRole.getName()); - - try - { - rmSecurityService.createRole(rmRootNode, "MyRole", "My Role", getListOfCapabilities(5)); - fail("Duplicate role id's not allowed for the same rm root node"); - } - catch (AlfrescoRuntimeException e) - { - // Expected - } - - rmSecurityService.createRole(rmRootNode, "MyRole2", "My Role", getListOfCapabilities(5)); - - roles = rmSecurityService.getRoles(rmRootNode); - assertNotNull(roles); - assertEquals(7, roles.size()); - - Set list = getListOfCapabilities(3, 4); - assertEquals(3, list.size()); - - Role result = rmSecurityService.updateRole(rmRootNode, "MyRole", "SomethingDifferent", list); - - assertNotNull(result); - assertEquals("MyRole", result.getName()); - assertEquals("SomethingDifferent", result.getDisplayLabel()); - assertNotNull(result.getCapabilities()); - assertEquals(3, result.getCapabilities().size()); - assertNotNull(result.getRoleGroupName()); - - roles = rmSecurityService.getRoles(rmRootNode); - assertNotNull(roles); - assertEquals(7, roles.size()); - - Role role2 = findRole(roles, "MyRole"); - assertNotNull(role2); - assertEquals("MyRole", role2.getName()); - assertEquals("SomethingDifferent", role2.getDisplayLabel()); - assertNotNull(role2.getCapabilities()); - assertEquals(3, role2.getCapabilities().size()); - assertNotNull(role2.getRoleGroupName()); - - rmSecurityService.deleteRole(rmRootNode, "MyRole2"); - - roles = rmSecurityService.getRoles(rmRootNode); - assertNotNull(roles); - assertEquals(6, roles.size()); - - return null; - } - }); - } - - private Role findRole(Set roles, String name) - { - Role result = null; - for (Role role : roles) - { - if (name.equals(role.getName()) == true) - { - result = role; - break; - } - } - - return result; - } - - private Set getListOfCapabilities(int size) - { - return getListOfCapabilities(size, 0); - } - - private Set getListOfCapabilities(int size, int offset) - { - Set result = new HashSet(size); - Set caps = capabilityService.getCapabilities(false); - int count = 0; - for (Capability cap : caps) - { - if (count < size+offset) - { - if (count >= offset) - { - result.add(cap); - } - } - else - { - break; - } - count ++; - } - return result; - } - - private NodeRef createRMRootNodeRef() - { - NodeRef root = this.nodeService.getRootNode(SPACES_STORE); - NodeRef filePlan = this.nodeService.createNode(root, ContentModel.ASSOC_CHILDREN, ContentModel.ASSOC_CHILDREN, TYPE_FILE_PLAN).getChildRef(); - - return filePlan; - } - - private NodeRef addFilePlanCompoent(NodeRef parent, QName type) - { - String id = GUID.generate(); - String seriesName = "Series" + id; - Map props = new HashMap(2); - props.put(ContentModel.PROP_NAME, seriesName); - props.put(PROP_IDENTIFIER, id); - return nodeService.createNode( - parent, - ContentModel.ASSOC_CONTAINS, - QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, seriesName), - type, - props).getChildRef(); - } - - private String createAndAddUserToRole(String role) - { - // Create an athentication - String userName = GUID.generate(); - authenticationService.createAuthentication(userName, "PWD".toCharArray()); - - // Create a person - PropertyMap ppOne = new PropertyMap(4); - ppOne.put(ContentModel.PROP_USERNAME, userName); - ppOne.put(ContentModel.PROP_FIRSTNAME, "firstName"); - ppOne.put(ContentModel.PROP_LASTNAME, "lastName"); - ppOne.put(ContentModel.PROP_EMAIL, "email@email.com"); - ppOne.put(ContentModel.PROP_JOBTITLE, "jobTitle"); - personService.createPerson(ppOne); - - // Assign the new user to the role passed - authorityService.addAuthority(role, userName); - - return userName; - } - - private String createUser() + @Override + protected boolean isUserTest() { - // Create an athentication - String userName = GUID.generate(); - authenticationService.createAuthentication(userName, "PWD".toCharArray()); - - // Create a person - PropertyMap ppOne = new PropertyMap(4); - ppOne.put(ContentModel.PROP_USERNAME, userName); - ppOne.put(ContentModel.PROP_FIRSTNAME, "firstName"); - ppOne.put(ContentModel.PROP_LASTNAME, "lastName"); - ppOne.put(ContentModel.PROP_EMAIL, "email@email.com"); - ppOne.put(ContentModel.PROP_JOBTITLE, "jobTitle"); - personService.createPerson(ppOne); - - return userName; + return true; } - - public void testExecutionAsRMAdmin() - { - final NodeRef filePlan = createRMRootNodeRef(); + + @Override + protected void setupTestDataImpl() + { + super.setupTestDataImpl(); - setComplete(); - endTransaction(); - - transactionHelper.doInTransaction(new RetryingTransactionCallback() + record = utils.createRecord(rmFolder, "record.txt"); + recordToo = utils.createRecord(rmFolder, "recordToo.txt"); + } + + + // TODO testGetProtectedAspects + + // TODO getProtectedProperties + + // TODO bootstrapDefaultRoles + + // TODO getRoles + + // TODO getRolesByUser + + // TODO getRole + + // TODO existsRole + + // TODO hasRMAdminRole + + // TODO createRole + + // TODO updateRole + + // TODO deleteRole + + // TODO assignRoleToAuthority + + // TODO setPermission + + // TODO deletePermission + + public void testExtendedReaders() + { + doTestInTransaction(new Test() { - public Object execute() throws Throwable + public Void run() { - System.out.println("Groups:"); - Set temp = authorityService.getAllRootAuthorities(AuthorityType.GROUP); - for (String g : temp) + assertFalse(hasExtendedReadersAspect(filePlan)); + assertFalse(hasExtendedReadersAspect(rmContainer)); + assertFalse(hasExtendedReadersAspect(rmFolder)); + assertFalse(hasExtendedReadersAspect(record)); + + assertNull(securityService.getExtendedReaders(record)); + + Set extendedReaders = new HashSet(2); + extendedReaders.add("monkey"); + extendedReaders.add("elephant"); + + securityService.setExtendedReaders(record, extendedReaders); + + Map testMap = new HashMap(2); + testMap.put("monkey", Integer.valueOf(1)); + testMap.put("elephant", Integer.valueOf(1)); + + test(filePlan, testMap); + test(rmContainer, testMap); + test(rmFolder, testMap); + test(record, testMap); + + Set extendedReadersToo = new HashSet(2); + extendedReadersToo.add("monkey"); + extendedReadersToo.add("snake"); + + securityService.setExtendedReaders(recordToo, extendedReadersToo); + + Map testMapToo = new HashMap(2); + testMapToo.put("monkey", Integer.valueOf(1)); + testMapToo.put("snake", Integer.valueOf(1)); + + Map testMapThree = new HashMap(3); + testMapThree.put("monkey", Integer.valueOf(2)); + testMapThree.put("elephant", Integer.valueOf(1)); + testMapThree.put("snake", Integer.valueOf(1)); + + test(filePlan, testMapThree); + test(rmContainer, testMapThree); + test(rmFolder, testMapThree); + test(recordToo, testMapToo); + + return null; + } + + private boolean hasExtendedReadersAspect(NodeRef nodeRef) + { + return nodeService.hasAspect(nodeRef, ASPECT_EXTENDED_READERS); + } + + @SuppressWarnings("unchecked") + private void test(NodeRef nodeRef, Map testMap) + { + assertTrue(hasExtendedReadersAspect(nodeRef)); + + Map readersMap = (Map)nodeService.getProperty(nodeRef, PROP_READERS); + assertNotNull(readersMap); + assertEquals(testMap.size(), readersMap.size()); + + for (Map.Entry entry: testMap.entrySet()) { - System.out.println(" - " + g); - } - System.out.println(""); - - assertTrue(permissionService.hasPermission(filePlan, RMPermissionModel.READ_RECORDS).equals(AccessStatus.ALLOWED)); - assertTrue(permissionService.hasPermission(filePlan, RMPermissionModel.FILE_RECORDS).equals(AccessStatus.ALLOWED)); - assertTrue(permissionService.hasPermission(filePlan, RMPermissionModel.FILING).equals(AccessStatus.ALLOWED)); - - Role adminRole = rmSecurityService.getRole(filePlan, "Administrator"); - assertNotNull(adminRole); - String adminUser = createAndAddUserToRole(adminRole.getRoleGroupName()); - AuthenticationUtil.setFullyAuthenticatedUser(adminUser); - - try - { - assertTrue(permissionService.hasPermission(filePlan, RMPermissionModel.READ_RECORDS).equals(AccessStatus.ALLOWED)); - assertTrue(permissionService.hasPermission(filePlan, RMPermissionModel.FILE_RECORDS).equals(AccessStatus.ALLOWED)); - assertTrue(permissionService.hasPermission(filePlan, RMPermissionModel.FILING).equals(AccessStatus.ALLOWED)); + assertTrue(readersMap.containsKey(entry.getKey())); + assertEquals(entry.getValue(), readersMap.get(entry.getKey())); - // Read the properties of the filePlan - nodeService.getProperties(filePlan); - } - finally - { - AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName()); } - return null; - } - }); - } - - public void testDefaultRolesBootstrap() - { - NodeRef rootNode = nodeService.getRootNode(SPACES_STORE); - final NodeRef filePlan = nodeService.createNode(rootNode, ContentModel.ASSOC_CHILDREN, - TYPE_FILE_PLAN, - TYPE_FILE_PLAN).getChildRef(); - - setComplete(); - endTransaction(); - - transactionHelper.doInTransaction(new RetryingTransactionCallback() - { - - public Object execute() throws Throwable - { - Set roles = rmSecurityService.getRoles(filePlan); - assertNotNull(roles); - assertEquals(5, roles.size()); - - Role role = rmSecurityService.getRole(filePlan, "User"); - assertNotNull(role); - assertEquals("User", role.getName()); - assertNotNull(role.getDisplayLabel()); - Set caps = role.getCapabilities(); - assertNotNull(caps); - System.out.println("\nUser capabilities: "); - for (String cap : caps) - { - assertNotNull(capabilityService.getCapability(cap)); - System.out.println(cap); - } - - role = rmSecurityService.getRole(filePlan, "PowerUser"); - assertNotNull(role); - assertEquals("PowerUser", role.getName()); - assertNotNull(role.getDisplayLabel()); - caps = role.getCapabilities(); - assertNotNull(caps); - System.out.println("\nPowerUser capabilities: "); - for (String cap : caps) - { - assertNotNull(capabilityService.getCapability(cap)); - System.out.println(cap); - } - - role = rmSecurityService.getRole(filePlan, "SecurityOfficer"); - assertNotNull(role); - assertEquals("SecurityOfficer", role.getName()); - assertNotNull(role.getDisplayLabel()); - caps = role.getCapabilities(); - assertNotNull(caps); - System.out.println("\nSecurityOfficer capabilities: "); - for (String cap : caps) - { - assertNotNull(capabilityService.getCapability(cap)); - System.out.println(cap); - } - - role = rmSecurityService.getRole(filePlan, "RecordsManager"); - assertNotNull(role); - assertEquals("RecordsManager", role.getName()); - assertNotNull(role.getDisplayLabel()); - caps = role.getCapabilities(); - assertNotNull(caps); - System.out.println("\nRecordsManager capabilities: "); - for (String cap : caps) - { - assertNotNull(capabilityService.getCapability(cap)); - System.out.println(cap); - } - - role = rmSecurityService.getRole(filePlan, "Administrator"); - assertNotNull(role); - assertEquals("Administrator", role.getName()); - assertNotNull(role.getDisplayLabel()); - caps = role.getCapabilities(); - assertNotNull(caps); - System.out.println("\nAdministrator capabilities: "); - for (String cap : caps) - { - assertNotNull("No capability called " + cap, capabilityService.getCapability(cap)); - System.out.println(cap); - } - - return null; - } - - }); - } - - public void xtestCreateNewRMUserAccessToFilePlan() - { - final NodeRef rmRootNode = createRMRootNodeRef(); - - final NodeRef seriesOne = addFilePlanCompoent(rmRootNode, TYPE_RECORD_CATEGORY); - final NodeRef seriesTwo = addFilePlanCompoent(rmRootNode, TYPE_RECORD_CATEGORY); - final NodeRef seriesThree = addFilePlanCompoent(rmRootNode, TYPE_RECORD_CATEGORY); - - final NodeRef catOne = addFilePlanCompoent(seriesOne, TYPE_RECORD_CATEGORY); - final NodeRef catTwo = addFilePlanCompoent(seriesOne, TYPE_RECORD_CATEGORY); - final NodeRef catThree = addFilePlanCompoent(seriesOne, TYPE_RECORD_CATEGORY); - - final NodeRef folderOne = addFilePlanCompoent(catOne, TYPE_RECORD_FOLDER); - final NodeRef folderTwo = addFilePlanCompoent(catOne, TYPE_RECORD_FOLDER); - final NodeRef folderThree = addFilePlanCompoent(catOne, TYPE_RECORD_FOLDER); - - setComplete(); - endTransaction(); - - final String user = transactionHelper.doInTransaction(new RetryingTransactionCallback() - { - public String execute() throws Throwable - { - // Create a new role - Set caps = new HashSet(1); - caps.add(capabilityService.getCapability(RMPermissionModel.VIEW_RECORDS)); - - Role role = rmSecurityService.createRole(rmRootNode, "TestRole", "My Test Role", caps); - String user = createUser(); - - // Check the role group and allRole group are set up correctly - Set groups = authorityService.getContainingAuthorities(AuthorityType.GROUP, role.getRoleGroupName(), true); - assertNotNull(groups); - // expect allRole group and the capability group - assertEquals(1, groups.size()); - List tempList = new ArrayList(groups); - assertTrue(tempList.get(0).startsWith("GROUP_AllRoles")); - - // User shouldn't be able to see the file plan node - AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() - { - public Object doWork() throws Exception - { - // Check the permissions of the group on the root node - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(rmRootNode, RMPermissionModel.READ_RECORDS)); - - try - { - nodeService.getChildAssocs(rmRootNode); - fail("The user shouldn't be able to read the children"); - } - catch (AlfrescoRuntimeException e) - { - // expected - } - - return null; - } - }, user); - - // Assign the new user to the role - rmSecurityService.assignRoleToAuthority(rmRootNode, role.getName(), user); - - return user; - } - }); - - transactionHelper.doInTransaction(new RetryingTransactionCallback() - { - public Object execute() throws Throwable - { - // Prove that all the series are there - List assocs = nodeService.getChildAssocs(rmRootNode); - assertNotNull(assocs); - assertEquals(3, assocs.size()); - - // User should be able to see the file plan node - AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() - { - public Object doWork() throws Exception - { - // Check user has read on the root - // assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(rmRootNode, RMPermissionModel.READ_RECORDS)); - - // Check that the user can not see any of the series - List assocs = nodeService.getChildAssocs(rmRootNode); - assertNotNull(assocs); - assertEquals(0, assocs.size()); - - return null; - } - }, user); - - // Add read permissions to one of the series - permissionService.setPermission(seriesOne, user, RMPermissionModel.READ_RECORDS, true); - - // Show that user can now see that series - AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() - { - public Object doWork() throws Exception - { - // Check that the user can not see any of the series - List assocs = nodeService.getChildAssocs(rmRootNode); - assertNotNull(assocs); - assertEquals(1, assocs.size()); - - return null; - } - }, user); - - // Add the read permission and file permission to get to the folder - permissionService.setPermission(catOne, user, RMPermissionModel.READ_RECORDS, true); - permissionService.setPermission(folderOne, user, RMPermissionModel.FILING, true); - - // TODO check visibility of items as we add the permissions - // TODO check that records inherit the permissions ok - - // Try and close the folder as the new user - AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() - { - public Object doWork() throws Exception - { - try - { - rmActionService.executeRecordsManagementAction(folderOne, "closeRecordFolder"); - fail("User does not have the capability for this"); - } - catch (org.alfresco.repo.security.permissions.AccessDeniedException exception) - { - // expected - } - - return null; - } - }, user); - - // Add the capability to the role - Set caps2 = new HashSet(1); - caps2.add(capabilityService.getCapability(RMPermissionModel.VIEW_RECORDS)); - caps2.add(capabilityService.getCapability(RMPermissionModel.CLOSE_FOLDERS)); - rmSecurityService.updateRole(rmRootNode, "TestRole", "My Test Role", caps2); - - Set aps = permissionService.getAllSetPermissions(rmRootNode); - System.out.println("\nPermissions on new series node: "); - for (AccessPermission ap : aps) - { - System.out.println(" - " + ap.getAuthority() + " has " + ap.getPermission()); - } - - // Try and close the folder as the new user - AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() - { - public Object doWork() throws Exception - { - assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(rmRootNode, RMPermissionModel.CLOSE_FOLDERS)); - - rmActionService.executeRecordsManagementAction(folderOne, "closeRecordFolder"); - - return null; - } - }, user); - - return null; - } - }); - } - - public void testSetPermissions() - { - final NodeRef rmRootNode = createRMRootNodeRef(); - - final NodeRef seriesOne = addFilePlanCompoent(rmRootNode, TYPE_RECORD_CATEGORY); - final NodeRef seriesTwo = addFilePlanCompoent(rmRootNode, TYPE_RECORD_CATEGORY); - final NodeRef seriesThree = addFilePlanCompoent(rmRootNode, TYPE_RECORD_CATEGORY); - - final NodeRef catOne = addFilePlanCompoent(seriesOne, TYPE_RECORD_CATEGORY); - final NodeRef catTwo = addFilePlanCompoent(seriesOne, TYPE_RECORD_CATEGORY); - final NodeRef catThree = addFilePlanCompoent(seriesOne, TYPE_RECORD_CATEGORY); - - final NodeRef folderOne = addFilePlanCompoent(catOne, TYPE_RECORD_FOLDER); - final NodeRef folderTwo = addFilePlanCompoent(catOne, TYPE_RECORD_FOLDER); - final NodeRef folderThree = addFilePlanCompoent(catOne, TYPE_RECORD_FOLDER); - - setComplete(); - endTransaction(); - - transactionHelper.doInTransaction(new RetryingTransactionCallback() - { - public Object execute() throws Throwable - { - // Create a new role - Set caps = new HashSet(1); - caps.add(capabilityService.getCapability(RMPermissionModel.VIEW_RECORDS)); - - Role role = rmSecurityService.createRole(rmRootNode, "TestRole", "My Test Role", caps); - String user = createUser(); - - rmSecurityService.assignRoleToAuthority(rmRootNode, role.getName(), user); - - AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() - { - public Object doWork() throws Exception - { - assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(rmRootNode, RMPermissionModel.READ_RECORDS)); - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(seriesOne, RMPermissionModel.READ_RECORDS)); - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(seriesTwo, RMPermissionModel.READ_RECORDS)); - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(seriesThree, RMPermissionModel.READ_RECORDS)); - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(catOne, RMPermissionModel.READ_RECORDS)); - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(catTwo, RMPermissionModel.READ_RECORDS)); - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(catThree, RMPermissionModel.READ_RECORDS)); - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folderOne, RMPermissionModel.READ_RECORDS)); - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folderTwo, RMPermissionModel.READ_RECORDS)); - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folderThree, RMPermissionModel.READ_RECORDS)); - - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(rmRootNode, RMPermissionModel.FILING)); - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(seriesOne, RMPermissionModel.FILING)); - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(seriesTwo, RMPermissionModel.FILING)); - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(seriesThree, RMPermissionModel.FILING)); - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(catOne, RMPermissionModel.FILING)); - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(catTwo, RMPermissionModel.FILING)); - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(catThree, RMPermissionModel.FILING)); - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folderOne, RMPermissionModel.FILING)); - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folderTwo, RMPermissionModel.FILING)); - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folderThree, RMPermissionModel.FILING)); - - return null; - } - }, user); - - rmSecurityService.setPermission(catOne, user, RMPermissionModel.FILING); - - AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() - { - public Object doWork() throws Exception - { - assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(rmRootNode, RMPermissionModel.READ_RECORDS)); - assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(seriesOne, RMPermissionModel.READ_RECORDS)); - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(seriesTwo, RMPermissionModel.READ_RECORDS)); - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(seriesThree, RMPermissionModel.READ_RECORDS)); - assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(catOne, RMPermissionModel.READ_RECORDS)); - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(catTwo, RMPermissionModel.READ_RECORDS)); - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(catThree, RMPermissionModel.READ_RECORDS)); - assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folderOne, RMPermissionModel.READ_RECORDS)); - assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folderTwo, RMPermissionModel.READ_RECORDS)); - assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folderThree, RMPermissionModel.READ_RECORDS)); - - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(rmRootNode, RMPermissionModel.FILING)); - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(seriesOne, RMPermissionModel.FILING)); - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(seriesTwo, RMPermissionModel.FILING)); - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(seriesThree, RMPermissionModel.FILING)); - assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(catOne, RMPermissionModel.FILING)); - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(catTwo, RMPermissionModel.FILING)); - assertEquals(AccessStatus.DENIED, permissionService.hasPermission(catThree, RMPermissionModel.FILING)); - assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folderOne, RMPermissionModel.FILING)); - assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folderTwo, RMPermissionModel.FILING)); - assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folderThree, RMPermissionModel.FILING)); - - return null; - } - }, user); - - return null; + Set readers = securityService.getExtendedReaders(nodeRef); + assertNotNull(readers); + assertEquals(testMap.size(), readers.size()); } }); } + + // TODO getExtendedReaders + + // TODO setExtendedReaders + + // TODO removeExtendedReaders + + // TODO removeAllExtendedReaders }