From 46483f1c5496bdeb9f4e984ff06b3712b66f249c Mon Sep 17 00:00:00 2001 From: Kevin Roast Date: Wed, 17 Dec 2008 14:12:21 +0000 Subject: [PATCH] Merged V3.0 to HEAD 11498: Improvements to DM ACL upgrade 11502: Edit Details button text updated to Edit Site Details to avoid confusion 11503: ETHREEOH-577 - It is possible to create empty comment at document details page 11504: ETHREEOH-576 - Cannot create calendar event with name containing certain characters such as : / 11505: Merged V2.2 to V3.0 11337: Tidy up the deletion of unused ACEs when authorities are deleted - ETWOTWO-749 11339: Fix permission checks under RunAs to use the effective user's groups - ETWOTWO-753 11506: Fixed ETHREEOH-579: RuntimeExec can not handle commands and arguments that contains spaces git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@12448 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../ImageMagickContentTransformerTest.java | 2 +- .../domain/hibernate/AclDaoComponentImpl.java | 22 ++ .../hibernate/DMAccessControlListDAO.java | 26 ++- .../repo/domain/hibernate/Permission.hbm.xml | 11 + .../HibernateNodeDaoServiceImpl.java | 9 + .../impl/PermissionServiceImpl.java | 1 + .../impl/PermissionServiceTest.java | 201 +++++++++++++++++- .../repo/security/person/PersonTest.java | 23 ++ 8 files changed, 285 insertions(+), 10 deletions(-) diff --git a/source/java/org/alfresco/repo/content/transform/magick/ImageMagickContentTransformerTest.java b/source/java/org/alfresco/repo/content/transform/magick/ImageMagickContentTransformerTest.java index d3298aa774..2c256e84e0 100644 --- a/source/java/org/alfresco/repo/content/transform/magick/ImageMagickContentTransformerTest.java +++ b/source/java/org/alfresco/repo/content/transform/magick/ImageMagickContentTransformerTest.java @@ -47,7 +47,7 @@ public class ImageMagickContentTransformerTest extends AbstractContentTransforme super.setUp(); RuntimeExec executer = new RuntimeExec(); - executer.setCommand("imconvert.exe ${source} ${options} ${target}"); + executer.setCommand(new String[] {"imconvert.exe", "${source}", "${options}", "${target}"}); executer.setDefaultProperties(Collections.singletonMap("options", "")); transformer = new ImageMagickContentTransformer(); diff --git a/source/java/org/alfresco/repo/domain/hibernate/AclDaoComponentImpl.java b/source/java/org/alfresco/repo/domain/hibernate/AclDaoComponentImpl.java index f2dd91752b..3baa3a240f 100644 --- a/source/java/org/alfresco/repo/domain/hibernate/AclDaoComponentImpl.java +++ b/source/java/org/alfresco/repo/domain/hibernate/AclDaoComponentImpl.java @@ -93,6 +93,8 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo // static String QUERY_GET_AUTHORITY_ALIASES = "permission.GetAuthorityAliases"; static String QUERY_GET_ACES_AND_ACLS_BY_AUTHORITY = "permission.GetAcesAndAclsByAuthority"; + + static String QUERY_GET_ACES_BY_AUTHORITY = "permission.GetAcesByAuthority"; static String QUERY_GET_ACES_FOR_ACL = "permission.GetAcesForAcl"; @@ -855,6 +857,26 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo getHibernateTemplate().delete(ace); } + + // Tidy up any unreferenced ACEs + + callback = new HibernateCallback() + { + public Object doInHibernate(Session session) + { + Query query = session.getNamedQuery(QUERY_GET_ACES_BY_AUTHORITY); + query.setParameter("authority", authority); + return query.list(); + } + }; + List unreferenced = (List) getHibernateTemplate().execute(callback); + + for (DbAccessControlEntry ace : unreferenced) + { + getHibernateTemplate().delete(ace); + } + + // remove authority callback = new HibernateCallback() diff --git a/source/java/org/alfresco/repo/domain/hibernate/DMAccessControlListDAO.java b/source/java/org/alfresco/repo/domain/hibernate/DMAccessControlListDAO.java index 8ebc99dcb3..3cf8bef009 100644 --- a/source/java/org/alfresco/repo/domain/hibernate/DMAccessControlListDAO.java +++ b/source/java/org/alfresco/repo/domain/hibernate/DMAccessControlListDAO.java @@ -206,7 +206,8 @@ public class DMAccessControlListDAO implements AccessControlListDAO // Do the children first DbAccessControlList existingAcl = getAccessControlList(nodeRef); - Long toInherit = inherited; + Long toInherit = null; + Long idToInheritFrom = null; if (existingAcl != null) { @@ -229,13 +230,13 @@ public class DMAccessControlListDAO implements AccessControlListDAO } if (existingAcl.getInherits()) { - if (toInherit != null) + if (inherited != null) { - aclDaoComponent.enableInheritance(id, toInherit); + aclDaoComponent.enableInheritance(id, inherited); } } - toInherit = aclDaoComponent.getInheritedAccessControlList(id); + idToInheritFrom = id; setAccessControlList(nodeRef, newAcl); } @@ -256,20 +257,33 @@ public class DMAccessControlListDAO implements AccessControlListDAO DbAccessControlList newAcl = aclDaoComponent.getDbAccessControlList(id); - toInherit = aclDaoComponent.getInheritedAccessControlList(id); + idToInheritFrom = id; setAccessControlList(nodeRef, newAcl); } else { // Unset - simple inherit - DbAccessControlList inheritedAcl = aclDaoComponent.getDbAccessControlList(toInherit); + DbAccessControlList inheritedAcl = aclDaoComponent.getDbAccessControlList(inherited); setAccessControlList(nodeRef, inheritedAcl); } } for (ChildAssociationRef child : nodeService.getChildAssocs(nodeRef)) { + // Only make inherited if required + if(toInherit == null) + { + if(idToInheritFrom == null) + { + toInherit = inherited; + } + else + { + toInherit = aclDaoComponent.getInheritedAccessControlList(idToInheritFrom); + } + } + if (child.isPrimary()) { CounterSet update = fixOldDmAcls(child.getChildRef(), toInherit, false); diff --git a/source/java/org/alfresco/repo/domain/hibernate/Permission.hbm.xml b/source/java/org/alfresco/repo/domain/hibernate/Permission.hbm.xml index 2f6405d52f..aa362af817 100644 --- a/source/java/org/alfresco/repo/domain/hibernate/Permission.hbm.xml +++ b/source/java/org/alfresco/repo/domain/hibernate/Permission.hbm.xml @@ -336,7 +336,18 @@ authority.authority = :authority + + select + ace + from + org.alfresco.repo.domain.hibernate.DbAccessControlEntryImpl as ace + join ace.authority as authority + where + authority.authority = :authority + + + select aclmem diff --git a/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java b/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java index 385af5e13c..da6590a8e7 100644 --- a/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java +++ b/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java @@ -1440,6 +1440,15 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements node.getProperties().clear(); node.getAspects().clear(); + // delete ACLs + + DbAccessControlList dbAcl = node.getAccessControlList(); + node.setAccessControlList(null); + if(dbAcl != null) + { + getHibernateTemplate().delete(dbAcl); + } + // Mark the node as deleted node.setDeleted(true); diff --git a/source/java/org/alfresco/repo/security/permissions/impl/PermissionServiceImpl.java b/source/java/org/alfresco/repo/security/permissions/impl/PermissionServiceImpl.java index ddf62b27ff..997aef995f 100644 --- a/source/java/org/alfresco/repo/security/permissions/impl/PermissionServiceImpl.java +++ b/source/java/org/alfresco/repo/security/permissions/impl/PermissionServiceImpl.java @@ -790,6 +790,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing } } } + auths.addAll(authorityService.getAuthoritiesForUser(user.getUsername())); return auths; } diff --git a/source/java/org/alfresco/repo/security/permissions/impl/PermissionServiceTest.java b/source/java/org/alfresco/repo/security/permissions/impl/PermissionServiceTest.java index bec40b5f24..6e4d8ba975 100644 --- a/source/java/org/alfresco/repo/security/permissions/impl/PermissionServiceTest.java +++ b/source/java/org/alfresco/repo/security/permissions/impl/PermissionServiceTest.java @@ -156,15 +156,15 @@ public class PermissionServiceTest extends AbstractPermissionTest { } - + runAs("admin"); permissionService.setPermission(folder, "andy", PermissionService.ALL_PERMISSIONS, true); - + FileFolderServiceImpl.makeFolders(serviceRegistry.getFileFolderService(), folder, pathElements, ContentModel.TYPE_FOLDER); } - public void testRunAsRealAndEffectiveUsers() + public void testRunAsRealAndEffectiveUsersWithPriorAuthentication() { runAs("admin"); @@ -197,6 +197,201 @@ public class PermissionServiceTest extends AbstractPermissionTest } + public void testNestedRunAsRealAndEffectiveUsersWithPriorAuthentication() + { + runAs("admin"); + + final NodeRef n1 = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}one"), ContentModel.TYPE_FOLDER).getChildRef(); + + runAs("andy"); + assertTrue(permissionService.hasPermission(n1, getPermission(PermissionService.CONTRIBUTOR)) == AccessStatus.DENIED); + + assertEquals("andy", AuthenticationUtil.getCurrentRealUserName()); + assertEquals("andy", AuthenticationUtil.getCurrentEffectiveUserName()); + + AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() + { + + public Object doWork() throws Exception + { + assertTrue(permissionService.hasPermission(n1, getPermission(PermissionService.CONTRIBUTOR)) == AccessStatus.ALLOWED); + + assertEquals("andy", AuthenticationUtil.getCurrentRealUserName()); + assertEquals("admin", AuthenticationUtil.getCurrentEffectiveUserName()); + + AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() + { + + public Object doWork() throws Exception + { + assertTrue(permissionService.hasPermission(n1, getPermission(PermissionService.CONTRIBUTOR)) == AccessStatus.DENIED); + + assertEquals("andy", AuthenticationUtil.getCurrentRealUserName()); + assertEquals("lemur", AuthenticationUtil.getCurrentEffectiveUserName()); + + AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() + { + + public Object doWork() throws Exception + { + assertTrue(permissionService.hasPermission(n1, getPermission(PermissionService.CONTRIBUTOR)) == AccessStatus.ALLOWED); + + assertEquals("andy", AuthenticationUtil.getCurrentRealUserName()); + assertEquals("admin", AuthenticationUtil.getCurrentEffectiveUserName()); + + AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() + { + + public Object doWork() throws Exception + { + assertTrue(permissionService.hasPermission(n1, getPermission(PermissionService.CONTRIBUTOR)) == AccessStatus.DENIED); + + assertEquals("andy", AuthenticationUtil.getCurrentRealUserName()); + assertEquals("andy", AuthenticationUtil.getCurrentEffectiveUserName()); + + return null; + } + }, "andy"); + + + assertEquals("andy", AuthenticationUtil.getCurrentRealUserName()); + assertEquals("admin", AuthenticationUtil.getCurrentEffectiveUserName()); + + return null; + } + }, "admin"); + + assertEquals("andy", AuthenticationUtil.getCurrentRealUserName()); + assertEquals("lemur", AuthenticationUtil.getCurrentEffectiveUserName()); + + return null; + } + }, "lemur"); + + assertEquals("andy", AuthenticationUtil.getCurrentRealUserName()); + assertEquals("admin", AuthenticationUtil.getCurrentEffectiveUserName()); + + return null; + } + }, "admin"); + + assertEquals("andy", AuthenticationUtil.getCurrentRealUserName()); + assertEquals("andy", AuthenticationUtil.getCurrentEffectiveUserName()); + + } + + public void testRunAsRealAndEffectiveUsersWithNoPriorAuthentication() + { + runAs("admin"); + + final NodeRef n1 = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}one"), ContentModel.TYPE_FOLDER).getChildRef(); + + AuthenticationUtil.clearCurrentSecurityContext(); + + assertNull(AuthenticationUtil.getCurrentRealUserName()); + assertNull(AuthenticationUtil.getCurrentEffectiveUserName()); + + AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() + { + + public Object doWork() throws Exception + { + assertTrue(permissionService.hasPermission(n1, getPermission(PermissionService.CONTRIBUTOR)) == AccessStatus.ALLOWED); + + assertEquals("admin", AuthenticationUtil.getCurrentRealUserName()); + assertEquals("admin", AuthenticationUtil.getCurrentEffectiveUserName()); + return null; + } + }, "admin"); + + assertNull(AuthenticationUtil.getCurrentRealUserName()); + assertNull(AuthenticationUtil.getCurrentEffectiveUserName()); + } + + + public void testNestedRunAsRealAndEffectiveUsersWithNoPriorAuthentication() + { + runAs("admin"); + + final NodeRef n1 = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}one"), ContentModel.TYPE_FOLDER).getChildRef(); + + AuthenticationUtil.clearCurrentSecurityContext(); + + assertNull(AuthenticationUtil.getCurrentRealUserName()); + assertNull(AuthenticationUtil.getCurrentEffectiveUserName()); + + AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() + { + + public Object doWork() throws Exception + { + assertTrue(permissionService.hasPermission(n1, getPermission(PermissionService.CONTRIBUTOR)) == AccessStatus.ALLOWED); + + assertEquals("admin", AuthenticationUtil.getCurrentRealUserName()); + assertEquals("admin", AuthenticationUtil.getCurrentEffectiveUserName()); + + AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() + { + + public Object doWork() throws Exception + { + assertTrue(permissionService.hasPermission(n1, getPermission(PermissionService.CONTRIBUTOR)) == AccessStatus.DENIED); + + assertEquals("admin", AuthenticationUtil.getCurrentRealUserName()); + assertEquals("lemur", AuthenticationUtil.getCurrentEffectiveUserName()); + + AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() + { + + public Object doWork() throws Exception + { + assertTrue(permissionService.hasPermission(n1, getPermission(PermissionService.CONTRIBUTOR)) == AccessStatus.ALLOWED); + + assertEquals("admin", AuthenticationUtil.getCurrentRealUserName()); + assertEquals("admin", AuthenticationUtil.getCurrentEffectiveUserName()); + + AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() + { + + public Object doWork() throws Exception + { + assertTrue(permissionService.hasPermission(n1, getPermission(PermissionService.CONTRIBUTOR)) == AccessStatus.DENIED); + + assertEquals("admin", AuthenticationUtil.getCurrentRealUserName()); + assertEquals("andy", AuthenticationUtil.getCurrentEffectiveUserName()); + + return null; + } + }, "andy"); + + + assertEquals("admin", AuthenticationUtil.getCurrentRealUserName()); + assertEquals("admin", AuthenticationUtil.getCurrentEffectiveUserName()); + + return null; + } + }, "admin"); + + assertEquals("admin", AuthenticationUtil.getCurrentRealUserName()); + assertEquals("lemur", AuthenticationUtil.getCurrentEffectiveUserName()); + + return null; + } + }, "lemur"); + + assertEquals("admin", AuthenticationUtil.getCurrentRealUserName()); + assertEquals("admin", AuthenticationUtil.getCurrentEffectiveUserName()); + + return null; + } + }, "admin"); + + assertNull(AuthenticationUtil.getCurrentRealUserName()); + assertNull(AuthenticationUtil.getCurrentEffectiveUserName()); + + + } + public void testDefaultModelPermissions() { runAs("admin"); diff --git a/source/java/org/alfresco/repo/security/person/PersonTest.java b/source/java/org/alfresco/repo/security/person/PersonTest.java index 21b3255eda..a8c49b6f36 100644 --- a/source/java/org/alfresco/repo/security/person/PersonTest.java +++ b/source/java/org/alfresco/repo/security/person/PersonTest.java @@ -37,6 +37,7 @@ import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; import org.alfresco.service.cmr.security.NoSuchPersonException; +import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.namespace.QName; import org.alfresco.service.transaction.TransactionService; @@ -54,6 +55,8 @@ public class PersonTest extends BaseSpringTest private NodeRef rootNodeRef; + private PermissionService permissionService; + public PersonTest() { super(); @@ -65,6 +68,7 @@ public class PersonTest extends BaseSpringTest transactionService = (TransactionService) applicationContext.getBean("transactionService"); personService = (PersonService) applicationContext.getBean("personService"); nodeService = (NodeService) applicationContext.getBean("nodeService"); + permissionService = (PermissionService) applicationContext.getBean("permissionService"); StoreRef storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.currentTimeMillis()); rootNodeRef = nodeService.getRootNode(storeRef); @@ -119,6 +123,25 @@ public class PersonTest extends BaseSpringTest } } + public void testDeletePerson() + { + personService.getPerson("andy"); + NodeRef n1 = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}one"), ContentModel.TYPE_FOLDER).getChildRef(); + NodeRef n2 = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}two"), ContentModel.TYPE_FOLDER).getChildRef(); + permissionService.setPermission(n1, "andy", PermissionService.READ, true); + permissionService.setPermission(n2, "andy", PermissionService.ALL_PERMISSIONS, true); + setComplete(); + endTransaction(); + startNewTransaction(); + nodeService.deleteNode(n1); + setComplete(); + endTransaction(); + startNewTransaction(); + personService.deletePerson("andy"); + setComplete(); + endTransaction(); + startNewTransaction(); + } public void testCreateAndThenDelete() {