diff --git a/config/alfresco/core-services-context.xml b/config/alfresco/core-services-context.xml index 7aab2c1d04..90d0af668f 100644 --- a/config/alfresco/core-services-context.xml +++ b/config/alfresco/core-services-context.xml @@ -42,6 +42,9 @@ ${db.pool.max} + + ${db.pool.maxIdleTime} + 1 diff --git a/config/alfresco/public-services-security-context.xml b/config/alfresco/public-services-security-context.xml index 28d8a48802..f3980481d6 100644 --- a/config/alfresco/public-services-security-context.xml +++ b/config/alfresco/public-services-security-context.xml @@ -98,6 +98,9 @@ + + + diff --git a/config/alfresco/repository.properties b/config/alfresco/repository.properties index 47d1746087..95752d6830 100644 --- a/config/alfresco/repository.properties +++ b/config/alfresco/repository.properties @@ -61,6 +61,7 @@ db.username=alfresco db.password=alfresco db.pool.initial=10 db.pool.max=20 +db.pool.maxIdleTime=120 # Email configuration diff --git a/source/java/org/alfresco/repo/security/permissions/dynamic/LockOwnerDynamicAuthority.java b/source/java/org/alfresco/repo/security/permissions/dynamic/LockOwnerDynamicAuthority.java index 40cd3b8d36..f952d5dd2b 100644 --- a/source/java/org/alfresco/repo/security/permissions/dynamic/LockOwnerDynamicAuthority.java +++ b/source/java/org/alfresco/repo/security/permissions/dynamic/LockOwnerDynamicAuthority.java @@ -16,10 +16,13 @@ */ package org.alfresco.repo.security.permissions.dynamic; +import org.alfresco.model.ContentModel; import org.alfresco.repo.security.permissions.DynamicAuthority; import org.alfresco.service.cmr.lock.LockService; import org.alfresco.service.cmr.lock.LockStatus; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; import org.alfresco.service.cmr.security.PermissionService; import org.springframework.beans.factory.InitializingBean; @@ -28,6 +31,9 @@ public class LockOwnerDynamicAuthority implements DynamicAuthority, Initializing { private LockService lockService; + + private NodeService nodeService; + public LockOwnerDynamicAuthority() { @@ -36,7 +42,19 @@ public class LockOwnerDynamicAuthority implements DynamicAuthority, Initializing public boolean hasAuthority(NodeRef nodeRef, String userName) { - return lockService.getLockStatus(nodeRef) == LockStatus.LOCK_OWNER; + if(lockService.getLockStatus(nodeRef) == LockStatus.LOCK_OWNER) + { + return true; + } + if(nodeService.hasAspect(nodeRef, ContentModel.ASPECT_WORKING_COPY)) + { + NodeRef originial = DefaultTypeConverter.INSTANCE.convert(NodeRef.class, nodeService.getProperty(nodeRef, ContentModel.PROP_COPY_REFERENCE)); + return (lockService.getLockStatus(originial) == LockStatus.LOCK_OWNER); + } + else + { + return false; + } } public String getAuthority() @@ -48,7 +66,11 @@ public class LockOwnerDynamicAuthority implements DynamicAuthority, Initializing { if(lockService == null) { - throw new IllegalStateException("A lock service must be set"); + throw new IllegalStateException("The LockService must be set"); + } + if(nodeService == null) + { + throw new IllegalStateException("The NodeService service must be set"); } } @@ -58,6 +80,12 @@ public class LockOwnerDynamicAuthority implements DynamicAuthority, Initializing this.lockService = lockService; } + + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + } diff --git a/source/java/org/alfresco/repo/security/permissions/dynamic/LockOwnerDynamicAuthorityTest.java b/source/java/org/alfresco/repo/security/permissions/dynamic/LockOwnerDynamicAuthorityTest.java index 6504f772a7..c7e790325d 100644 --- a/source/java/org/alfresco/repo/security/permissions/dynamic/LockOwnerDynamicAuthorityTest.java +++ b/source/java/org/alfresco/repo/security/permissions/dynamic/LockOwnerDynamicAuthorityTest.java @@ -24,6 +24,7 @@ import org.alfresco.model.ContentModel; import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.security.authentication.MutableAuthenticationDao; import org.alfresco.service.ServiceRegistry; +import org.alfresco.service.cmr.coci.CheckOutCheckInService; import org.alfresco.service.cmr.lock.LockService; import org.alfresco.service.cmr.lock.LockStatus; import org.alfresco.service.cmr.lock.LockType; @@ -32,6 +33,7 @@ import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.AuthenticationService; +import org.alfresco.service.cmr.security.OwnableService; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.transaction.TransactionService; import org.alfresco.util.ApplicationContextHelper; @@ -59,6 +61,10 @@ public class LockOwnerDynamicAuthorityTest extends TestCase private LockOwnerDynamicAuthority dynamicAuthority; + private CheckOutCheckInService checkOutCheckInService; + + private OwnableService ownableService; + public LockOwnerDynamicAuthorityTest() { super(); @@ -77,7 +83,9 @@ public class LockOwnerDynamicAuthorityTest extends TestCase lockService = (LockService) ctx.getBean("lockService"); permissionService = (PermissionService) ctx.getBean("permissionService"); authenticationDAO = (MutableAuthenticationDao) ctx.getBean("alfDaoImpl"); - + checkOutCheckInService = (CheckOutCheckInService) ctx.getBean("checkOutCheckInService"); + ownableService = (OwnableService) ctx.getBean("ownableService"); + authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); TransactionService transactionService = (TransactionService) ctx.getBean(ServiceRegistry.TRANSACTION_SERVICE @@ -150,7 +158,6 @@ public class LockOwnerDynamicAuthorityTest extends TestCase assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(rootNodeRef, PermissionService.CHECK_OUT)); assertEquals(AccessStatus.DENIED, permissionService.hasPermission(rootNodeRef, PermissionService.CHECK_IN)); assertEquals(AccessStatus.DENIED, permissionService.hasPermission(rootNodeRef, PermissionService.CANCEL_CHECK_OUT)); - } public void testPermissionWithLockAspect() @@ -212,5 +219,166 @@ public class LockOwnerDynamicAuthorityTest extends TestCase } + public void testCheckOutCheckInAuthorities() + { + permissionService.setPermission(rootNodeRef, "andy", PermissionService.ALL_PERMISSIONS, true); + permissionService.setPermission(rootNodeRef, "lemur", PermissionService.CHECK_OUT, true); + permissionService.setPermission(rootNodeRef, "lemur", PermissionService.WRITE, true); + permissionService.setPermission(rootNodeRef, "lemur", PermissionService.READ, true); + permissionService.setPermission(rootNodeRef, "frog", PermissionService.CHECK_OUT, true); + permissionService.setPermission(rootNodeRef, "frog", PermissionService.WRITE, true); + permissionService.setPermission(rootNodeRef, "frog", PermissionService.READ, true); + + authenticationService.authenticate("andy", "andy".toCharArray()); + NodeRef testNode = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, ContentModel.TYPE_PERSON, + ContentModel.TYPE_CMOBJECT, null).getChildRef(); + permissionService.setPermission(rootNodeRef, "andy", PermissionService.ALL_PERMISSIONS, false); + + + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, + PermissionService.LOCK)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, + PermissionService.UNLOCK)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.CHECK_OUT)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, PermissionService.CHECK_IN)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, PermissionService.CANCEL_CHECK_OUT)); + + authenticationService.authenticate("lemur", "lemur".toCharArray()); + + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, + PermissionService.LOCK)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, + PermissionService.UNLOCK)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.CHECK_OUT)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, PermissionService.CHECK_IN)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, PermissionService.CANCEL_CHECK_OUT)); + + authenticationService.authenticate("frog", "frog".toCharArray()); + + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, + PermissionService.LOCK)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, + PermissionService.UNLOCK)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.CHECK_OUT)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, PermissionService.CHECK_IN)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, PermissionService.CANCEL_CHECK_OUT)); + + // Check out as frog + NodeRef workingCopy = checkOutCheckInService.checkout(testNode); + + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, + PermissionService.LOCK)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, + PermissionService.UNLOCK)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.CHECK_OUT)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.CHECK_IN)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.CANCEL_CHECK_OUT)); + + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(workingCopy, + PermissionService.LOCK)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(workingCopy, + PermissionService.UNLOCK)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(workingCopy, PermissionService.CHECK_OUT)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(workingCopy, PermissionService.CHECK_IN)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(workingCopy, PermissionService.CANCEL_CHECK_OUT)); + + authenticationService.authenticate("lemur", "lemur".toCharArray()); + + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, + PermissionService.LOCK)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, + PermissionService.UNLOCK)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.CHECK_OUT)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, PermissionService.CHECK_IN)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, PermissionService.CANCEL_CHECK_OUT)); + + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(workingCopy, + PermissionService.LOCK)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(workingCopy, + PermissionService.UNLOCK)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(workingCopy, PermissionService.CHECK_OUT)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(workingCopy, PermissionService.CHECK_IN)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(workingCopy, PermissionService.CANCEL_CHECK_OUT)); + + + // set owner ...frog only has permissions of dynamic lock owner in wc and sourec + authenticationService.authenticate("frog", "frog".toCharArray()); + ownableService.setOwner(workingCopy, "lemur"); + + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, + PermissionService.LOCK)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, + PermissionService.UNLOCK)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.CHECK_OUT)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.CHECK_IN)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.CANCEL_CHECK_OUT)); + + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(workingCopy, + PermissionService.LOCK)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(workingCopy, + PermissionService.UNLOCK)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(workingCopy, PermissionService.CHECK_OUT)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(workingCopy, PermissionService.CHECK_IN)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(workingCopy, PermissionService.CANCEL_CHECK_OUT)); + + // test the new owner.. + authenticationService.authenticate("lemur", "lemur".toCharArray()); + + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, + PermissionService.LOCK)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, + PermissionService.UNLOCK)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.CHECK_OUT)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, PermissionService.CHECK_IN)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, PermissionService.CANCEL_CHECK_OUT)); + + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(workingCopy, + PermissionService.LOCK)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(workingCopy, + PermissionService.UNLOCK)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(workingCopy, PermissionService.CHECK_OUT)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(workingCopy, PermissionService.CHECK_IN)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(workingCopy, PermissionService.CANCEL_CHECK_OUT)); + + authenticationService.authenticate("frog", "frog".toCharArray()); + checkOutCheckInService.cancelCheckout(workingCopy); + + authenticationService.authenticate("andy", "andy".toCharArray()); + + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, + PermissionService.LOCK)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, + PermissionService.UNLOCK)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.CHECK_OUT)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, PermissionService.CHECK_IN)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, PermissionService.CANCEL_CHECK_OUT)); + + authenticationService.authenticate("lemur", "lemur".toCharArray()); + + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, + PermissionService.LOCK)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, + PermissionService.UNLOCK)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.CHECK_OUT)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, PermissionService.CHECK_IN)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, PermissionService.CANCEL_CHECK_OUT)); + + authenticationService.authenticate("frog", "frog".toCharArray()); + + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, + PermissionService.LOCK)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, + PermissionService.UNLOCK)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.CHECK_OUT)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, PermissionService.CHECK_IN)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, PermissionService.CANCEL_CHECK_OUT)); + + + authenticationService.authenticate("frog", "frog".toCharArray()); + workingCopy = checkOutCheckInService.checkout(testNode); + ownableService.setOwner(workingCopy, "lemur"); + checkOutCheckInService.checkin(workingCopy, null); + + } }