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/pom.xml b/pom.xml index 9bfa10ac3b..9b8e0e8dff 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 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!"); 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/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/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. 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(); 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(); 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")