From 918e91fcfc981a561134b0b0366f46d56c937ac7 Mon Sep 17 00:00:00 2001 From: Kevin Roast Date: Wed, 17 Dec 2008 14:24:08 +0000 Subject: [PATCH] Merged V3.0 to HEAD 11509: ETHREEOH-394: Incorrect message in activity feed when user accepts an invitation to a site 11510: Fix to set position 11511: Fix for ETHREEOH-533: Dialogs access via ExternalAccessServlet return to blank empty container.jsp page when Close button is clicked 11512: Fix DM ACL deletion after merge forward for shared and defining ACLs. 11513: Merged V2.2 to V3.0 11501: Expose if set permissions are inherited or not and fix relatd behaviour for import/copy 11514: Fix for ETHREEOH-476 (Impossible to create Site Invite Workflow) & ETHREEOH-254 (Default value at 'Start Advanced Workflow Wizard' page) 11515: Fix for ETHREEOH-446 and ETHREEOH-447 11517: Fix for ETHREEOH-225: Web Forms with repeating elements don't work 11518: Merged V2.2 to V3.0 11343: ACL upgrades may require a COW - it now warns when this happens. 11369: Always lock against staging - ETWOTWO-763 11519: Merged V2.2 to V3.0 11467: Fixed ETWOTWO-774: CreateVersionTxnListener.afterCommit() throws NPE 11468: More defensive coding on AVM txn listeners (avoid NPEs) 11475: More defensive checks to avoid NPE 11520: Merged V2.2 to V3.0 11478: Keep creator and owner as orihinally set in AVM - Fix for ETWOTWO-604 11521: RuntimeExec: Added optional directive SPLIT: to force argument tokenization 11522: Limited tests to just check the command format not execute it for "dir . .." 11523: Undid revision 11520 (Merged V2.2 11478) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@12449 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/content-services-context.xml | 12 +- .../repo/avm/AVMLockingAwareService.java | 8 +- .../repo/avm/CreateStoreTxnListener.java | 13 +- .../repo/avm/CreateVersionTxnListener.java | 13 +- .../repo/avm/PurgeStoreTxnListener.java | 13 +- .../repo/avm/PurgeVersionTxnListener.java | 13 +- .../alfresco/repo/copy/CopyServiceImpl.java | 5 +- .../hibernate/AVMAccessControlListDAO.java | 4 +- .../repo/exporter/ExporterComponent.java | 5 +- .../repo/importer/view/NodeContext.java | 16 ++ .../HibernateNodeDaoServiceImpl.java | 33 ++- .../impl/AccessPermissionImpl.java | 20 +- .../impl/PermissionServiceImpl.java | 12 +- .../impl/PermissionServiceTest.java | 243 ++++++++++++++---- .../impl/SimplePermissionEntry.java | 1 + .../cmr/security/AccessPermission.java | 22 ++ 16 files changed, 340 insertions(+), 93 deletions(-) diff --git a/config/alfresco/content-services-context.xml b/config/alfresco/content-services-context.xml index f1ff67f080..8395ac44d9 100644 --- a/config/alfresco/content-services-context.xml +++ b/config/alfresco/content-services-context.xml @@ -356,13 +356,15 @@ init-method="init"> - + - - imconvert "${source}" ${options} "${target}" - - convert ${source} ${options} ${target} + + imconvert + ${source} + SPLIT:${options} + ${target} + diff --git a/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java b/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java index b78bb26103..4d1ea5d57e 100644 --- a/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java +++ b/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java @@ -60,6 +60,8 @@ import org.springframework.context.ApplicationContextAware; */ public class AVMLockingAwareService implements AVMService, ApplicationContextAware { + public static final String STORE_SEPARATOR = "--"; + private AVMService fService; private AVMLockingService fLockingService; @@ -856,7 +858,11 @@ public class AVMLockingAwareService implements AVMService, ApplicationContextAwa return null; } String dnsString = results.keySet().iterator().next().getLocalName(); - return dnsString.substring(dnsString.lastIndexOf('.') + 1, dnsString.length()); + String storeName = dnsString.substring(dnsString.lastIndexOf('.') + 1, dnsString.length()); + final int index = storeName.indexOf(STORE_SEPARATOR); + return (index == -1 + ? storeName + : storeName.substring(0, index)); } private void grabLock(String path) diff --git a/source/java/org/alfresco/repo/avm/CreateStoreTxnListener.java b/source/java/org/alfresco/repo/avm/CreateStoreTxnListener.java index a11d060fdb..b3e882b53c 100644 --- a/source/java/org/alfresco/repo/avm/CreateStoreTxnListener.java +++ b/source/java/org/alfresco/repo/avm/CreateStoreTxnListener.java @@ -40,17 +40,20 @@ public class CreateStoreTxnListener extends TransactionListenerAdapter public void afterCommit() { List created = fCreatedStores.get(); - for (String name : created) + if (created != null) { - synchronized (this) + for (String name : created) { - for (CreateStoreCallback cb : fCallbacks) + synchronized (this) { - cb.storeCreated(name); + for (CreateStoreCallback cb : fCallbacks) + { + cb.storeCreated(name); + } } } + fCreatedStores.set(null); } - fCreatedStores.set(null); } /* (non-Javadoc) diff --git a/source/java/org/alfresco/repo/avm/CreateVersionTxnListener.java b/source/java/org/alfresco/repo/avm/CreateVersionTxnListener.java index 9841d78e77..4247000e46 100644 --- a/source/java/org/alfresco/repo/avm/CreateVersionTxnListener.java +++ b/source/java/org/alfresco/repo/avm/CreateVersionTxnListener.java @@ -41,17 +41,20 @@ public class CreateVersionTxnListener extends TransactionListenerAdapter public void afterCommit() { List> created = fCreatedVersions.get(); - for (Pair version : created) + if (created != null) { - synchronized (this) + for (Pair version : created) { - for (CreateVersionCallback cb : fCallbacks) + synchronized (this) { - cb.versionCreated(version.getFirst(), version.getSecond()); + for (CreateVersionCallback cb : fCallbacks) + { + cb.versionCreated(version.getFirst(), version.getSecond()); + } } } + fCreatedVersions.set(null); } - fCreatedVersions.set(null); } /* (non-Javadoc) diff --git a/source/java/org/alfresco/repo/avm/PurgeStoreTxnListener.java b/source/java/org/alfresco/repo/avm/PurgeStoreTxnListener.java index 1a657e2ffe..5d95c80fd4 100644 --- a/source/java/org/alfresco/repo/avm/PurgeStoreTxnListener.java +++ b/source/java/org/alfresco/repo/avm/PurgeStoreTxnListener.java @@ -40,17 +40,20 @@ public class PurgeStoreTxnListener extends TransactionListenerAdapter public void afterCommit() { List created = fPurgedStores.get(); - for (String name : created) + if (created != null) { - synchronized (this) + for (String name : created) { - for (PurgeStoreCallback cb : fCallbacks) + synchronized (this) { - cb.storePurged(name); + for (PurgeStoreCallback cb : fCallbacks) + { + cb.storePurged(name); + } } } + fPurgedStores.set(null); } - fPurgedStores.set(null); } /* (non-Javadoc) diff --git a/source/java/org/alfresco/repo/avm/PurgeVersionTxnListener.java b/source/java/org/alfresco/repo/avm/PurgeVersionTxnListener.java index 2bf2c30db0..44ec282aaf 100644 --- a/source/java/org/alfresco/repo/avm/PurgeVersionTxnListener.java +++ b/source/java/org/alfresco/repo/avm/PurgeVersionTxnListener.java @@ -41,17 +41,20 @@ public class PurgeVersionTxnListener extends TransactionListenerAdapter public void afterCommit() { List> created = fPurgedVersions.get(); - for (Pair version : created) + if (created != null) { - synchronized (this) + for (Pair version : created) { - for (PurgeVersionCallback cb : fCallbacks) + synchronized (this) { - cb.versionPurged(version.getFirst(), version.getSecond()); + for (PurgeVersionCallback cb : fCallbacks) + { + cb.versionPurged(version.getFirst(), version.getSecond()); + } } } + fPurgedVersions.set(null); } - fPurgedVersions.set(null); } /* (non-Javadoc) diff --git a/source/java/org/alfresco/repo/copy/CopyServiceImpl.java b/source/java/org/alfresco/repo/copy/CopyServiceImpl.java index 0fe1eb9e3b..b5ed947820 100644 --- a/source/java/org/alfresco/repo/copy/CopyServiceImpl.java +++ b/source/java/org/alfresco/repo/copy/CopyServiceImpl.java @@ -540,11 +540,14 @@ public class CopyServiceImpl implements CopyService // Set the permission values on the destination node for (AccessPermission permission : permissions) { - this.permissionService.setPermission( + if(permission.isSetDirectly()) + { + this.permissionService.setPermission( destinationNodeRef, permission.getAuthority(), permission.getPermission(), permission.getAccessStatus().equals(AccessStatus.ALLOWED)); + } } this.permissionService.setInheritParentPermissions(destinationNodeRef, includeInherited); } diff --git a/source/java/org/alfresco/repo/domain/hibernate/AVMAccessControlListDAO.java b/source/java/org/alfresco/repo/domain/hibernate/AVMAccessControlListDAO.java index e72a8a5e47..a10f0cc965 100644 --- a/source/java/org/alfresco/repo/domain/hibernate/AVMAccessControlListDAO.java +++ b/source/java/org/alfresco/repo/domain/hibernate/AVMAccessControlListDAO.java @@ -864,7 +864,7 @@ public class AVMAccessControlListDAO implements AccessControlListDAO { if (!change.getBefore().equals(change.getAfter())) { - throw new IllegalStateException("ACL fix should not change the acl ids - unexpected COW!"); + s_logger.warn("ACL fix should not change the acl ids - unexpected COW!"); } } @@ -910,7 +910,7 @@ public class AVMAccessControlListDAO implements AccessControlListDAO { if (!change.getBefore().equals(change.getAfter())) { - throw new IllegalStateException("ACL fix should not change the acl ids - unexpected COW!"); + s_logger.warn("ACL fix should not change the acl ids - unexpected COW!"); } } diff --git a/source/java/org/alfresco/repo/exporter/ExporterComponent.java b/source/java/org/alfresco/repo/exporter/ExporterComponent.java index 4f7c9433ca..d215a2a731 100644 --- a/source/java/org/alfresco/repo/exporter/ExporterComponent.java +++ b/source/java/org/alfresco/repo/exporter/ExporterComponent.java @@ -414,7 +414,10 @@ public class ExporterComponent exporter.startACL(nodeRef); for (AccessPermission permission : permissions) { - exporter.permission(nodeRef, permission); + if(permission.isSetDirectly()) + { + exporter.permission(nodeRef, permission); + } } exporter.endACL(nodeRef); } diff --git a/source/java/org/alfresco/repo/importer/view/NodeContext.java b/source/java/org/alfresco/repo/importer/view/NodeContext.java index 600fa9d3de..39457916ce 100644 --- a/source/java/org/alfresco/repo/importer/view/NodeContext.java +++ b/source/java/org/alfresco/repo/importer/view/NodeContext.java @@ -507,6 +507,7 @@ public class NodeContext extends ElementContext private AccessStatus accessStatus; private String authority; private String permission; + private int position; /* * (non-Javadoc) @@ -543,6 +544,21 @@ public class NodeContext extends ElementContext { return null; } + + public int getPosition() + { + return 0; + } + + public boolean isInherited() + { + return false; + } + + public boolean isSetDirectly() + { + return true; + } } } 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 da6590a8e7..93dbccc5b0 100644 --- a/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java +++ b/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java @@ -106,10 +106,14 @@ import org.alfresco.util.GUID; import org.alfresco.util.Pair; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.hibernate.Criteria; import org.hibernate.Query; import org.hibernate.ScrollMode; import org.hibernate.ScrollableResults; import org.hibernate.Session; +import org.hibernate.criterion.Criterion; +import org.hibernate.criterion.Projections; +import org.hibernate.criterion.Restrictions; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.orm.hibernate3.HibernateCallback; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; @@ -1446,7 +1450,34 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements node.setAccessControlList(null); if(dbAcl != null) { - getHibernateTemplate().delete(dbAcl); + if(dbAcl.getAclType() == ACLType.DEFINING) + { + getHibernateTemplate().delete(dbAcl); + } + if(dbAcl.getAclType() == ACLType.SHARED) + { + // check unused + Long defining = dbAcl.getInheritsFrom(); + if(getHibernateTemplate().get(DbAccessControlListImpl.class, defining) == null) + { + final Long id = dbAcl.getId(); + HibernateCallback check = new HibernateCallback() + { + public Object doInHibernate(Session session) + { + Criteria criteria = getSession().createCriteria(NodeImpl.class, "n"); + criteria.add(Restrictions.eq("n.accessControlList.id", id)); + criteria.setProjection(Projections.rowCount()); + return criteria.list(); + } + }; + List list = (List)getHibernateTemplate().execute(check); + if(list.get(0).intValue() == 0) + { + getHibernateTemplate().delete(dbAcl); + } + } + } } // Mark the node as deleted diff --git a/source/java/org/alfresco/repo/security/permissions/impl/AccessPermissionImpl.java b/source/java/org/alfresco/repo/security/permissions/impl/AccessPermissionImpl.java index 5a80636125..56b3d8fc59 100644 --- a/source/java/org/alfresco/repo/security/permissions/impl/AccessPermissionImpl.java +++ b/source/java/org/alfresco/repo/security/permissions/impl/AccessPermissionImpl.java @@ -42,13 +42,16 @@ public class AccessPermissionImpl implements AccessPermission private String authority; private AuthorityType authorityType; + + private int position; - public AccessPermissionImpl(String permission, AccessStatus accessStatus, String authority) + public AccessPermissionImpl(String permission, AccessStatus accessStatus, String authority, int position) { this.permission = permission; this.accessStatus = accessStatus; this.authority = authority; this.authorityType = AuthorityType.getAuthorityType(authority); + this.position = position; } public String getPermission() @@ -99,4 +102,19 @@ public class AccessPermissionImpl implements AccessPermission { return ((authority.hashCode() * 37) + permission.hashCode()) * 37 + accessStatus.hashCode(); } + + public int getPosition() + { + return position; + } + + public boolean isInherited() + { + return (position > 0); + } + + public boolean isSetDirectly() + { + return (position == 0); + } } \ No newline at end of file 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 997aef995f..c74a0fb42d 100644 --- a/source/java/org/alfresco/repo/security/permissions/impl/PermissionServiceImpl.java +++ b/source/java/org/alfresco/repo/security/permissions/impl/PermissionServiceImpl.java @@ -342,7 +342,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing NodePermissionEntry nodePremissionEntry = getSetPermissions(nodeRef); for (PermissionEntry pe : nodePremissionEntry.getPermissionEntries()) { - accessPermissions.add(new AccessPermissionImpl(getPermission(pe.getPermissionReference()), pe.getAccessStatus(), pe.getAuthority())); + accessPermissions.add(new AccessPermissionImpl(getPermission(pe.getPermissionReference()), pe.getAccessStatus(), pe.getAuthority(), pe.getPosition())); } return accessPermissions; } @@ -353,7 +353,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing NodePermissionEntry nodePremissionEntry = getSetPermissions(storeRef); for (PermissionEntry pe : nodePremissionEntry.getPermissionEntries()) { - accessPermissions.add(new AccessPermissionImpl(getPermission(pe.getPermissionReference()), pe.getAccessStatus(), pe.getAuthority())); + accessPermissions.add(new AccessPermissionImpl(getPermission(pe.getPermissionReference()), pe.getAccessStatus(), pe.getAuthority(), pe.getPosition())); } return accessPermissions; } @@ -366,13 +366,13 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing { if (hasPermission(nodeRef, pr) == AccessStatus.ALLOWED) { - accessPermissions.add(new AccessPermissionImpl(getPermission(pr), AccessStatus.ALLOWED, userName)); + accessPermissions.add(new AccessPermissionImpl(getPermission(pr), AccessStatus.ALLOWED, userName, -1)); } else { if (includeFalse) { - accessPermissions.add(new AccessPermissionImpl(getPermission(pr), AccessStatus.DENIED, userName)); + accessPermissions.add(new AccessPermissionImpl(getPermission(pr), AccessStatus.DENIED, userName, -1)); } } } @@ -757,7 +757,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing auths.add(authority.getAuthority()); } auths.addAll(getDynamicAuthorities(auth, nodeRef, required)); - auths.addAll(authorityService.getAuthorities()); + auths.addAll(authorityService.getAuthoritiesForUser(username)); return auths; } @@ -809,7 +809,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing { auths.add(authority.getAuthority()); } - auths.addAll(authorityService.getAuthorities()); + auths.addAll(authorityService.getAuthoritiesForUser(user.getUsername())); if (context != null) { 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 6e4d8ba975..4c2486df4a 100644 --- a/source/java/org/alfresco/repo/security/permissions/impl/PermissionServiceTest.java +++ b/source/java/org/alfresco/repo/security/permissions/impl/PermissionServiceTest.java @@ -104,41 +104,126 @@ public class PermissionServiceTest extends AbstractPermissionTest assertEquals(0, permissionService.getAllSetPermissions(n1).size()); assertEquals(0, permissionService.getAllSetPermissions(n2).size()); - + permissionService.deletePermissions(n1); permissionService.deletePermissions(n2); - + permissionService.setPermission(new SimplePermissionEntry(n1, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED)); - + assertEquals(1, permissionService.getAllSetPermissions(n1).size()); assertEquals(1, permissionService.getAllSetPermissions(n2).size()); - + permissionService.deletePermissions(n2); - + assertEquals(1, permissionService.getAllSetPermissions(n1).size()); assertEquals(1, permissionService.getAllSetPermissions(n2).size()); - + permissionService.setPermission(new SimplePermissionEntry(n2, getPermission(PermissionService.WRITE), "andy", AccessStatus.ALLOWED)); - + assertEquals(1, permissionService.getAllSetPermissions(n1).size()); assertEquals(2, permissionService.getAllSetPermissions(n2).size()); permissionService.deletePermissions(n2); - + assertEquals(1, permissionService.getAllSetPermissions(n1).size()); assertEquals(1, permissionService.getAllSetPermissions(n2).size()); - + permissionService.setPermission(new SimplePermissionEntry(n2, getPermission(PermissionService.WRITE), "andy", AccessStatus.ALLOWED)); - + assertEquals(1, permissionService.getAllSetPermissions(n1).size()); assertEquals(2, permissionService.getAllSetPermissions(n2).size()); - + permissionService.deletePermissions(n1); - + assertEquals(0, permissionService.getAllSetPermissions(n1).size()); assertEquals(1, permissionService.getAllSetPermissions(n2).size()); } - + + /** + * This will break when merged forward + */ + public void testPositionInformation() + { + runAs("admin"); + NodeRef one = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}one"), ContentModel.TYPE_FOLDER).getChildRef(); + NodeRef two = nodeService.createNode(one, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}two"), ContentModel.TYPE_FOLDER).getChildRef(); + NodeRef three = nodeService.createNode(two, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}three"), ContentModel.TYPE_FOLDER).getChildRef(); + NodeRef four = nodeService.createNode(three, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}three"), ContentModel.TYPE_FOLDER).getChildRef(); + permissionService.setPermission(one, "andy", PermissionService.ALL_PERMISSIONS, true); + permissionService.setPermission(two, "bob", PermissionService.ALL_PERMISSIONS, true); + permissionService.setPermission(three, "carol", PermissionService.ALL_PERMISSIONS, true); + + Set set = permissionService.getAllSetPermissions(one); + assertEquals(1, set.size()); + for (AccessPermission ap : set) + { + if (ap.getAuthority().equals("andy")) + { + assertFalse(ap.isInherited()); + assertEquals(0, ap.getPosition()); + } + } + + set = permissionService.getAllSetPermissions(two); + assertEquals(2, set.size()); + for (AccessPermission ap : set) + { + if (ap.getAuthority().equals("andy")) + { + assertTrue(ap.isInherited()); + assertEquals(2, ap.getPosition()); + } + if (ap.getAuthority().equals("bob")) + { + assertFalse(ap.isInherited()); + assertEquals(0, ap.getPosition()); + } + } + + set = permissionService.getAllSetPermissions(three); + assertEquals(3, set.size()); + for (AccessPermission ap : set) + { + if (ap.getAuthority().equals("andy")) + { + assertTrue(ap.isInherited()); + assertEquals(4, ap.getPosition()); + } + if (ap.getAuthority().equals("bob")) + { + assertTrue(ap.isInherited()); + assertEquals(2, ap.getPosition()); + } + if (ap.getAuthority().equals("carol")) + { + assertFalse(ap.isInherited()); + assertEquals(0, ap.getPosition()); + } + } + + set = permissionService.getAllSetPermissions(four); + assertEquals(3, set.size()); + for (AccessPermission ap : set) + { + if (ap.getAuthority().equals("andy")) + { + assertTrue(ap.isInherited()); + assertEquals(5, ap.getPosition()); + } + if (ap.getAuthority().equals("bob")) + { + assertTrue(ap.isInherited()); + assertEquals(3, ap.getPosition()); + } + if (ap.getAuthority().equals("carol")) + { + assertTrue(ap.isInherited()); + assertEquals(1, ap.getPosition()); + } + } + + } + public void test_AR_2055() { runAs("admin"); @@ -183,11 +268,63 @@ public class PermissionServiceTest extends AbstractPermissionTest { assertEquals("andy", AuthenticationUtil.getCurrentRealUserName()); assertEquals("admin", AuthenticationUtil.getCurrentEffectiveUserName()); - + 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"); @@ -238,29 +375,28 @@ public class PermissionServiceTest extends AbstractPermissionTest 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); + public Object doWork() throws Exception + { + assertTrue(permissionService.hasPermission(n1, getPermission(PermissionService.CONTRIBUTOR)) == AccessStatus.DENIED); - assertEquals("andy", AuthenticationUtil.getCurrentRealUserName()); - assertEquals("andy", AuthenticationUtil.getCurrentEffectiveUserName()); + assertEquals("andy", AuthenticationUtil.getCurrentRealUserName()); + assertEquals("andy", AuthenticationUtil.getCurrentEffectiveUserName()); - return null; - } - }, "andy"); - + return null; + } + }, "andy"); assertEquals("andy", AuthenticationUtil.getCurrentRealUserName()); assertEquals("admin", AuthenticationUtil.getCurrentEffectiveUserName()); - + return null; } }, "admin"); - + assertEquals("andy", AuthenticationUtil.getCurrentRealUserName()); assertEquals("lemur", AuthenticationUtil.getCurrentEffectiveUserName()); @@ -308,7 +444,6 @@ public class PermissionServiceTest extends AbstractPermissionTest assertNull(AuthenticationUtil.getCurrentEffectiveUserName()); } - public void testNestedRunAsRealAndEffectiveUsersWithNoPriorAuthentication() { runAs("admin"); @@ -349,29 +484,28 @@ public class PermissionServiceTest extends AbstractPermissionTest 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); + public Object doWork() throws Exception + { + assertTrue(permissionService.hasPermission(n1, getPermission(PermissionService.CONTRIBUTOR)) == AccessStatus.DENIED); - assertEquals("admin", AuthenticationUtil.getCurrentRealUserName()); - assertEquals("andy", AuthenticationUtil.getCurrentEffectiveUserName()); + assertEquals("admin", AuthenticationUtil.getCurrentRealUserName()); + assertEquals("andy", AuthenticationUtil.getCurrentEffectiveUserName()); - return null; - } - }, "andy"); - + return null; + } + }, "andy"); assertEquals("admin", AuthenticationUtil.getCurrentRealUserName()); assertEquals("admin", AuthenticationUtil.getCurrentEffectiveUserName()); - + return null; } }, "admin"); - + assertEquals("admin", AuthenticationUtil.getCurrentRealUserName()); assertEquals("lemur", AuthenticationUtil.getCurrentEffectiveUserName()); @@ -389,9 +523,8 @@ public class PermissionServiceTest extends AbstractPermissionTest assertNull(AuthenticationUtil.getCurrentRealUserName()); assertNull(AuthenticationUtil.getCurrentEffectiveUserName()); - } - + public void testDefaultModelPermissions() { runAs("admin"); @@ -565,21 +698,21 @@ public class PermissionServiceTest extends AbstractPermissionTest private void printPermissions(NodeRef nodeRef, String path) { Long id = nodeDaoService.getNodePair(nodeRef).getFirst(); - System.out.println(path + " has "+id); - for(AccessControlEntry entry : aclDaoComponent.getAccessControlList(id).getEntries()) + System.out.println(path + " has " + id); + for (AccessControlEntry entry : aclDaoComponent.getAccessControlList(id).getEntries()) { - System.out.println("\t\t "+id+" "+entry); + System.out.println("\t\t " + id + " " + entry); } List children = nodeService.getChildAssocs(nodeRef); - for(ChildAssociationRef child: children) + for (ChildAssociationRef child : children) { - String newPath = path+"/"+child.getQName(); + String newPath = path + "/" + child.getQName(); printPermissions(child.getChildRef(), newPath); - + } - + } - + public void testSetNodePermissionEntry() { runAs("andy"); @@ -2003,14 +2136,14 @@ public class PermissionServiceTest extends AbstractPermissionTest assertFalse(permissionService.hasPermission(n2, getPermission(PermissionService.READ_CHILDREN)) == AccessStatus.ALLOWED); assertFalse(permissionService.hasPermission(n2, getPermission(PermissionService.READ_CONTENT)) == AccessStatus.ALLOWED); - //printPermissions(rootNodeRef, "/"); - + // printPermissions(rootNodeRef, "/"); + permissionService.deletePermission(new SimplePermissionEntry(n2, getPermission(PermissionService.READ_CHILDREN), "andy", AccessStatus.ALLOWED)); permissionService.deletePermission(new SimplePermissionEntry(n2, getPermission(PermissionService.READ_PROPERTIES), "andy", AccessStatus.ALLOWED)); permissionService.deletePermission(new SimplePermissionEntry(n2, getPermission(PermissionService.READ_CONTENT), "andy", AccessStatus.ALLOWED)); - //printPermissions(rootNodeRef, "/"); - + // printPermissions(rootNodeRef, "/"); + runAs("andy"); assertFalse(permissionService.hasPermission(n2, getPermission(PermissionService.READ)) == AccessStatus.ALLOWED); assertFalse(permissionService.hasPermission(n2, getPermission(PermissionService.READ_PROPERTIES)) == AccessStatus.ALLOWED); diff --git a/source/java/org/alfresco/repo/security/permissions/impl/SimplePermissionEntry.java b/source/java/org/alfresco/repo/security/permissions/impl/SimplePermissionEntry.java index 2bd9dbe93f..ee0f0c95cf 100644 --- a/source/java/org/alfresco/repo/security/permissions/impl/SimplePermissionEntry.java +++ b/source/java/org/alfresco/repo/security/permissions/impl/SimplePermissionEntry.java @@ -70,6 +70,7 @@ public final class SimplePermissionEntry extends AbstractPermissionEntry this.permissionReference = permissionReference; this.authority = authority; this.accessStatus = accessStatus; + this.position = position; } public PermissionReference getPermissionReference() diff --git a/source/java/org/alfresco/service/cmr/security/AccessPermission.java b/source/java/org/alfresco/service/cmr/security/AccessPermission.java index fdeafa0714..fa1c76bf48 100644 --- a/source/java/org/alfresco/service/cmr/security/AccessPermission.java +++ b/source/java/org/alfresco/service/cmr/security/AccessPermission.java @@ -62,4 +62,26 @@ public interface AccessPermission * @return */ public AuthorityType getAuthorityType(); + + + /** + * At what position in the inheritance chain for permissions is this permission set? + * = 0 -> Set direct on the object. + * > 0 -> Inherited + * < 0 -> We don't know and are using this object for reporting (e.g. the actual permissions that apply to a node for the current user) + * @return + */ + public int getPosition(); + + /** + * Is this an inherited permission entry? + * @return + */ + public boolean isInherited(); + + /** + * Is this permission set on the object? + * @return + */ + public boolean isSetDirectly(); }