diff --git a/config/alfresco/messages/patch-service.properties b/config/alfresco/messages/patch-service.properties
index 6e6030b3fa..4c5455bdfb 100644
--- a/config/alfresco/messages/patch-service.properties
+++ b/config/alfresco/messages/patch-service.properties
@@ -219,4 +219,7 @@ patch.updateDmPermissions.description=Update ACLs on all DM node objects to the
patch.updateDmPermissions.result=Updated ACLs. Created {0} defining ACLs.
patch.createSiteStore.description=Create the AVM store for site data structure for 3.0 web-tier clients.
-patch.createSiteStore.result=Created the AVM site data store.
\ No newline at end of file
+patch.createSiteStore.result=Created the AVM site data store.
+
+patch.sitePermissionRefactorPatch.description=Create permission groups for sites.
+patch.sitePermissionRefactorPatch.result=Groups have been created for all sites and user's allocated accordingly.
\ No newline at end of file
diff --git a/config/alfresco/patch/patch-services-context.xml b/config/alfresco/patch/patch-services-context.xml
index 4178aaeaff..1787a46644 100644
--- a/config/alfresco/patch/patch-services-context.xml
+++ b/config/alfresco/patch/patch-services-context.xml
@@ -1470,4 +1470,22 @@
+
+ patch.sitePermissionRefactorPatch
+ patch.sitePermissionRefactorPatch.description
+ 0
+ 128
+ 129
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/alfresco/site-services-context.xml b/config/alfresco/site-services-context.xml
index 9c04503753..8f717f0520 100644
--- a/config/alfresco/site-services-context.xml
+++ b/config/alfresco/site-services-context.xml
@@ -16,6 +16,40 @@
+
+
+
+ org.alfresco.repo.site.SiteService
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${server.transaction.mode.default}
+
+
+
+
+
+
+
+
@@ -25,6 +59,7 @@
+
diff --git a/config/alfresco/version.properties b/config/alfresco/version.properties
index c97f1fd1aa..4f5efb1fa0 100644
--- a/config/alfresco/version.properties
+++ b/config/alfresco/version.properties
@@ -19,4 +19,4 @@ version.build=@build-number@
# Schema number
-version.schema=128
\ No newline at end of file
+version.schema=129
\ No newline at end of file
diff --git a/source/java/org/alfresco/repo/admin/patch/impl/SitePermissionRefactorPatch.java b/source/java/org/alfresco/repo/admin/patch/impl/SitePermissionRefactorPatch.java
new file mode 100644
index 0000000000..1cdd595f17
--- /dev/null
+++ b/source/java/org/alfresco/repo/admin/patch/impl/SitePermissionRefactorPatch.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2005-2008 Alfresco Software Limited.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program 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 General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ * As a special exception to the terms and conditions of version 2.0 of
+ * the GPL, you may redistribute this Program in connection with Free/Libre
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's
+ * FLOSS exception. You should have recieved a copy of the text describing
+ * the FLOSS exception, and it is also available here:
+ * http://www.alfresco.com/legal/licensing"
+ */
+package org.alfresco.repo.admin.patch.impl;
+
+import java.util.List;
+import java.util.Set;
+
+import org.alfresco.i18n.I18NUtil;
+import org.alfresco.repo.admin.patch.AbstractPatch;
+import org.alfresco.repo.site.SiteInfo;
+import org.alfresco.repo.site.SiteModel;
+import org.alfresco.repo.site.SiteService;
+import org.alfresco.repo.site.SiteServiceImpl;
+import org.alfresco.service.cmr.security.AccessPermission;
+import org.alfresco.service.cmr.security.AuthorityService;
+import org.alfresco.service.cmr.security.AuthorityType;
+import org.alfresco.service.cmr.security.PermissionService;
+
+/**
+ * Patch's the site permission model to use groups to contain users.
+ *
+ * @author Roy Wetherall
+ */
+public class SitePermissionRefactorPatch extends AbstractPatch
+{
+ /** Messages */
+ private static final String STATUS_MSG = "patch.sitePermissionRefactorPatch.result";
+
+ /** Services */
+ private SiteService siteService;
+ private PermissionService permissionService;
+ private AuthorityService authorityService;
+
+ /**
+ * Set site service
+ *
+ * @param siteService the site service
+ */
+ public void setSiteService(SiteService siteService)
+ {
+ this.siteService = siteService;
+ }
+
+ /**
+ * Set the permission service
+ *
+ * @param permissionService the permission service
+ */
+ public void setPermissionService(PermissionService permissionService)
+ {
+ this.permissionService = permissionService;
+ }
+
+ /**
+ * The authority service
+ *
+ * @param authorityService the authority service
+ */
+ public void setAuthorityService(AuthorityService authorityService)
+ {
+ this.authorityService = authorityService;
+ }
+
+ /**
+ * @see org.alfresco.repo.admin.patch.AbstractPatch#applyInternal()
+ */
+ @Override
+ protected String applyInternal() throws Exception
+ {
+ // Set all the sites in the repository
+ List sites = this.siteService.listSites(null, null);
+ for (SiteInfo siteInfo : sites)
+ {
+ // Create the site's groups
+ String siteGroup = authorityService.createAuthority(
+ AuthorityType.GROUP,
+ null,
+ ((SiteServiceImpl)this.siteService).getSiteGroupName(siteInfo.getShortName(),
+ false));
+ Set permissions = permissionService.getSettablePermissions(SiteModel.TYPE_SITE);
+ for (String permission : permissions)
+ {
+ // Create a group for the permission
+ String permissionGroup = authorityService.createAuthority(
+ AuthorityType.GROUP,
+ siteGroup,
+ ((SiteServiceImpl)this.siteService).getSitePermissionGroupName(
+ siteInfo.getShortName(),
+ permission,
+ false));
+
+ // Assign the group the relevant permission on the site
+ permissionService.setPermission(siteInfo.getNodeRef(), permissionGroup, permission, true);
+ }
+
+ // Take the current members and assign them to the appropriate groups
+ Set currentPermissions = this.permissionService.getAllSetPermissions(siteInfo.getNodeRef());
+ for (AccessPermission permission : currentPermissions)
+ {
+ // Only support user's being transfered (if public the everyone group will stay on the node)
+ if (permission.getAuthorityType() == AuthorityType.USER)
+ {
+ // Add this authority to the appropriate group
+ String group = ((SiteServiceImpl)this.siteService).getSitePermissionGroupName(
+ siteInfo.getShortName(),
+ permission.getPermission(),
+ true);
+ this.authorityService.addAuthority(group, permission.getAuthority());
+
+ // Remove the permission from the node
+ this.permissionService.deletePermission(siteInfo.getNodeRef(), permission.getAuthority(), permission.getPermission());
+ }
+ }
+ }
+
+ // Report status
+ return I18NUtil.getMessage(STATUS_MSG);
+ }
+}
diff --git a/source/java/org/alfresco/repo/site/SiteServiceImpl.java b/source/java/org/alfresco/repo/site/SiteServiceImpl.java
index aa7470365b..f45e270f95 100644
--- a/source/java/org/alfresco/repo/site/SiteServiceImpl.java
+++ b/source/java/org/alfresco/repo/site/SiteServiceImpl.java
@@ -47,6 +47,7 @@ import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.AccessPermission;
+import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.AuthorityType;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.security.PersonService;
@@ -85,6 +86,7 @@ public class SiteServiceImpl implements SiteService, SiteModel
private PersonService personService;
private AuthenticationComponent authenticationComponent;
private TaggingService taggingService;
+ private AuthorityService authorityService;
/** The site root node reference */
private NodeRef siteRootNodeRef;
@@ -169,15 +171,31 @@ public class SiteServiceImpl implements SiteService, SiteModel
this.taggingService = taggingService;
}
+ /**
+ * Set the authority service
+ *
+ * @param authorityService authority service
+ */
+ public void setAuthorityService(AuthorityService authorityService)
+ {
+ this.authorityService = authorityService;
+ }
+
/**
* @see org.alfresco.repo.site.SiteService#createSite(java.lang.String, java.lang.String, java.lang.String, java.lang.String, boolean)
*/
- public SiteInfo createSite(String sitePreset, String shortName, String title, String description, boolean isPublic)
+ public SiteInfo createSite(final String sitePreset, String passedShortName, final String title, final String description, final boolean isPublic)
{
- /// TODO check for shortname duplicates
-
// Remove spaces from shortName
- shortName = shortName.replaceAll(" ", "");
+ final String shortName = passedShortName.replaceAll(" ", "");
+
+ // Check to see if we already have a site of this name
+ NodeRef existingSite = getSiteNodeRef(shortName);
+ if (existingSite != null)
+ {
+ // Throw an exception since we have a duplicate site name
+ throw new AlfrescoRuntimeException("Unable to create site because the site short name '" + shortName + "' is already in use. Site short names must be unique.");
+ }
// Get the site parent node reference
NodeRef siteParent = getSiteParent(shortName);
@@ -188,7 +206,7 @@ public class SiteServiceImpl implements SiteService, SiteModel
properties.put(SiteModel.PROP_SITE_PRESET, sitePreset);
properties.put(ContentModel.PROP_TITLE, title);
properties.put(ContentModel.PROP_DESCRIPTION, description);
- NodeRef siteNodeRef = this.nodeService.createNode(
+ final NodeRef siteNodeRef = this.nodeService.createNode(
siteParent,
ContentModel.ASSOC_CONTAINS,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, shortName),
@@ -198,21 +216,80 @@ public class SiteServiceImpl implements SiteService, SiteModel
// Make the new site a tag scope
this.taggingService.addTagScope(siteNodeRef);
- // Set the memberhips details
- // - give all authorities read permissions if site is public
- // - give all authorities read permission on permissions so memberships can be calculated
- // - give current user role of site manager
- this.permissionService.setInheritParentPermissions(siteNodeRef, false);
- if (isPublic == true)
- {
- this.permissionService.setPermission(siteNodeRef, PermissionService.ALL_AUTHORITIES, SITE_CONSUMER, true);
- }
- this.permissionService.setPermission(siteNodeRef, PermissionService.ALL_AUTHORITIES, PermissionService.READ_PERMISSIONS, true);
- this.permissionService.setPermission(siteNodeRef, authenticationComponent.getCurrentUserName(), SiteModel.SITE_MANAGER, true);
+ // Clear the sites inherited permissions
+ this.permissionService.setInheritParentPermissions(siteNodeRef, false);
- // Return created site information
- SiteInfo siteInfo = new SiteInfo(sitePreset, shortName, title, description, isPublic, siteNodeRef);
- return siteInfo;
+ // Get the current user
+ final String currentUser = authenticationComponent.getCurrentUserName();
+
+ // Create the relevant groups and assign permissions
+ AuthenticationUtil.runAs(
+ new AuthenticationUtil.RunAsWork