From 927878fba23010ead89d714c91bd9ac56599cb09 Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Fri, 4 Mar 2016 15:01:45 +0000 Subject: [PATCH] Merged 5.1.0 (5.1.0) to 5.1.N (5.1.1) 122919 jphuynh: Merged SAVA/BRANCHES/ACE-5162 (5.1.0) to 5.1.0 (5.1.0) 122838 sdinuta: ACE-5162: commited the changes for the solution before internal review git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.1.N/root@123118 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../repo/virtual/ActualEnvironment.java | 6 +- .../repo/virtual/AlfrescoEnviroment.java | 14 +- .../virtual/template/TemplateFilingRule.java | 9 +- ...VirtualPermissionServiceExtensionTest.java | 282 +++++++++++++++++- .../repo/virtual/template/testTemplate7.json | 35 +++ 5 files changed, 327 insertions(+), 19 deletions(-) create mode 100644 source/test-resources/org/alfresco/repo/virtual/template/testTemplate7.json diff --git a/source/java/org/alfresco/repo/virtual/ActualEnvironment.java b/source/java/org/alfresco/repo/virtual/ActualEnvironment.java index 57c19ee5bf..989d88d3ea 100644 --- a/source/java/org/alfresco/repo/virtual/ActualEnvironment.java +++ b/source/java/org/alfresco/repo/virtual/ActualEnvironment.java @@ -102,9 +102,11 @@ public interface ActualEnvironment FileInfo create(NodeRef parentNodeRef, String name, QName typeQName) throws FileExistsException; - ContentWriter getWriter(NodeRef nodeRef, QName propertyQName, boolean update) - throws InvalidNodeRefException, InvalidTypeException; + ContentWriter getWriter(NodeRef nodeRef, QName propertyQName, boolean update) throws InvalidNodeRefException, + InvalidTypeException; void addAspect(NodeRef nodeRef, QName aspectTypeQName, Map aspectProperties) throws InvalidNodeRefException, InvalidAspectException; + + boolean hasPermission(NodeRef nodeRef, String perm); } diff --git a/source/java/org/alfresco/repo/virtual/AlfrescoEnviroment.java b/source/java/org/alfresco/repo/virtual/AlfrescoEnviroment.java index 38b802f36e..2e0a1600c0 100644 --- a/source/java/org/alfresco/repo/virtual/AlfrescoEnviroment.java +++ b/source/java/org/alfresco/repo/virtual/AlfrescoEnviroment.java @@ -44,6 +44,7 @@ import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.Path; import org.alfresco.service.cmr.search.ResultSet; import org.alfresco.service.cmr.search.SearchParameters; +import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.namespace.NamespacePrefixResolver; import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QNamePattern; @@ -60,14 +61,14 @@ public class AlfrescoEnviroment implements ActualEnvironment private NamespacePrefixResolver namespacePrefixResolver; private Repository repositoryHelper; - + private NodeRefResolver nodeRefResolver; public void setNodeRefResolver(NodeRefResolver nodeRefResolver) { this.nodeRefResolver = nodeRefResolver; } - + public void setAlfrescoAPIFacet(AlfrescoAPIFacet apiFacet) { this.apiFacet = apiFacet; @@ -82,7 +83,7 @@ public class AlfrescoEnviroment implements ActualEnvironment { return this.serviceRegistry; } - + public void setRepositoryHelper(Repository repository) { this.repositoryHelper = repository; @@ -299,4 +300,11 @@ public class AlfrescoEnviroment implements ActualEnvironment Resource resource = resolver.getResource("classpath:" + classpath); return resource.exists(); } + + @Override + public boolean hasPermission(NodeRef nodeRef, String perm) + { + return apiFacet.getPermissionService().hasPermission(nodeRef, + perm).equals(AccessStatus.ALLOWED); + } } diff --git a/source/java/org/alfresco/repo/virtual/template/TemplateFilingRule.java b/source/java/org/alfresco/repo/virtual/template/TemplateFilingRule.java index 67f5cbc899..ba03b96467 100644 --- a/source/java/org/alfresco/repo/virtual/template/TemplateFilingRule.java +++ b/source/java/org/alfresco/repo/virtual/template/TemplateFilingRule.java @@ -33,6 +33,7 @@ import org.alfresco.repo.virtual.config.NodeRefPathExpression; import org.alfresco.repo.virtual.ref.GetActualNodeRefMethod; import org.alfresco.repo.virtual.ref.Reference; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.namespace.NamespacePrefixResolver; import org.alfresco.service.namespace.QName; import org.alfresco.util.ISO9075; @@ -59,7 +60,6 @@ public class TemplateFilingRule implements FilingRule private Map stringProperties; - public TemplateFilingRule(ActualEnvironment environment, String path, String type, Set aspects, Map properties) { @@ -180,11 +180,16 @@ public class TemplateFilingRule implements FilingRule String[] pathElements = NodeRefPathExpression.splitAndNormalizePath(path); for (int i = 0; i < pathElements.length; i++) { - pathElements[i]=ISO9075.decode(pathElements[i]); + pathElements[i] = ISO9075.decode(pathElements[i]); } fParentRef = env.findQNamePath(pathElements); } + if (!env.hasPermission(fParentRef, + PermissionService.READ_PERMISSIONS)) + { + fParentRef = null; + } if (failIfNotFound && fParentRef == null) { throw new VirtualizationException("The filing path " + path + " could not be resolved."); diff --git a/source/test-java/org/alfresco/repo/virtual/bundle/VirtualPermissionServiceExtensionTest.java b/source/test-java/org/alfresco/repo/virtual/bundle/VirtualPermissionServiceExtensionTest.java index e094c4acbd..0924a38b39 100644 --- a/source/test-java/org/alfresco/repo/virtual/bundle/VirtualPermissionServiceExtensionTest.java +++ b/source/test-java/org/alfresco/repo/virtual/bundle/VirtualPermissionServiceExtensionTest.java @@ -27,7 +27,6 @@ import java.util.Map; import java.util.Set; import org.alfresco.model.ContentModel; -import org.alfresco.repo.jscript.ScriptNode; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.security.permissions.NodePermissionEntry; @@ -36,13 +35,13 @@ import org.alfresco.repo.security.permissions.PermissionServiceSPI; import org.alfresco.repo.virtual.VirtualizationIntegrationTest; import org.alfresco.repo.virtual.store.VirtualStoreImpl; import org.alfresco.repo.virtual.store.VirtualUserPermissions; -import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.Path; import org.alfresco.service.cmr.security.AccessPermission; import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.PermissionService; +import org.alfresco.service.cmr.site.SiteService; +import org.alfresco.service.cmr.site.SiteVisibility; import org.junit.Test; public class VirtualPermissionServiceExtensionTest extends VirtualizationIntegrationTest @@ -62,6 +61,16 @@ public class VirtualPermissionServiceExtensionTest extends VirtualizationIntegra /** original user permissions to be restored on tear down */ private VirtualUserPermissions savedUserPermissions; + private NodeRef testSiteFolder = null, smartFolder = null, contributionDocsFolder = null; + + private SiteService siteService; + + private String sName = "mytestsite_ace_5162"; + + private NodeRef myContentSMF; + + private NodeRef contributionsSMF; + @Override protected void setUp() throws Exception { @@ -69,10 +78,12 @@ public class VirtualPermissionServiceExtensionTest extends VirtualizationIntegra // we set our own virtual user permissions in order to be context xml // independent smartStore = VirtualPermissionServiceExtensionTest.ctx.getBean("smartStore", - VirtualStoreImpl.class); + VirtualStoreImpl.class); permissionService = VirtualPermissionServiceExtensionTest.ctx.getBean("permissionServiceImpl", PermissionServiceSPI.class); + siteService = VirtualPermissionServiceExtensionTest.ctx.getBean("siteService", + SiteService.class); user1 = "user1"; @@ -95,6 +106,15 @@ public class VirtualPermissionServiceExtensionTest extends VirtualizationIntegra PermissionService.DELETE_CHILDREN, false); + this.permissionService.setPermission(this.virtualFolder1NodeRef, + user1, + PermissionService.READ_PERMISSIONS, + true); + this.permissionService.setPermission(this.virtualFolder1NodeRef, + user2, + PermissionService.READ_PERMISSIONS, + true); + this.permissionService.setPermission(this.virtualFolder1NodeRef, user1, PermissionService.READ_PROPERTIES, @@ -225,9 +245,6 @@ public class VirtualPermissionServiceExtensionTest extends VirtualizationIntegra ContentModel.ASSOC_CONTAINS, "FilingFolder_filing_path"); - - - assertEquals(AccessStatus.DENIED, hasPermissionAs(filingFolderVirtualNodeRef, PermissionService.DELETE, @@ -236,7 +253,7 @@ public class VirtualPermissionServiceExtensionTest extends VirtualizationIntegra assertEquals(AccessStatus.DENIED, hasPermissionAs(filingFolderVirtualNodeRef, asTypedPermission(PermissionService.DELETE), - user1) ); + user1)); assertEquals(AccessStatus.DENIED, hasPermissionAs(filingFolderVirtualNodeRef, @@ -249,7 +266,7 @@ public class VirtualPermissionServiceExtensionTest extends VirtualizationIntegra user1)); } - + @Test public void testHasPermissionAdherence_folderPath() throws Exception { @@ -270,12 +287,16 @@ public class VirtualPermissionServiceExtensionTest extends VirtualizationIntegra "FilingFolder"); NodeRef filingFolderNodeRef = filingFolderChildAssoc.getChildRef(); - + + this.permissionService.setPermission(filingFolderNodeRef, + user1, + PermissionService.READ_PERMISSIONS, + true); this.permissionService.setPermission(filingFolderNodeRef, user1, PermissionService.CREATE_CHILDREN, true); - + this.permissionService.setPermission(filingFolderNodeRef, user2, PermissionService.CREATE_CHILDREN, @@ -295,7 +316,7 @@ public class VirtualPermissionServiceExtensionTest extends VirtualizationIntegra hasPermissionAs(filingFolderNodeRef, PermissionService.CREATE_CHILDREN, user2)); - + assertEquals(AccessStatus.DENIED, hasPermissionAs(filingFolderVirtualNodeRef, PermissionService.DELETE, @@ -615,6 +636,243 @@ public class VirtualPermissionServiceExtensionTest extends VirtualizationIntegra } + @Test + public void testNodes_WithfilingPath_withNoReadPermissions_hasReadonlyPermission() throws Exception + { + final String[] deniedReadOnly = new String[] { PermissionService.UNLOCK, PermissionService.CANCEL_CHECK_OUT, + PermissionService.CHANGE_PERMISSIONS, PermissionService.CREATE_CHILDREN, PermissionService.DELETE, + PermissionService.WRITE, PermissionService.DELETE_NODE, PermissionService.WRITE_PROPERTIES, + PermissionService.WRITE_CONTENT, PermissionService.CREATE_ASSOCIATIONS }; + + NodeRef virtualFolderT5 = createVirtualizedFolder(testRootFolder.getNodeRef(), + "VirtualFolderT5", + TEST_TEMPLATE_5_JSON_SYS_PATH); + + NodeRef filingFolderVirtualNodeRef = nodeService.getChildByName(virtualFolderT5, + ContentModel.ASSOC_CONTAINS, + "FilingFolder_filing_path"); + + ChildAssociationRef filingFolderChildAssoc = createFolder(rootNodeRef, + "FilingFolder"); + + NodeRef filingFolderNodeRef = filingFolderChildAssoc.getChildRef(); + + this.permissionService.setPermission(filingFolderNodeRef, + user1, + PermissionService.READ_PERMISSIONS, + false); + + this.permissionService.setPermission(filingFolderNodeRef, + user1, + PermissionService.CREATE_CHILDREN, + true); + + this.permissionService.setPermission(filingFolderNodeRef, + user2, + PermissionService.CREATE_CHILDREN, + false); + + assertEquals(AccessStatus.DENIED, + hasPermissionAs(filingFolderNodeRef, + PermissionService.DELETE, + user1)); + + assertEquals(AccessStatus.ALLOWED, + hasPermissionAs(filingFolderNodeRef, + PermissionService.CREATE_CHILDREN, + user1)); + + assertEquals(AccessStatus.DENIED, + hasPermissionAs(filingFolderNodeRef, + PermissionService.CREATE_CHILDREN, + user2)); + + // for virtual folder + + StringBuilder nonDeniedTrace = new StringBuilder(); + for (int i = 0; i < deniedReadOnly.length; i++) + { + AccessStatus accessStatus = hasPermissionAs(filingFolderVirtualNodeRef, + deniedReadOnly[i], + user1); + if (!AccessStatus.DENIED.equals(accessStatus)) + { + if (nonDeniedTrace.length() > 0) + { + nonDeniedTrace.append(","); + } + nonDeniedTrace.append(deniedReadOnly[i]); + } + } + + assertTrue("Non-denied permissions on RO virtual nodes : " + nonDeniedTrace, + nonDeniedTrace.length() == 0); + + this.permissionService.setPermission(filingFolderNodeRef, + user1, + PermissionService.DELETE_CHILDREN, + true); + + this.permissionService.setPermission(filingFolderNodeRef, + user2, + PermissionService.DELETE_CHILDREN, + false); + + this.permissionService.setPermission(filingFolderNodeRef, + user1, + PermissionService.READ_PROPERTIES, + true); + + this.permissionService.setPermission(filingFolderNodeRef, + user1, + PermissionService.CREATE_CHILDREN, + false); + + this.permissionService.setPermission(filingFolderNodeRef, + user1, + PermissionService.DELETE, + true); + + assertEquals(AccessStatus.ALLOWED, + hasPermissionAs(filingFolderNodeRef, + PermissionService.DELETE, + user1)); + + assertEquals(AccessStatus.DENIED, + hasPermissionAs(filingFolderNodeRef, + PermissionService.CREATE_CHILDREN, + user1)); + + StringBuilder nonDeniedTrace1 = new StringBuilder(); + for (int i = 0; i < deniedReadOnly.length; i++) + { + AccessStatus accessStatus = hasPermissionAs(filingFolderVirtualNodeRef, + deniedReadOnly[i], + user1); + if (!AccessStatus.DENIED.equals(accessStatus)) + { + if (nonDeniedTrace1.length() > 0) + { + nonDeniedTrace1.append(","); + } + nonDeniedTrace1.append(deniedReadOnly[i]); + } + } + + assertTrue("Non-denied permissions on RO virtual nodes : " + nonDeniedTrace1, + nonDeniedTrace1.length() == 0); + + } + + @Test + public void testPerm_ace_5162() throws Exception + { + final String[] deniedReadOnly = new String[] { PermissionService.UNLOCK, PermissionService.CANCEL_CHECK_OUT, + PermissionService.CHANGE_PERMISSIONS, PermissionService.CREATE_CHILDREN, PermissionService.DELETE, + PermissionService.WRITE, PermissionService.DELETE_NODE, PermissionService.WRITE_PROPERTIES, + PermissionService.WRITE_CONTENT, PermissionService.CREATE_ASSOCIATIONS }; + + try + { + // Create a public site + + siteService.createSite("testSitePreset", + sName, + sName, + sName, + SiteVisibility.PUBLIC); + + testSiteFolder = siteService.createContainer(sName, + "TestSiteFolder", + ContentModel.TYPE_FOLDER, + null); + + smartFolder = createVirtualizedFolder(testSiteFolder, + "SmartFolder", + "C" + TEST_TEMPLATE_CLASSPATH + "testTemplate7.json"); + contributionDocsFolder = createFolder(testSiteFolder, + "Contribution Docs").getChildRef(); + permissionService.setInheritParentPermissions(contributionDocsFolder, + false); + + myContentSMF = nodeService.getChildByName(smartFolder, + ContentModel.ASSOC_CONTAINS, + "My content"); + assertNotNull(myContentSMF); + + contributionsSMF = nodeService.getChildByName(myContentSMF, + ContentModel.ASSOC_CONTAINS, + "Contributions"); + assertNotNull(contributionsSMF); + + // test that the all denied permissions for read only virtual nodes + // apply for virtual nodes with filing path with no READ_PERMISSONS + // for authenticated user + StringBuilder nonDeniedTrace = new StringBuilder(); + for (int i = 0; i < deniedReadOnly.length; i++) + { + AccessStatus accessStatus = hasPermissionAs(contributionsSMF, + deniedReadOnly[i], + user1); + if (!AccessStatus.DENIED.equals(accessStatus)) + { + if (nonDeniedTrace.length() > 0) + { + nonDeniedTrace.append(","); + } + nonDeniedTrace.append(deniedReadOnly[i]); + } + } + + assertTrue("Non-denied permissions on RO virtual nodes : " + nonDeniedTrace, + nonDeniedTrace.length() == 0); + + // test that the admin user can see documents from virtual nodes + // with filing path with no inherited parent permissions + fileAndFolderService.create(contributionsSMF, + "T1", + ContentModel.TYPE_CONTENT); + + NodeRef childContet = nodeService.getChildByName(contributionsSMF, + ContentModel.ASSOC_CONTAINS, + "T1"); + assertNotNull(childContet); + + assertTrue(nodeService.getChildAssocs(contributionsSMF).size() > 0); + + // test that the user1 can't see documents from virtual nodes with + // filing path with no inherited parent permissions + RunAsWork hasChildAssocs = new RunAsWork() + { + @Override + public Boolean doWork() throws Exception + { + return nodeService.getChildAssocs(contributionsSMF).size() > 0; + } + }; + + boolean value = AuthenticationUtil.runAs(hasChildAssocs, + user1); + assertFalse(value); + } + finally + { + if (contributionDocsFolder != null) + { + nodeService.deleteNode(contributionDocsFolder); + } + if (smartFolder != null) + { + nodeService.deleteNode(smartFolder); + } + if (testSiteFolder != null) + { + nodeService.deleteNode(testSiteFolder); + } + siteService.deleteSite(sName); + } + } + private String asTypedPermission(String perm) { return smartStore.getUserPermissions().getPermissionTypeQName() + "." + perm; diff --git a/source/test-resources/org/alfresco/repo/virtual/template/testTemplate7.json b/source/test-resources/org/alfresco/repo/virtual/template/testTemplate7.json new file mode 100644 index 0000000000..836a877078 --- /dev/null +++ b/source/test-resources/org/alfresco/repo/virtual/template/testTemplate7.json @@ -0,0 +1,35 @@ +{ + "name":"Smart Folders Example", + "nodes":[ + { + "id":"1", + "name":"My content", + "description":"My files in this repository", + "nodes":[ + { + "id":"13", + "name":"Contributions", + "description":"My 'dublin core' contributions - add new documents here to contribute", + "search":{ + "language":"fts-alfresco", + "query":"+ASPECT:'cm:dublincore' AND (PATH:'/app:company_home/st:sites/cm:mytestsite_ace_5162/cm:TestSiteFolder/cm:Contribution_x0020_Docs/*')" + }, + "filing":{ + "path":"/app:company_home/st:sites/cm:mytestsite_ace_5162/cm:TestSiteFolder/cm:Contribution_x0020_Docs", + "classification":{ + "type":"cm:content", + "aspects":[ + "cm:dublincore" + ] + }, + "properties":{ + "cm:contributor":"%CURRENT_USER%", + "cm:rights":"Alfresco", + "cm:publisher":"Alfresco" + } + } + } + ] + } + ] +} \ No newline at end of file