diff --git a/l10n.properties b/l10n.properties new file mode 100644 index 0000000000..536a9014f7 --- /dev/null +++ b/l10n.properties @@ -0,0 +1,6 @@ +# Branch specific configuration file for localisation scripts + +MESSAGE_SEARCH_PATH="src/main/resources/alfresco/messages/action-config*.properties src/main/resources/alfresco/messages/action-service*.properties src/main/resources/alfresco/messages/activiti-engine-messages*.properties src/main/resources/alfresco/messages/activities-service*.properties src/main/resources/alfresco/messages/activity-list*.properties src/main/resources/alfresco/messages/application-model*.properties src/main/resources/alfresco/messages/authentication*.properties src/main/resources/alfresco/messages/bootstrap-content-template-examples*.properties src/main/resources/alfresco/messages/bootstrap-example-javascripts*.properties src/main/resources/alfresco/messages/bootstrap-example-smartfoldertemplates*.properties src/main/resources/alfresco/messages/bootstrap-imapscripts*.properties src/main/resources/alfresco/messages/bootstrap-javascripts*.properties src/main/resources/alfresco/messages/bootstrap-messages*.properties src/main/resources/alfresco/messages/bootstrap-readme-template*.properties src/main/resources/alfresco/messages/bootstrap-spaces*.properties src/main/resources/alfresco/messages/bootstrap-templates*.properties src/main/resources/alfresco/messages/bootstrap-tutorial*.properties src/main/resources/alfresco/messages/bootstrap-webscripts*.properties src/main/resources/alfresco/messages/bootstrap-webscriptsextensions*.properties src/main/resources/alfresco/messages/bpm-messages*.properties src/main/resources/alfresco/messages/categories*.properties src/main/resources/alfresco/messages/coci-service*.properties src/main/resources/alfresco/messages/content-filter-languages*.properties src/main/resources/alfresco/messages/content-model*.properties src/main/resources/alfresco/messages/copy-service*.properties src/main/resources/alfresco/messages/custommodel-service*.properties src/main/resources/alfresco/messages/discussion-messages*.properties src/main/resources/alfresco/messages/distributionpolicies-model*.properties src/main/resources/alfresco/messages/doclink-service*.properties src/main/resources/alfresco/messages/download-model*.properties src/main/resources/alfresco/messages/email-server-model*.properties src/main/resources/alfresco/messages/email-service*.properties src/main/resources/alfresco/messages/file-folder-service*.properties src/main/resources/alfresco/messages/form-service*.properties src/main/resources/alfresco/messages/forum-model*.properties src/main/resources/alfresco/messages/imap-service*.properties src/main/resources/alfresco/messages/initiate-inplace*.properties src/main/resources/alfresco/messages/invitation-service*.properties src/main/resources/alfresco/messages/lock-service*.properties src/main/resources/alfresco/messages/notification-service*.properties src/main/resources/alfresco/messages/period-provider*.properties src/main/resources/alfresco/messages/permissions-service*.properties src/main/resources/alfresco/messages/publishing-model*.properties src/main/resources/alfresco/messages/publishing-service*.properties src/main/resources/alfresco/messages/quickshare-service*.properties src/main/resources/alfresco/messages/rendition-config*.properties src/main/resources/alfresco/messages/replication*.properties src/main/resources/alfresco/messages/repoadmin-service*.properties src/main/resources/alfresco/messages/reset-password-messages*.properties src/main/resources/alfresco/messages/rule-config*.properties src/main/resources/alfresco/messages/site-model*.properties src/main/resources/alfresco/messages/site-service*.properties src/main/resources/alfresco/messages/slingshot*.properties src/main/resources/alfresco/messages/smartfolder-model*.properties src/main/resources/alfresco/messages/subscription-service*.properties src/main/resources/alfresco/messages/system-messages*.properties src/main/resources/alfresco/messages/system-model*.properties src/main/resources/alfresco/messages/template-service*.properties src/main/resources/alfresco/messages/templates-messages*.properties src/main/resources/alfresco/messages/transfer-model*.properties src/main/resources/alfresco/messages/transfer-service*.properties src/main/resources/alfresco/messages/ui-inplace*.properties src/main/resources/alfresco/messages/webdav-messages*.properties src/main/resources/alfresco/messages/workflow-package-messages*.properties src/main/resources/alfresco/workflow/invitation-moderated-workflow-messages*.properties src/main/resources/alfresco/workflow/invitation-nominated-workflow-messages*.properties src/main/resources/alfresco/workflow/workflow-messages*.properties" + +EXCLUDED_FILES="src/main/resources/alfresco/messages/content-service.properties src/main/resources/alfresco/messages/module-messages.properties src/main/resources/alfresco/messages/patch-service.properties src/main/resources/alfresco/messages/repoadmin-interpreter-help.properties src/main/resources/alfresco/messages/schema-update.properties src/main/resources/alfresco/messages/tenant-interpreter-help.properties src/main/resources/alfresco/messages/version-service.properties src/main/resources/alfresco/messages/workflow-interpreter-help.properties src/main/resources/alfresco/alfresco-shared.properties src/main/resources/alfresco/caches.properties src/main/resources/alfresco/repository.properties src/main/resources/alfresco/client/config/repo-clients-apps.properties src/main/resources/alfresco/domain/cache-strategies.properties src/main/resources/alfresco/domain/hibernate-cfg.properties src/main/resources/alfresco/domain/quartz.properties src/main/resources/alfresco/domain/transaction.properties src/main/resources/alfresco/keystore/keystore-passwords.properties src/main/resources/alfresco/keystore/ssl-keystore-passwords.properties src/main/resources/alfresco/keystore/ssl-truststore-passwords.properties src/main/resources/alfresco/metadata/dwgmetadataextracter.properties src/main/resources/alfresco/metadata/htmlmetadataextracter.properties src/main/resources/alfresco/metadata/mailmetadataextracter.properties src/main/resources/alfresco/metadata/mp3metadataextracter.properties src/main/resources/alfresco/metadata/officemetadataextracter.properties src/main/resources/alfresco/metadata/opendocumentmetadataextracter.properties src/main/resources/alfresco/metadata/openofficemetadataextracter.properties src/main/resources/alfresco/metadata/pdfboxmetadataextracter.properties src/main/resources/alfresco/metadata/poimetadataextracter.properties src/main/resources/alfresco/metadata/rfc822metadataextracter.properties src/main/resources/alfresco/metadata/tikaaudiometadataextracter.properties src/main/resources/alfresco/metadata/tikaautometadataextracter.properties src/main/resources/alfresco/metadata/tikaspringconfiguredmetadataextracter.properties src/main/resources/alfresco/subsystems/activitiesfeed/default/activities-jobs.properties src/main/resources/alfresco/subsystems/authentication/alfrescontlm/alfresco-authentication.properties src/main/resources/alfresco/subsystems/authentication/external/external-authentication.properties src/main/resources/alfresco/subsystems/authentication/kerberos/kerberos-authentication.properties src/main/resources/alfresco/subsystems/authentication/ldap/ldap-authentication.properties src/main/resources/alfresco/subsystems/authentication/ldap-ad/ldap-ad-authentication.properties src/main/resources/alfresco/subsystems/authentication/passthru/passthru-authentication-context.properties src/main/resources/alfresco/subsystems/email/inboundsmtp/inboundsmtp.properties src/main/resources/alfresco/subsystems/email/outboundsmtp/outboundsmtp.properties src/main/resources/alfresco/subsystems/fileservers/default/file-servers.properties src/main/resources/alfresco/subsystems/imap/default/imap-server.properties src/main/resources/alfresco/subsystems/ooodirect/default/openoffice-transform.properties src/main/resources/alfresco/subsystems/replication/default/replication.properties src/main/resources/alfresco/subsystems/search/buildonly/common-search.properties src/main/resources/alfresco/subsystems/search/buildonly/index-recovery.properties src/main/resources/alfresco/subsystems/search/buildonly/lucene-search.properties src/main/resources/alfresco/subsystems/search/buildonly/scheduled-jobs.properties src/main/resources/alfresco/subsystems/search/noindex/common-search.properties src/main/resources/alfresco/subsystems/search/noindex/noindex-search.properties src/main/resources/alfresco/subsystems/search/solr/common-search.properties src/main/resources/alfresco/subsystems/search/solr/solr-backup.properties src/main/resources/alfresco/subsystems/search/solr/solr-search.properties src/main/resources/alfresco/subsystems/search/solr/facet/solr-facets-config.properties src/main/resources/alfresco/subsystems/search/solr4/common-search.properties src/main/resources/alfresco/subsystems/search/solr4/solr-backup.properties src/main/resources/alfresco/subsystems/search/solr4/solr-search.properties src/main/resources/alfresco/subsystems/search/solr6/common-search.properties src/main/resources/alfresco/subsystems/search/solr6/solr-backup.properties src/main/resources/alfresco/subsystems/search/solr6/solr-search.properties src/main/resources/alfresco/subsystems/subscriptions/default/subscription-service.properties src/main/resources/alfresco/subsystems/synchronization/default/default-synchronization.properties src/main/resources/alfresco/subsystems/sysadmin/default/sysadmin-parameter.properties src/main/resources/alfresco/subsystems/thirdparty/default/alfresco-pdf-renderer-transform.properties src/main/resources/alfresco/subsystems/thirdparty/default/imagemagick-transform.properties src/main/resources/alfresco/subsystems/transformers/default/transformers.properties src/main/resources/org/alfresco/encryption/keystore-parameters.properties src/main/resources/org/alfresco/repo/i18n/testmessages.properties src/main/resources/org/alfresco/repo/module/tool/default-file-mapping.properties src/main/resources/org/alfresco/repo/publishing/facebook/facebook-publishing.properties src/main/resources/org/alfresco/repo/publishing/flickr/flickr-publishing.properties src/main/resources/org/alfresco/repo/publishing/linkedin/linkedin-publishing.properties src/main/resources/org/alfresco/repo/publishing/slideshare/slideshare-publishing.properties src/main/resources/org/alfresco/repo/publishing/twitter/twitter-publishing.properties src/main/resources/org/alfresco/repo/publishing/youtube/youtube-publishing.properties" + diff --git a/src/main/java/org/alfresco/repo/action/executer/MailActionExecuter.java b/src/main/java/org/alfresco/repo/action/executer/MailActionExecuter.java index 07d46f2751..1cfff8df39 100644 --- a/src/main/java/org/alfresco/repo/action/executer/MailActionExecuter.java +++ b/src/main/java/org/alfresco/repo/action/executer/MailActionExecuter.java @@ -614,11 +614,13 @@ public class MailActionExecuter extends ActionExecuterAbstractBase } // set recipient - String to = (String)ruleAction.getParameterValue(PARAM_TO); + String to = (String)ruleAction.getParameterValue(PARAM_TO); + String toRecipients = null; if (to != null && to.length() != 0) { messageRef[0].setTo(to); - + toRecipients = to; + // Note: there is no validation on the username to check that it actually is an email address. // TODO Fix this. @@ -777,7 +779,8 @@ public class MailActionExecuter extends ActionExecuterAbstractBase if(recipients.size() > 0) { - messageRef[0].setTo(recipients.toArray(new String[recipients.size()])); + messageRef[0].setTo(recipients.toArray(new String[recipients.size()])); + toRecipients = String.join(",", recipients); } else { @@ -925,7 +928,7 @@ public class MailActionExecuter extends ActionExecuterAbstractBase } // build the email template model - Map model = createEmailTemplateModel(actionedUponNodeRef, suppliedModel, fromPerson); + Map model = createEmailTemplateModel(actionedUponNodeRef, suppliedModel, fromPerson, toRecipients); // Determine the locale to use to send the email. Locale locale = recipient.getSecond(); @@ -1044,8 +1047,8 @@ public class MailActionExecuter extends ActionExecuterAbstractBase { // Send the message unless we are in "testMode" if (!testMode) - { - mailService.send(preparedMessage.getMimeMessage()); + { + mailService.send(preparedMessage.getMimeMessage()); onSend(); } else @@ -1054,7 +1057,7 @@ public class MailActionExecuter extends ActionExecuterAbstractBase testSentCount++; } } - catch (MailException e) + catch (NullPointerException | MailException e) { onFail(); String to = (String)ruleAction.getParameterValue(PARAM_TO); @@ -1500,15 +1503,20 @@ public class MailActionExecuter extends ActionExecuterAbstractBase * * @return Model map for email templates */ - private Map createEmailTemplateModel(NodeRef ref, Map suppliedModel, NodeRef fromPerson) + private Map createEmailTemplateModel(NodeRef ref, Map suppliedModel, NodeRef fromPerson, String toRecipents) { Map model = new HashMap(8, 1.0f); if (fromPerson != null) { model.put("person", new TemplateNode(fromPerson, serviceRegistry, null)); - } - + } + + if (toRecipents != null) + { + model.put("to", toRecipents); + } + if (ref != null) { model.put("document", new TemplateNode(ref, serviceRegistry, null)); 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/action/executer/AbstractMailActionExecuterTest.java b/src/test/java/org/alfresco/repo/action/executer/AbstractMailActionExecuterTest.java index 5144cfb68a..d2d6513b93 100644 --- a/src/test/java/org/alfresco/repo/action/executer/AbstractMailActionExecuterTest.java +++ b/src/test/java/org/alfresco/repo/action/executer/AbstractMailActionExecuterTest.java @@ -772,6 +772,60 @@ public abstract class AbstractMailActionExecuterTest } } - - + /** + * Test for MNT-17970 + * @throws IOException + * @throws MessagingException + */ + @Test + public void testGetToUsersWhenSendingToGroup() throws IOException, MessagingException + { + String groupName = null; + final String USER1 = "test_user1"; + final String USER2 = "test_user2"; + try + { + // Create users and add them to a group + createUser(USER1, null); + createUser(USER2, null); + groupName = AUTHORITY_SERVICE.createAuthority(AuthorityType.GROUP, "testgroup1"); + AUTHORITY_SERVICE.addAuthority(groupName, USER1); + AUTHORITY_SERVICE.addAuthority(groupName, USER2); + + // Create mail + final Action mailAction = ACTION_SERVICE.createAction(MailActionExecuter.NAME); + mailAction.setParameterValue(MailActionExecuter.PARAM_FROM, "some.body@example.com"); + mailAction.setParameterValue(MailActionExecuter.PARAM_TO_MANY, groupName); + mailAction.setParameterValue(MailActionExecuter.PARAM_SUBJECT, "Testing"); + mailAction.setParameterValue(MailActionExecuter.PARAM_TEXT, "Testing"); + mailAction.setParameterValue(MailActionExecuter.PARAM_TEMPLATE, "alfresco/templates/mail/testSentTo.txt.ftl"); + + RetryingTransactionHelper txHelper = APP_CONTEXT_INIT.getApplicationContext().getBean("retryingTransactionHelper", RetryingTransactionHelper.class); + + // Send mail + MimeMessage message = txHelper.doInTransaction(new RetryingTransactionCallback() + { + @Override + public MimeMessage execute() throws Throwable + { + ACTION_EXECUTER.executeImpl(mailAction, null); + return ACTION_EXECUTER.retrieveLastTestMessage(); + } + }, true); + + // Check that both users are displayed in message body + String recipients = USER1 + "@email.com" + "," + USER2 + "@email.com"; + Assert.assertNotNull(message); + Assert.assertEquals("This email was sent to " + recipients, (String) message.getContent()); + } + finally + { + if (groupName != null) + { + AUTHORITY_SERVICE.deleteAuthority(groupName, true); + } + PERSON_SERVICE.deletePerson(USER1); + PERSON_SERVICE.deletePerson(USER2); + } + } } 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") diff --git a/src/test/resources/alfresco/templates/mail/testSentTo.txt.ftl b/src/test/resources/alfresco/templates/mail/testSentTo.txt.ftl new file mode 100644 index 0000000000..7e4bd7c87a --- /dev/null +++ b/src/test/resources/alfresco/templates/mail/testSentTo.txt.ftl @@ -0,0 +1 @@ +This email was sent to ${to} \ No newline at end of file