diff --git a/config/alfresco/bootstrap/sitesSpace.xml b/config/alfresco/bootstrap/sitesSpace.xml index 6920e8702b..52f078b394 100644 --- a/config/alfresco/bootstrap/sitesSpace.xml +++ b/config/alfresco/bootstrap/sitesSpace.xml @@ -2,10 +2,6 @@ - - GROUP_EVERYONE - Contributor - @@ -27,4 +23,4 @@ - \ No newline at end of file + diff --git a/config/alfresco/messages/patch-service.properties b/config/alfresco/messages/patch-service.properties index 831e4c9a98..2778af6d65 100644 --- a/config/alfresco/messages/patch-service.properties +++ b/config/alfresco/messages/patch-service.properties @@ -430,3 +430,6 @@ patch.copiedFromAspect.result=Fixed cm:copiedfrom model for {0} nodes. See file patch.workflowNotification.description=Patch to add workflow email notification email folder and template. patch.nodeTemplatesFolder.description=Patch to create new Data Dictionary folder for Share - Create Node by Template + +patch.sitesSpacePermissions.description=Patch to remove the EVERYONE Contributor permissions on the Sites Space (parent container of all Sites) +patch.sitesSpacePermissions.result=Permissions corrected. diff --git a/config/alfresco/patch/patch-services-context.xml b/config/alfresco/patch/patch-services-context.xml index 17ed953318..b738cb2862 100644 --- a/config/alfresco/patch/patch-services-context.xml +++ b/config/alfresco/patch/patch-services-context.xml @@ -3050,4 +3050,17 @@ + + + patch.sitesSpacePermissions + patch.sitesSpacePermissions.description + 0 + 5017 + 5018 + true + true + + + + diff --git a/config/alfresco/version.properties b/config/alfresco/version.properties index 44ea92f8f2..372724fa13 100644 --- a/config/alfresco/version.properties +++ b/config/alfresco/version.properties @@ -19,4 +19,4 @@ version.build=@build-number@ # Schema number -version.schema=5017 +version.schema=5018 diff --git a/source/java/org/alfresco/repo/admin/patch/impl/SitesSpacePermissionsPatch.java b/source/java/org/alfresco/repo/admin/patch/impl/SitesSpacePermissionsPatch.java new file mode 100644 index 0000000000..dbd2a84065 --- /dev/null +++ b/source/java/org/alfresco/repo/admin/patch/impl/SitesSpacePermissionsPatch.java @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2005-2010 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * 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 . + */ +package org.alfresco.repo.admin.patch.impl; + +import java.util.List; +import java.util.Properties; + +import org.alfresco.repo.admin.patch.AbstractPatch; +import org.alfresco.repo.importer.ImporterBootstrap; +import org.alfresco.service.cmr.admin.PatchException; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.security.PermissionService; +import org.springframework.extensions.surf.util.I18NUtil; + +/** + * Patch to remove the GROUP_EVERYONE Contributor permissions on the + * Sites Space (/ + *

+ * Formerly, all users could create anything in this folder. As only + * Sites should live there, and the SiteService handles permissions itself, + * the Contributor permission can be removed. + * + * @author Nick Burch + * @since 4.0 + */ +public class SitesSpacePermissionsPatch extends AbstractPatch +{ + // Message IDs + private static final String MSG_SUCCESS = "patch.sitesSpacePermissions.result"; + + // Folders' names for path building + private static final String PROPERTY_COMPANY_HOME_CHILDNAME = "spaces.company_home.childname"; + private static final String PROPERTY_SITES_CHILDNAME = "spaces.sites.childname"; + + // Things we've found + private NodeRef companyHomeNodeRef; + private NodeRef sitesNodeRef; + + // Dependencies + private ImporterBootstrap importerBootstrap; + private PermissionService permissionService; + + public void setImporterBootstrap(ImporterBootstrap importerBootstrap) + { + this.importerBootstrap = importerBootstrap; + } + public void setPermissionService(PermissionService permissionService) + { + this.permissionService = permissionService; + } + + @Override + protected void checkProperties() + { + super.checkProperties(); + checkPropertyNotNull(importerBootstrap, "importerBootstrap"); + checkPropertyNotNull(permissionService, "permissionService"); + } + + public SitesSpacePermissionsPatch() + { + } + + protected void setUp() throws Exception + { + // Get the node store that we must work against + StoreRef storeRef = importerBootstrap.getStoreRef(); + if (storeRef == null) + { + throw new PatchException("Bootstrap store has not been set"); + } + NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef); + + // Build up the Assocation Names that form the path + Properties configuration = importerBootstrap.getConfiguration(); + + String companyHomeChildName = configuration.getProperty(PROPERTY_COMPANY_HOME_CHILDNAME); + if (companyHomeChildName == null || companyHomeChildName.length() == 0) + { + throw new PatchException("Bootstrap property '" + PROPERTY_COMPANY_HOME_CHILDNAME + "' is not present"); + } + String sitesChildName = configuration.getProperty(PROPERTY_SITES_CHILDNAME); + if (sitesChildName == null || sitesChildName.length() == 0) + { + throw new PatchException("Bootstrap property '" + PROPERTY_SITES_CHILDNAME + "' is not present"); + } + + // Build the search string to get the company home node + StringBuilder sb = new StringBuilder(256); + sb.append("/").append(companyHomeChildName); + String xpath = sb.toString(); + // get the company home + List nodeRefs = searchService.selectNodes(storeRootNodeRef, xpath, null, namespaceService, false); + if (nodeRefs.size() == 0) + { + throw new PatchException("XPath didn't return any results: \n" + " root: " + storeRootNodeRef + "\n" + " xpath: " + xpath); + } + else if (nodeRefs.size() > 1) + { + throw new PatchException("XPath returned too many results: \n" + " root: " + storeRootNodeRef + "\n" + " xpath: " + xpath + "\n" + " results: " + nodeRefs); + } + this.companyHomeNodeRef = nodeRefs.get(0); + + // build the search string to get the sites node + sb.append("/").append(sitesChildName); + xpath = sb.toString(); + // get the sites node + nodeRefs = searchService.selectNodes(storeRootNodeRef, xpath, null, namespaceService, false); + if (nodeRefs.size() == 0) + { + throw new PatchException("XPath didn't return any results: \n" + " root: " + storeRootNodeRef + "\n" + " xpath: " + xpath); + } + else if (nodeRefs.size() > 1) + { + throw new PatchException("XPath returned too many results: \n" + " root: " + storeRootNodeRef + "\n" + " xpath: " + xpath + "\n" + " results: " + nodeRefs); + } + this.sitesNodeRef = nodeRefs.get(0); + } + + @Override + protected String applyInternal() throws Exception + { + setUp(); + + // Get the sites space + NodeRef sitesSpace = sitesNodeRef; + if(sitesSpace == null || !nodeService.exists(sitesSpace)) + { + throw new IllegalStateException("Sites Space not found in Company Home!"); + } + + // Remove the permission + permissionService.deletePermission( + sitesSpace, + PermissionService.ALL_AUTHORITIES, + PermissionService.CONTRIBUTOR + ); + + // All done + String msg = I18NUtil.getMessage(MSG_SUCCESS); + return msg; + } +} diff --git a/source/java/org/alfresco/repo/site/SiteServiceImpl.java b/source/java/org/alfresco/repo/site/SiteServiceImpl.java index 99efcd971d..d2dc6083c6 100644 --- a/source/java/org/alfresco/repo/site/SiteServiceImpl.java +++ b/source/java/org/alfresco/repo/site/SiteServiceImpl.java @@ -449,27 +449,33 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic } // Get the site parent node reference - NodeRef siteParent = getSiteParent(shortName); + final NodeRef siteParent = getSiteParent(shortName); if (siteParent == null) { throw new SiteServiceException("No root sites folder exists"); } // Create the site node - PropertyMap properties = new PropertyMap(4); + final PropertyMap properties = new PropertyMap(4); properties.put(ContentModel.PROP_NAME, shortName); properties.put(SiteModel.PROP_SITE_PRESET, sitePreset); properties.put(SiteModel.PROP_SITE_VISIBILITY, visibility.toString()); properties.put(ContentModel.PROP_TITLE, title); properties.put(ContentModel.PROP_DESCRIPTION, description); - final NodeRef siteNodeRef = this.nodeService.createNode( - siteParent, - ContentModel.ASSOC_CONTAINS, - QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, shortName), - siteType, - properties).getChildRef(); - + final NodeRef siteNodeRef = AuthenticationUtil.runAsSystem(new RunAsWork() { + @Override + public NodeRef doWork() throws Exception { + return nodeService.createNode( + siteParent, + ContentModel.ASSOC_CONTAINS, + QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, shortName), + siteType, + properties + ).getChildRef(); + } + }); + // Make the new site a tag scope this.taggingService.addTagScope(siteNodeRef);