From 41eba5bac8c27f855caddb15a5df83e8518ebf43 Mon Sep 17 00:00:00 2001 From: Andrei Rebegea Date: Tue, 5 Sep 2017 14:48:21 +0300 Subject: [PATCH 1/6] REPO-2872: fix HtmlParserContentTransformerTest.testEncodingHandling() test failing when run locally on systems other than Linux --- .../HtmlParserContentTransformerTest.java | 37 ++++++++----------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/src/test/java/org/alfresco/repo/content/transform/HtmlParserContentTransformerTest.java b/src/test/java/org/alfresco/repo/content/transform/HtmlParserContentTransformerTest.java index f7648aba84..3647b69e50 100644 --- a/src/test/java/org/alfresco/repo/content/transform/HtmlParserContentTransformerTest.java +++ b/src/test/java/org/alfresco/repo/content/transform/HtmlParserContentTransformerTest.java @@ -76,18 +76,24 @@ public class HtmlParserContentTransformerTest extends AbstractContentTransformer /** * Checks that we correctly handle text in different encodings, * no matter if the encoding is specified on the Content Property - * or in a meta tag within the HTML itself. (ALF-10466) + * or in a meta tag within the HTML itself. (ALF-10466) + * + * On Windows, org.htmlparser.beans.StringBean.carriageReturn() appends a new system dependent new line + * so we must be careful when checking the returned text */ public void testEncodingHandling() throws Exception - { + { + final String NEWLINE = System.getProperty ("line.separator"); final String TITLE = "Testing!"; final String TEXT_P1 = "This is some text in English"; final String TEXT_P2 = "This is more text in English"; final String TEXT_P3 = "C'est en Fran\u00e7ais et Espa\u00f1ol"; - String partA = ""+TITLE+""; - String partB = "\n

"+TEXT_P1+"

\n" + - "

"+TEXT_P2+"

\n" + "

"+TEXT_P3+"

\n"; + String partA = "" + TITLE + "" + NEWLINE; + String partB = "

" + TEXT_P1 + "

" + NEWLINE + + "

" + TEXT_P2 + "

" + NEWLINE + + "

" + TEXT_P3 + "

" + NEWLINE; String partC = ""; + final String expected = TITLE + NEWLINE + TEXT_P1 + NEWLINE + TEXT_P2 + NEWLINE + TEXT_P3 + NEWLINE; ContentWriter content; ContentWriter dest; @@ -108,10 +114,8 @@ public class HtmlParserContentTransformerTest extends AbstractContentTransformer dest.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); transformer.transform(content.getReader(), dest); - assertEquals( - TITLE + "\n" + TEXT_P1 + "\n" + TEXT_P2 + "\n" + TEXT_P3 + "\n", - dest.getReader().getContentString() - ); + + assertEquals(expected, dest.getReader().getContentString()); tmpS.delete(); tmpD.delete(); @@ -128,10 +132,7 @@ public class HtmlParserContentTransformerTest extends AbstractContentTransformer dest.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); transformer.transform(content.getReader(), dest); - assertEquals( - TITLE + "\n" + TEXT_P1 + "\n" + TEXT_P2 + "\n" + TEXT_P3 + "\n", - dest.getReader().getContentString() - ); + assertEquals(expected, dest.getReader().getContentString()); tmpS.delete(); tmpD.delete(); @@ -148,10 +149,7 @@ public class HtmlParserContentTransformerTest extends AbstractContentTransformer dest.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); transformer.transform(content.getReader(), dest); - assertEquals( - TITLE + "\n" + TEXT_P1 + "\n" + TEXT_P2 + "\n" + TEXT_P3 + "\n", - dest.getReader().getContentString() - ); + assertEquals(expected, dest.getReader().getContentString()); tmpS.delete(); tmpD.delete(); @@ -178,10 +176,7 @@ public class HtmlParserContentTransformerTest extends AbstractContentTransformer dest.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); transformer.transform(content.getReader(), dest); - assertEquals( - TITLE + "\n" + TEXT_P1 + "\n" + TEXT_P2 + "\n" + TEXT_P3 + "\n", - dest.getReader().getContentString() - ); + assertEquals(expected, dest.getReader().getContentString()); tmpS.delete(); tmpD.delete(); From 3c98f67e1a5e888d928f17a6cf775b954b81151d Mon Sep 17 00:00:00 2001 From: Cristian Turlica Date: Fri, 8 Sep 2017 15:51:43 +0300 Subject: [PATCH 2/6] REPO-2705: Service Pack: MNT-17961: Cannot create new Alfresco NON-versioned document with CMIS API Calls - added possibility to create cmis document with VersioningState.NONE --- .../java/org/alfresco/opencmis/AlfrescoCmisServiceImpl.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/java/org/alfresco/opencmis/AlfrescoCmisServiceImpl.java b/src/main/java/org/alfresco/opencmis/AlfrescoCmisServiceImpl.java index 0e01b2d199..6da2629133 100644 --- a/src/main/java/org/alfresco/opencmis/AlfrescoCmisServiceImpl.java +++ b/src/main/java/org/alfresco/opencmis/AlfrescoCmisServiceImpl.java @@ -1283,11 +1283,6 @@ public class AlfrescoCmisServiceImpl extends AbstractCmisService implements Alfr throw new CmisConstraintException("This document type does requires content!"); } - if (docType.isVersionable() && (versioningState == VersioningState.NONE)) - { - throw new CmisConstraintException("This document type is versionable!"); - } - if (!docType.isVersionable() && (versioningState != VersioningState.NONE)) { throw new CmisConstraintException("This document type is not versionable!"); From d1216de8d447280952f5a4c32885144a33ddbb89 Mon Sep 17 00:00:00 2001 From: alandavis Date: Mon, 11 Sep 2017 09:09:33 +0100 Subject: [PATCH 3/6] Fix/mnt 18404 image magick fails on windows (#14) REMO-18404 Environment not being set for ImageMagick The environment required by ImageMagick was not being set. Even though the environment shown by log4j.logger.org.alfresco.util.exec.RuntimeExec=trace indicated that the required variables already existed in the current environment, that does not mean they are passed on to the sub process. In this case they were not being passed on and they were not being set as additional variables required by the sub process. The bug was introduced when Alfresco PDF renderer was added (REPO-2054) to ACS 5.2.1 and ACS 5.2.g. The context file for ImageMagic (imagemagick-transform-context.xml) was used as the basis for Alfresco PDF renderer's context file. Unfortunately the names of the spring beans that provided the Windows and Unix environment variable values were not changed. As a result, ImageMagick was being provided with Alfresco PDF renderer's environment variables. The Alfresco global property img.gslib and environment variable $GS_LIB set using it, are now redundant following the REPO-2054 work so have been removed in this commit. When testing this issue we should test ImageMagick and Alfresco PDF renderer on both Windows and Unix (Linux). I have not dug into why ImageMagick and Alfresco PDF renderer are working on Linux. I'm guessing that the current environment is being passed on unlike Windows. --- .gitignore | 3 + .../alfresco-global.properties.sample | 21 +++--- ...lfresco-pdf-renderer-transform-context.xml | 6 +- .../default/imagemagick-transform-context.xml | 9 +-- .../default/imagemagick-transform.properties | 1 - .../ImageMagickContentTransformerTest.java | 64 +++++++++++-------- 6 files changed, 57 insertions(+), 47 deletions(-) diff --git a/.gitignore b/.gitignore index 5cd20fa5aa..ff04b28cf1 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,6 @@ target # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* +alf_data +/src/main/resources/alfresco-global.properties +/src/main/resources/alfresco/extension/custom-log4j.properties diff --git a/src/main/resources/alfresco-global.properties.sample b/src/main/resources/alfresco-global.properties.sample index a76e00e0a1..781a79a9db 100644 --- a/src/main/resources/alfresco-global.properties.sample +++ b/src/main/resources/alfresco-global.properties.sample @@ -29,7 +29,6 @@ # #img.coders=${img.root}/modules/coders #img.config=${img.root}/config -#img.gslib=${img.root}/lib # # Property to control whether schema updates are performed automatically. @@ -69,16 +68,16 @@ #db.url=jdbc:postgresql://localhost:5432/alfresco # -# DB2 connection -# -#db.driver=com.ibm.db2.jcc.DB2Driver -#db.url=jdbc:db2://localhost:50000/alfresco:retrieveMessagesFromServerOnGetMessage=true; +# DB2 connection +# +#db.driver=com.ibm.db2.jcc.DB2Driver +#db.url=jdbc:db2://localhost:50000/alfresco:retrieveMessagesFromServerOnGetMessage=true; # # When schema is used which does not match DB2 username then currentSchema and hibernate.default_schema should be set #db.url=jdbc:db2://localhost:50000/alfresco:retrieveMessagesFromServerOnGetMessage=true;currentSchema=${hibernate.default_schema}; #hibernate.default_schema=SAMPLE_SCHEMA - -# + +# # Index Recovery Mode #------------- #index.recovery.mode=AUTO @@ -142,11 +141,11 @@ #imap.server.port=143 #imap.server.host=localhost -# Default value of alfresco.rmi.services.host is 0.0.0.0 which means 'listen on all adapters'. -# This allows connections to JMX both remotely and locally. +# Default value of alfresco.rmi.services.host is 0.0.0.0 which means 'listen on all adapters'. +# This allows connections to JMX both remotely and locally. # -alfresco.rmi.services.host=0.0.0.0 - +alfresco.rmi.services.host=0.0.0.0 + # # # Assign individual ports for each service for best performance diff --git a/src/main/resources/alfresco/subsystems/thirdparty/default/alfresco-pdf-renderer-transform-context.xml b/src/main/resources/alfresco/subsystems/thirdparty/default/alfresco-pdf-renderer-transform-context.xml index 08d4cacf74..024e724778 100644 --- a/src/main/resources/alfresco/subsystems/thirdparty/default/alfresco-pdf-renderer-transform-context.xml +++ b/src/main/resources/alfresco/subsystems/thirdparty/default/alfresco-pdf-renderer-transform-context.xml @@ -20,7 +20,7 @@ - + @@ -47,7 +47,7 @@ - + @@ -57,7 +57,7 @@ - + diff --git a/src/main/resources/alfresco/subsystems/thirdparty/default/imagemagick-transform-context.xml b/src/main/resources/alfresco/subsystems/thirdparty/default/imagemagick-transform-context.xml index 5fc1f0c57f..6874cc5be2 100644 --- a/src/main/resources/alfresco/subsystems/thirdparty/default/imagemagick-transform-context.xml +++ b/src/main/resources/alfresco/subsystems/thirdparty/default/imagemagick-transform-context.xml @@ -22,7 +22,7 @@ - + @@ -50,7 +50,7 @@ - + @@ -62,9 +62,6 @@ ${img.config} - - ${img.gslib} - ${img.dyn} @@ -75,7 +72,7 @@ - + diff --git a/src/main/resources/alfresco/subsystems/thirdparty/default/imagemagick-transform.properties b/src/main/resources/alfresco/subsystems/thirdparty/default/imagemagick-transform.properties index 281e763a3b..0c0512e3be 100644 --- a/src/main/resources/alfresco/subsystems/thirdparty/default/imagemagick-transform.properties +++ b/src/main/resources/alfresco/subsystems/thirdparty/default/imagemagick-transform.properties @@ -4,4 +4,3 @@ img.dyn=${img.root}/lib img.exe=${img.root}/bin/convert img.coders=${img.root}/modules/coders img.config=${img.root}/config -img.gslib= diff --git a/src/test/java/org/alfresco/repo/content/transform/magick/ImageMagickContentTransformerTest.java b/src/test/java/org/alfresco/repo/content/transform/magick/ImageMagickContentTransformerTest.java index 1970caccd9..c7865b0bc8 100644 --- a/src/test/java/org/alfresco/repo/content/transform/magick/ImageMagickContentTransformerTest.java +++ b/src/test/java/org/alfresco/repo/content/transform/magick/ImageMagickContentTransformerTest.java @@ -1,28 +1,28 @@ -/* - * #%L - * Alfresco Repository - * %% - * Copyright (C) 2005 - 2016 Alfresco Software Limited - * %% - * This file is part of the Alfresco software. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * 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 . - * #L% - */ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * 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 . + * #L% + */ package org.alfresco.repo.content.transform.magick; import java.io.File; @@ -120,12 +120,24 @@ public class ImageMagickContentTransformerTest extends AbstractContentTransforme } } + public void testGifToPng() throws Exception + { + ImageTransformationOptions options = new ImageTransformationOptions(); + transform(MimetypeMap.MIMETYPE_IMAGE_GIF, MimetypeMap.MIMETYPE_IMAGE_PNG, options); + } + + public void testJpegToPng() throws Exception + { + ImageTransformationOptions options = new ImageTransformationOptions(); + transform(MimetypeMap.MIMETYPE_IMAGE_JPEG, MimetypeMap.MIMETYPE_IMAGE_PNG, options); + } + public void testPageSourceOptions() throws Exception { // Test empty source options ImageTransformationOptions options = new ImageTransformationOptions(); this.transform(MimetypeMap.MIMETYPE_PDF, MimetypeMap.MIMETYPE_IMAGE_PNG, options); - + // Test first page options = new ImageTransformationOptions(); List sourceOptionsList = new ArrayList(); From 28366861fcf8f5f46887d8f3ddea6ff4de931a8c Mon Sep 17 00:00:00 2001 From: Ancuta Morarasu Date: Fri, 8 Sep 2017 16:20:44 +0300 Subject: [PATCH 4/6] REPO-2705 / MNT-17961: Cannot create new Alfresco NON-versioned document with CMIS API Calls - test --- .../java/org/alfresco/opencmis/CMISTest.java | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/src/test/java/org/alfresco/opencmis/CMISTest.java b/src/test/java/org/alfresco/opencmis/CMISTest.java index dc1043a8a6..b0a69bb7cb 100644 --- a/src/test/java/org/alfresco/opencmis/CMISTest.java +++ b/src/test/java/org/alfresco/opencmis/CMISTest.java @@ -3668,6 +3668,64 @@ public class CMISTest AuthenticationUtil.popAuthentication(); } } + + @Test + public void testCreateDocWithVersioningStateNone() throws Exception + { + AuthenticationUtil.pushAuthentication(); + AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName()); + + try + { + // get repository id + final String repositoryId = withCmisService(new CmisServiceCallback() + { + @Override + public String execute(CmisService cmisService) + { + List repositories = cmisService.getRepositoryInfos(null); + assertTrue(repositories.size() > 0); + RepositoryInfo repo = repositories.get(0); + final String repositoryId = repo.getId(); + return repositoryId; + } + }, CmisVersion.CMIS_1_1); + + final NodeRef documentNodeRef = withCmisService(new CmisServiceCallback() + { + @Override + public NodeRef execute(CmisService cmisService) + { + final PropertiesImpl properties = new PropertiesImpl(); + String objectTypeId = "cmis:document"; + properties.addProperty(new PropertyIdImpl(PropertyIds.OBJECT_TYPE_ID, objectTypeId)); + String fileName = "textFile" + GUID.generate(); + properties.addProperty(new PropertyStringImpl(PropertyIds.NAME, fileName)); + final ContentStreamImpl contentStream = new ContentStreamImpl(fileName, MimetypeMap.MIMETYPE_TEXT_PLAIN, "Simple text plain document"); + + String nodeId = cmisService.create(repositoryId, properties, repositoryHelper.getCompanyHome().getId(), contentStream, VersioningState.NONE, null, null); + return new NodeRef(nodeId.substring(0, nodeId.indexOf(';'))); + } + }, CmisVersion.CMIS_1_1); + + // check versioning properties + transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback>() + { + @Override + public List execute() throws Throwable + { + assertTrue(nodeService.exists(documentNodeRef)); + assertFalse(nodeService.hasAspect(documentNodeRef, ContentModel.ASPECT_VERSIONABLE)); + + return null; + } + }); + } + finally + { + AuthenticationUtil.popAuthentication(); + } + } /** * MNT-14951: Test that the list of parents can be retrieved for a folder. From 7b24ed66b6c7ea12b42945c2ddf965ad8c286dcc Mon Sep 17 00:00:00 2001 From: Alex Mukha Date: Tue, 12 Sep 2017 11:09:29 +0100 Subject: [PATCH 5/6] REPO-2183 Update data-model to 6.18 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7154d23935..94b30fcb65 100644 --- a/pom.xml +++ b/pom.xml @@ -40,7 +40,7 @@ 6.0 6.13 6.0 - 6.17 + 6.18 6.3 1.0 From 2a8d08567f508d648b416bc51ed6e5f5fc526c12 Mon Sep 17 00:00:00 2001 From: Andrei Rebegea Date: Fri, 15 Sep 2017 14:44:50 +0300 Subject: [PATCH 6/6] Fix/repo 2880 move to perm fix (#18) * REPO-2880: MNT-18014 Site Managers cannot view content of folders with inheritance off after a Move Operation * REPO-2880: fix compilation error, add missing import --- .../repo/site/SitesPermissionCleaner.java | 155 +++++++++--------- .../repo/site/SiteServiceImplTest.java | 112 ++++++++++++- 2 files changed, 192 insertions(+), 75 deletions(-) diff --git a/src/main/java/org/alfresco/repo/site/SitesPermissionCleaner.java b/src/main/java/org/alfresco/repo/site/SitesPermissionCleaner.java index 76d37475d3..9c655b43a7 100644 --- a/src/main/java/org/alfresco/repo/site/SitesPermissionCleaner.java +++ b/src/main/java/org/alfresco/repo/site/SitesPermissionCleaner.java @@ -1,28 +1,28 @@ -/* - * #%L - * Alfresco Repository - * %% - * Copyright (C) 2005 - 2016 Alfresco Software Limited - * %% - * This file is part of the Alfresco software. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * 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 . - * #L% - */ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * 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 . + * #L% + */ package org.alfresco.repo.site; import java.util.List; @@ -31,6 +31,7 @@ import org.alfresco.repo.domain.node.NodeDAO; import org.alfresco.repo.domain.node.NodeIdAndAclId; import org.alfresco.repo.domain.permissions.Acl; import org.alfresco.repo.domain.permissions.AclDAO; +import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.permissions.ACLType; import org.alfresco.repo.security.permissions.AccessControlEntry; import org.alfresco.repo.security.permissions.AccessControlList; @@ -99,62 +100,70 @@ public class SitesPermissionCleaner public void cleanSitePermissions(final NodeRef targetNode, SiteInfo containingSite) { - if (nodeDAO.exists(targetNode)) + if (!nodeDAO.exists(targetNode)) { - // We can calculate the containing site at the start of a recursive call & then reuse it on subsequent calls. - if (containingSite == null) - { - containingSite = siteServiceImpl.getSite(targetNode); - } + return; + } + // We can calculate the containing site at the start of a recursive call & then reuse it on subsequent calls. + if (containingSite == null) + { + containingSite = siteServiceImpl.getSite(targetNode); + } - // Short-circuit at this point if the node is not in a Site. - if (containingSite != null) + // Short-circuit at this point if the node is not in a Site. + if (containingSite == null) + { + return; + } + // For performance reasons we navigate down the containment hierarchy using the DAOs + // rather than the NodeService. Note: direct use of NodeDAO requires tenantService (ALF-12732). + final Long targetNodeID = nodeDAO.getNodePair(tenantService.getName(targetNode)).getFirst(); + final Long targetNodeAclID = nodeDAO.getNodeAclId(targetNodeID); + Acl targetNodeAcl = aclDAO.getAcl(targetNodeAclID); + + // Nodes that don't have defining ACLs do not need to be considered. + if (targetNodeAcl.getAclType() == ACLType.DEFINING) + { + AccessControlList targetNodeAccessControlList = aclDAO.getAccessControlList(targetNodeAclID); + List targetNodeAclEntries = targetNodeAccessControlList.getEntries(); + for (AccessControlEntry entry : targetNodeAclEntries) { - // For performance reasons we navigate down the containment hierarchy using the DAOs - // rather than the NodeService. Note: direct use of NodeDAO requires tenantService (ALF-12732). - final Long targetNodeID = nodeDAO.getNodePair(tenantService.getName(targetNode)).getFirst(); - final Long targetNodeAclID = nodeDAO.getNodeAclId(targetNodeID); - Acl targetNodeAcl = aclDAO.getAcl(targetNodeAclID); - - // Nodes that don't have defining ACLs do not need to be considered. - if (targetNodeAcl.getAclType() == ACLType.DEFINING) + String authority = entry.getAuthority(); + + String thisSiteGroupPrefix = siteServiceImpl.getSiteGroup(containingSite.getShortName(), true); + + // If it's a group site permission for a site other than the current site + if (authority.startsWith(PermissionService.GROUP_PREFIX) && + // And it's not GROUP_EVERYONE + !authority.startsWith(PermissionService.ALL_AUTHORITIES) && !authority.startsWith(thisSiteGroupPrefix) && + // And if the current user has permissions to do it + publicServiceAccessService.hasAccess("PermissionService", "clearPermission", targetNode, authority) == AccessStatus.ALLOWED) { - AccessControlList targetNodeAccessControlList = aclDAO.getAccessControlList(targetNodeAclID); - List targetNodeAclEntries = targetNodeAccessControlList.getEntries(); - for (AccessControlEntry entry : targetNodeAclEntries) - { - String authority = entry.getAuthority(); - - String thisSiteGroupPrefix = siteServiceImpl.getSiteGroup(containingSite.getShortName(), true); - - // If it's a group site permission for a site other than the current site - if (authority.startsWith(PermissionService.GROUP_PREFIX) && - !authority.startsWith(PermissionService.ALL_AUTHORITIES) && // And it's not GROUP_EVERYONE - !authority.startsWith(thisSiteGroupPrefix)) - { - // And if the current user has permissions to do it - if (publicServiceAccessService.hasAccess("PermissionService", "clearPermission", targetNode, authority) == AccessStatus.ALLOWED) - { - // Then remove it. - permissionService.clearPermission(targetNode, authority); - } - if (publicServiceAccessService.hasAccess("PermissionService", "setInheritParentPermissions", targetNode, true) == AccessStatus.ALLOWED) - { - // And reenable permission inheritance. - permissionService.setInheritParentPermissions(targetNode, true); - } - } - - } + // Then remove it. + permissionService.clearPermission(targetNode, authority); } - - // Recurse - List childNodeIds = nodeDAO.getPrimaryChildrenAcls(targetNodeID); - for (NodeIdAndAclId nextChild : childNodeIds) + + if (!permissionService.getInheritParentPermissions(targetNode)) { - cleanSitePermissions(nodeDAO.getNodePair(nextChild.getId()).getSecond(), containingSite); + // The site manager from the new site, where this node was moved to, has to have permission to this node + String siteManagerAuthority = thisSiteGroupPrefix + "_" + SiteModel.SITE_MANAGER; + AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() + { + public Void doWork() throws Exception + { + permissionService.setPermission(targetNode, siteManagerAuthority, SiteModel.SITE_MANAGER, true); + return null; + } + }, AuthenticationUtil.getSystemUserName()); } } } + + // Recurse + List childNodeIds = nodeDAO.getPrimaryChildrenAcls(targetNodeID); + for (NodeIdAndAclId nextChild : childNodeIds) + { + cleanSitePermissions(nodeDAO.getNodePair(nextChild.getId()).getSecond(), containingSite); + } } } diff --git a/src/test/java/org/alfresco/repo/site/SiteServiceImplTest.java b/src/test/java/org/alfresco/repo/site/SiteServiceImplTest.java index 95bdf04954..43be6f9622 100644 --- a/src/test/java/org/alfresco/repo/site/SiteServiceImplTest.java +++ b/src/test/java/org/alfresco/repo/site/SiteServiceImplTest.java @@ -64,6 +64,7 @@ import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.TypeDefinition; import org.alfresco.service.cmr.model.FileFolderService; import org.alfresco.service.cmr.model.FileInfo; +import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.repository.CopyService; @@ -91,7 +92,6 @@ import org.alfresco.test_category.BaseSpringTestsCategory; import org.alfresco.util.ApplicationContextHelper; import org.alfresco.util.BaseAlfrescoSpringTest; import org.alfresco.util.GUID; -import org.alfresco.util.PropertyMap; import org.junit.experimental.categories.Category; import org.springframework.extensions.surf.util.I18NUtil; @@ -1167,7 +1167,115 @@ public class SiteServiceImplTest extends BaseAlfrescoSpringTest // Intentionally empty } } - + + /** + * This is an integration test for MNT-18014 + */ + public void testMoveFolderStructureWithNonInheritedPermission() + { + //Login to share as the admin user + AuthenticationUtil.setAdminUserAsFullyAuthenticatedUser(); + + // Create 2 sites test1, test2 as admin + String test1SiteShortName = "test1" + GUID.generate(); + String test2SiteShortName = "test2" + GUID.generate(); + createSite(test1SiteShortName, SiteService.DOCUMENT_LIBRARY, SiteVisibility.PUBLIC); + createSite(test2SiteShortName, SiteService.DOCUMENT_LIBRARY, SiteVisibility.PUBLIC); + + SiteInfo test1SiteInfo = this.siteService.getSite(test1SiteShortName); + assertNotNull(test1SiteInfo); + SiteInfo test2SiteInfo = this.siteService.getSite(test2SiteShortName); + assertNotNull(test2SiteInfo); + + // add user1 (USER_ONE) and user2 (USER_TWO) as managers on test1 site (test1SiteInfo) + siteService.setMembership(test1SiteShortName, USER_ONE, SiteModel.SITE_MANAGER); + siteService.setMembership(test1SiteShortName, USER_TWO, SiteModel.SITE_MANAGER); + + // Give manager role to user1 to test2 + siteService.setMembership(test2SiteShortName, USER_ONE, SiteModel.SITE_MANAGER); + + // Log in as user2 + AuthenticationUtil.setFullyAuthenticatedUser(USER_TWO); + + // In document library of test1, create fol1 containing fol2 containing fol3 + NodeRef documentLibraryTest1Site = siteService.getContainer(test1SiteShortName, SiteService.DOCUMENT_LIBRARY); + assertNotNull(documentLibraryTest1Site); + NodeRef fol1 = this.fileFolderService.create(documentLibraryTest1Site, "fol1-" + GUID.generate(), ContentModel.TYPE_FOLDER).getNodeRef(); + NodeRef fol2 = this.fileFolderService.create(fol1, "fol2-" + GUID.generate(), ContentModel.TYPE_FOLDER).getNodeRef(); + NodeRef fol3 = this.fileFolderService.create(fol2, "fol3-" + GUID.generate(), ContentModel.TYPE_FOLDER).getNodeRef(); + + // Cut inheritance on fol2 + permissionService.setInheritParentPermissions(fol2, false); + + // this is what happens when called from Share : permissions.post: + // var siteManagerAuthority = "GROUP_site_" + location.site + "_SiteManager"; + // // Insure Site Managers can still manage content. + // node.setPermission("SiteManager", siteManagerAuthority); + String test1SiteGroupPrefix = siteServiceImpl.getSiteGroup(test1SiteShortName, true); + String test1SiteManagerAuthority = test1SiteGroupPrefix + "_" + SiteModel.SITE_MANAGER; + permissionService.setPermission(fol2, test1SiteManagerAuthority, SiteModel.SITE_MANAGER, true); + + // Log in as user1, go to site test1 + AuthenticationUtil.setFullyAuthenticatedUser(USER_ONE); + + // Check that user1 can see fol1 fol2 fol3 + List childAssocs = nodeService.getChildAssocs(documentLibraryTest1Site); + assertEquals("Size should be 1", 1, childAssocs.size()); + assertTrue("Folder name should start with fol1", getFirstName(childAssocs).startsWith("fol1")); + childAssocs = nodeService.getChildAssocs(childAssocs.get(0).getChildRef()); + assertEquals("Size should be 1", 1, childAssocs.size()); + assertTrue("Folder name should start with fol2", getFirstName(childAssocs).startsWith("fol2")); + childAssocs = nodeService.getChildAssocs(childAssocs.get(0).getChildRef()); + assertEquals("Size should be 1", 1, childAssocs.size()); + assertTrue("Folder name should start with fol3", getFirstName(childAssocs).startsWith("fol3")); + + NodeRef documentLibraryTest2Site = siteService.getContainer(test2SiteShortName, SiteService.DOCUMENT_LIBRARY); + assertNotNull(documentLibraryTest2Site); + childAssocs = nodeService.getChildAssocs(documentLibraryTest2Site); + assertTrue("Folder should be empty.", childAssocs.isEmpty()); + + // Move fol1 to site test2 + ChildAssociationRef childAssociationRef = nodeService.moveNode(fol1, documentLibraryTest2Site, ContentModel.ASSOC_CONTAINS, + QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, GUID.generate())); + + // This is what Share does: + // move the node + //result.success = fileNode.move(parent, destNode); + // + //if (result.success) + //{ + // // If this was an inter-site move, we'll need to clean up the permissions on the node + // if ((fromSite) && (String(fromSite) !== String(fileNode.siteShortName))) + // { + // siteService.cleanSitePermissions(fileNode); + // } + //} + siteService.cleanSitePermissions(fol1, test2SiteInfo); + + childAssocs = nodeService.getChildAssocs(documentLibraryTest1Site); + assertTrue("test1Site document library should be empty.", childAssocs.isEmpty()); + + assertFalse("After the move the folder should keep the inherit permission value(false).", + permissionService.getInheritParentPermissions(fol2)); + + // Go to the site test2's document library and click on fol1 + // user1 is able to see the contents of fol1 + childAssocs = nodeService.getChildAssocs(documentLibraryTest2Site); + assertEquals("Size should be 1", 1, childAssocs.size()); + assertTrue("Folder name should start with fol1", getFirstName(childAssocs).startsWith("fol1")); + childAssocs = nodeService.getChildAssocs(childAssocs.get(0).getChildRef()); + assertEquals("Size should be 1", 1, childAssocs.size()); + assertTrue("Folder name should start with fol2", getFirstName(childAssocs).startsWith("fol2")); + childAssocs = nodeService.getChildAssocs(childAssocs.get(0).getChildRef()); + assertEquals("Size should be 1", 1, childAssocs.size()); + assertTrue("Folder name should start with fol3", getFirstName(childAssocs).startsWith("fol3")); + } + + private String getFirstName(List childAssocs) + { + return nodeService.getProperties(childAssocs.get(0).getChildRef()).get(ContentModel.PROP_NAME).toString(); + } + public void testDeleteSite() { @SuppressWarnings("deprecation")