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);