From b9bcb907bcdc7bed73f5a9375e16f75edcff48a6 Mon Sep 17 00:00:00 2001 From: Derek Hulley Date: Wed, 11 Mar 2009 02:20:29 +0000 Subject: [PATCH] Merged V3.1 to HEAD 12991: Merged V3.0 to V3.1 12929: Merged V2.2 to V3.0 12579: Fix ETWOTWO-925: Adding users to a web project is slow due to permission setting 12583: Fix ETWOTWO-925: Added post fix snapshot (follow on from 12579) ___________________________________________________________________ Modified: svn:mergeinfo Merged /alfresco/BRANCHES/V3.0:r12929 Merged /alfresco/BRANCHES/V2.2:r12579,12583 Merged /alfresco/BRANCHES/V3.1:r12991 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@13547 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../messages/patch-service.properties | 3 + .../alfresco/patch/patch-services-context.xml | 50 ++ config/alfresco/version.properties | 2 +- config/alfresco/wcm-services-context.xml | 1 + .../MoveWCMToGroupBasedPermissionsPatch.java | 493 ++++++++++++++++++ .../cmr/security/PermissionService.java | 8 + .../alfresco/wcm/sandbox/SandboxFactory.java | 431 +++++++++------ .../java/org/alfresco/wcm/util/WCMUtil.java | 11 +- 8 files changed, 821 insertions(+), 178 deletions(-) create mode 100644 source/java/org/alfresco/repo/admin/patch/impl/MoveWCMToGroupBasedPermissionsPatch.java diff --git a/config/alfresco/messages/patch-service.properties b/config/alfresco/messages/patch-service.properties index 988869c051..3d03b80c84 100644 --- a/config/alfresco/messages/patch-service.properties +++ b/config/alfresco/messages/patch-service.properties @@ -242,3 +242,6 @@ patch.spacesStoreGuestPermission.description=Sets READ permissions for GUEST on patch.spacesStoreGuestPermission.result=Granted READ permissions for GUEST on root node of the SpacesStore. patch.administratorGroup.description=Adds the 'ALFRESCO_ADMINISTRATORS' group. + +patch.moveWCMToGroupBasedPermissionsPatch.description=Move WCM to group based permissions. +patch.moveWCMToGroupBasedPermissionsPatch.result=WCM moved to group based permissions. diff --git a/config/alfresco/patch/patch-services-context.xml b/config/alfresco/patch/patch-services-context.xml index 2764dab19e..a4c2ef5d89 100644 --- a/config/alfresco/patch/patch-services-context.xml +++ b/config/alfresco/patch/patch-services-context.xml @@ -1598,4 +1598,54 @@ + + patch.moveWCMToGroupBasedPermissionsPatch + patch.moveWCMToGroupBasedPermissionsPatch.description + 0 + 2001 + 2002 + + + + + + + + + + + + + + + + + + ContentManager + + + + + patch.wcmPostPermissionSnapshotPatch2 + patch.wcmPostPermissionSnapshotPatch.description + 0 + 2001 + 2002 + + + + + + + + + + + + + + + + + diff --git a/config/alfresco/version.properties b/config/alfresco/version.properties index 87fd99dcb6..e08741a4f6 100644 --- a/config/alfresco/version.properties +++ b/config/alfresco/version.properties @@ -19,4 +19,4 @@ version.build=@build-number@ # Schema number -version.schema=2001 +version.schema=2002 diff --git a/config/alfresco/wcm-services-context.xml b/config/alfresco/wcm-services-context.xml index 20a5d85e0b..6b9b2cabe2 100644 --- a/config/alfresco/wcm-services-context.xml +++ b/config/alfresco/wcm-services-context.xml @@ -217,6 +217,7 @@ + diff --git a/source/java/org/alfresco/repo/admin/patch/impl/MoveWCMToGroupBasedPermissionsPatch.java b/source/java/org/alfresco/repo/admin/patch/impl/MoveWCMToGroupBasedPermissionsPatch.java new file mode 100644 index 0000000000..3af5b17286 --- /dev/null +++ b/source/java/org/alfresco/repo/admin/patch/impl/MoveWCMToGroupBasedPermissionsPatch.java @@ -0,0 +1,493 @@ +/* + * Copyright (C) 2005-2007 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.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import net.sf.acegisecurity.providers.jaas.AuthorityGranter; + +import org.alfresco.i18n.I18NUtil; +import org.alfresco.model.WCMAppModel; +import org.alfresco.repo.admin.patch.AbstractPatch; +import org.alfresco.repo.avm.AVMNodeConverter; +import org.alfresco.repo.avm.AVMRepository; +import org.alfresco.repo.domain.PropertyValue; +import org.alfresco.repo.domain.hibernate.AclDaoComponentImpl; +import org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor; +import org.alfresco.repo.transaction.RetryingTransactionHelper; +import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; +import org.alfresco.service.cmr.avm.AVMNodeDescriptor; +import org.alfresco.service.cmr.avm.AVMService; +import org.alfresco.service.cmr.avm.AVMStoreDescriptor; +import org.alfresco.service.cmr.dictionary.DataTypeDefinition; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.StoreRef; +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.namespace.QName; +import org.alfresco.service.namespace.RegexQNamePattern; +import org.alfresco.service.transaction.TransactionService; + +/** + * Remove ACLs on all but staging area stores On staging area stores, set ACls according to the users and roles as set + * on the web site Note: runs as the system user + * + * @author andyh + */ +public class MoveWCMToGroupBasedPermissionsPatch extends AbstractPatch +{ + public static final String[] PERMISSIONS = new String[] { PermissionService.WCM_CONTENT_MANAGER, PermissionService.WCM_CONTENT_PUBLISHER, + PermissionService.WCM_CONTENT_CONTRIBUTOR, PermissionService.WCM_CONTENT_REVIEWER }; + + private static final String MSG_SUCCESS = "patch.moveWCMToGroupBasedPermissionsPatch.result"; + + AVMSnapShotTriggeredIndexingMethodInterceptor avmSnapShotTriggeredIndexingMethodInterceptor; + + AVMService avmService; + + PermissionService permissionService; + + AclDaoComponentImpl aclDaoComponent; + + AuthorityService authorityService; + + String replaceAllWith = PermissionService.WCM_CONTENT_MANAGER; + + public void setAvmService(AVMService avmService) + { + this.avmService = avmService; + } + + public void setAvmSnapShotTriggeredIndexingMethodInterceptor(AVMSnapShotTriggeredIndexingMethodInterceptor avmSnapShotTriggeredIndexingMethodInterceptor) + { + this.avmSnapShotTriggeredIndexingMethodInterceptor = avmSnapShotTriggeredIndexingMethodInterceptor; + } + + public void setPermissionService(PermissionService permissionService) + { + this.permissionService = permissionService; + } + + public void setAclDaoComponent(AclDaoComponentImpl aclDaoComponent) + { + this.aclDaoComponent = aclDaoComponent; + } + + public void setAuthorityService(AuthorityService authorityService) + { + this.authorityService = authorityService; + } + + + + public void setReplaceAllWith(String replaceAllWith) + { + this.replaceAllWith = replaceAllWith; + } + + @Override + protected String applyInternal() throws Exception + { + Thread progressThread = null; + if (aclDaoComponent.supportsProgressTracking()) + { + Long toDo = aclDaoComponent.getAVMHeadNodeCount(); + Long maxId = aclDaoComponent.getMaxAclId(); + + progressThread = new Thread(new ProgressWatcher(toDo, maxId), "WCMPactchProgressWatcher"); + progressThread.start(); + } + + List stores = avmService.getStores(); + for (AVMStoreDescriptor store : stores) + { + switch (avmSnapShotTriggeredIndexingMethodInterceptor.getStoreType(store.getName())) + { + /* Set permissions in staging */ + case STAGING: + fixAllPermissions(store); + setStagingAreaPermissions(store); + setStagingAreaMasks(store); + // TODO: mark read only + break; + /* Clear permissions */ + case AUTHOR: + case AUTHOR_PREVIEW: + case AUTHOR_WORKFLOW: + case AUTHOR_WORKFLOW_PREVIEW: + fixAllStagingPermissions(store); + setSandBoxMasks(store); + break; + case STAGING_PREVIEW: + fixAllStagingPermissions(store); + setStagingAreaMasks(store); + // TODO: mark read only + break; + case WORKFLOW: + case WORKFLOW_PREVIEW: + break; + /* non WCM stores - nothing to do */ + case UNKNOWN: + default: + } + } + + if (progressThread != null) + { + progressThread.interrupt(); + progressThread.join(); + } + + // build the result message + String msg = I18NUtil.getMessage(MSG_SUCCESS); + // done + return msg; + } + + private boolean isPermissionSet(NodeRef nodeRef, String authority, String permission) + { + Set set = permissionService.getAllSetPermissions(nodeRef); + for (AccessPermission ap : set) + { + if (ap.getAuthority().equals(authority) && ap.isSetDirectly() && ap.getPermission().equals(permission)) + { + return true; + } + } + return false; + } + + private boolean isMaskSet(StoreRef storeRef, String authority, String permission) + { + Set set = permissionService.getAllSetPermissions(storeRef); + for (AccessPermission ap : set) + { + if (ap.getAuthority().equals(authority) && ap.isSetDirectly() && ap.getPermission().equals(permission)) + { + return true; + } + } + return false; + } + + private void makeGroupsIfRequired(String stagingStoreName, NodeRef dirRef) + { + for (String permission : PERMISSIONS) + { + String shortName = stagingStoreName + "-" + permission; + String group = authorityService.getName(AuthorityType.GROUP, shortName); + if (!authorityService.authorityExists(group)) + { + String newGroup = authorityService.createAuthority(AuthorityType.GROUP, null, shortName); + permissionService.setPermission(dirRef, newGroup, permission, true); + } + } + } + + private void addToGroupIfRequired(String stagingStoreName, String user, String permission) + { + String shortName = stagingStoreName + "-" + permission; + String group = authorityService.getName(AuthorityType.GROUP, shortName); + Set members = authorityService.getContainedAuthorities(AuthorityType.USER, group, true); + if (!members.contains(user)) + { + authorityService.addAuthority(group, user); + } + } + + private void fixAllPermissions(AVMStoreDescriptor store) + { + fixAllPermissionsImpl(store.getName()); + } + + private void fixAllStagingPermissions(AVMStoreDescriptor store) + { + + String stagingAreaName = extractStagingAreaName(store.getName()); + fixAllPermissionsImpl(stagingAreaName); + } + + private void fixAllPermissionsImpl(String stagingStoreName) + { + QName propQName = QName.createQName(null, ".web_project.noderef"); + + PropertyValue pValue = avmService.getStoreProperty(stagingStoreName, propQName); + + if (pValue != null) + { + NodeRef webProjectNodeRef = (NodeRef) pValue.getValue(DataTypeDefinition.NODE_REF); + + // Apply sepcific user permissions as set on the web project + List userInfoRefs = nodeService.getChildAssocs(webProjectNodeRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); + for (ChildAssociationRef ref : userInfoRefs) + { + NodeRef userInfoRef = ref.getChildRef(); + String username = (String) nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME); + String userrole = (String) nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE); + + if (userrole.equals(PermissionService.ALL_PERMISSIONS)) + { + nodeService.setProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE, replaceAllWith); + } + + } + } + } + + private void setStagingAreaPermissions(AVMStoreDescriptor store) + { + QName propQName = QName.createQName(null, ".web_project.noderef"); + + NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, store.getName() + ":/www"); + + makeGroupsIfRequired(store.getName(), dirRef); + + if (!isPermissionSet(dirRef, PermissionService.ALL_AUTHORITIES, PermissionService.READ)) + { + permissionService.setPermission(dirRef, PermissionService.ALL_AUTHORITIES, PermissionService.READ, true); + } + + // Add group permissions + for (String permission : PERMISSIONS) + { + String cms = authorityService.getName(AuthorityType.GROUP, store.getName() + "-" + permission); + permissionService.setPermission(dirRef, cms, permission, true); + } + + PropertyValue pValue = avmService.getStoreProperty(store.getName(), propQName); + + if (pValue != null) + { + NodeRef webProjectNodeRef = (NodeRef) pValue.getValue(DataTypeDefinition.NODE_REF); + + // Apply sepcific user permissions as set on the web project + List userInfoRefs = nodeService.getChildAssocs(webProjectNodeRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); + for (ChildAssociationRef ref : userInfoRefs) + { + NodeRef userInfoRef = ref.getChildRef(); + String username = (String) nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME); + String userrole = (String) nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE); + + // remove existing + + if (isPermissionSet(dirRef, username, userrole)) + { + permissionService.deletePermission(dirRef, username, userrole); + } + + addToGroupIfRequired(store.getName(), username, userrole); + } + } + } + + private void setStagingAreaMasks(AVMStoreDescriptor store) + { + // groups must exist + NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, store.getName() + ":/www"); + + if (!isMaskSet(dirRef.getStoreRef(), PermissionService.ALL_AUTHORITIES, PermissionService.READ)) + { + permissionService.setPermission(dirRef.getStoreRef(), PermissionService.ALL_AUTHORITIES, PermissionService.READ, true); + } + + String cms = authorityService.getName(AuthorityType.GROUP, store.getName() + "-" + PermissionService.WCM_CONTENT_MANAGER); + if (!isMaskSet(dirRef.getStoreRef(), cms, PermissionService.CHANGE_PERMISSIONS)) + { + permissionService.setPermission(dirRef.getStoreRef(), cms, PermissionService.CHANGE_PERMISSIONS, true); + } + + if (!isMaskSet(dirRef.getStoreRef(), cms, PermissionService.READ_PERMISSIONS)) + { + permissionService.setPermission(dirRef.getStoreRef(), cms, PermissionService.READ_PERMISSIONS, true); + } + + QName propQName = QName.createQName(null, ".web_project.noderef"); + + PropertyValue pValue = avmService.getStoreProperty(store.getName(), propQName); + + if (pValue != null) + { + NodeRef webProjectNodeRef = (NodeRef) pValue.getValue(DataTypeDefinition.NODE_REF); + + // Apply sepcific user permissions as set on the web project + List userInfoRefs = nodeService.getChildAssocs(webProjectNodeRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); + for (ChildAssociationRef ref : userInfoRefs) + { + NodeRef userInfoRef = ref.getChildRef(); + String username = (String) nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME); + String userrole = (String) nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE); + + if (userrole.equals(PermissionService.WCM_CONTENT_MANAGER)) + { + // remove existing + + if (isMaskSet(dirRef.getStoreRef(), username, PermissionService.CHANGE_PERMISSIONS)) + { + permissionService.deletePermission(dirRef.getStoreRef(), username, PermissionService.CHANGE_PERMISSIONS); + } + + if (isMaskSet(dirRef.getStoreRef(), username, PermissionService.READ_PERMISSIONS)) + { + permissionService.deletePermission(dirRef.getStoreRef(), username, PermissionService.READ_PERMISSIONS); + } + } + } + } + + } + + private void setSandBoxMasks(AVMStoreDescriptor sandBoxStore) + { + // get the settings from the staging store ... + + String owner = extractOwner(sandBoxStore.getName()); + String stagingAreaName = extractStagingAreaName(sandBoxStore.getName()); + + QName propQName = QName.createQName(null, ".web_project.noderef"); + + NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, sandBoxStore.getName() + ":/www"); + + Map woof = avmService.getStoreProperties(stagingAreaName); + PropertyValue pValue = avmService.getStoreProperty(stagingAreaName, propQName); + + if (!isMaskSet(dirRef.getStoreRef(), PermissionService.ALL_AUTHORITIES, PermissionService.READ)) + { + permissionService.setPermission(dirRef.getStoreRef(), PermissionService.ALL_AUTHORITIES, PermissionService.READ, true); + } + + String cms = authorityService.getName(AuthorityType.GROUP, stagingAreaName + "-" + PermissionService.WCM_CONTENT_MANAGER); + if (!isMaskSet(dirRef.getStoreRef(), cms, PermissionService.WCM_CONTENT_MANAGER)) + { + permissionService.setPermission(dirRef.getStoreRef(), cms, PermissionService.WCM_CONTENT_MANAGER, true); + } + + if (pValue != null) + { + NodeRef webProjectNodeRef = (NodeRef) pValue.getValue(DataTypeDefinition.NODE_REF); + + // Apply sepcific user permissions as set on the web project + List userInfoRefs = nodeService.getChildAssocs(webProjectNodeRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); + for (ChildAssociationRef ref : userInfoRefs) + { + NodeRef userInfoRef = ref.getChildRef(); + String username = (String) nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME); + String userrole = (String) nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE); + + if (username.equals(owner)) + { + permissionService.setPermission(dirRef.getStoreRef(), username, PermissionService.ALL_PERMISSIONS, true); + } + else if (userrole.equals("ContentManager")) + { + if (isMaskSet(dirRef.getStoreRef(), username, userrole)) + { + permissionService.deletePermission(dirRef.getStoreRef(), username, userrole); + } + } + } + } + } + + private String extractOwner(String name) + { + int start = name.indexOf("--"); + if (start == -1) + { + throw new UnsupportedOperationException(name); + } + int end = name.indexOf("--", start + 1); + if (end == -1) + { + return name.substring(start + 2); + } + return name.substring(start + 2, end); + } + + private String extractStagingAreaName(String name) + { + int index = name.indexOf("--"); + if (index == -1) + { + throw new UnsupportedOperationException(name); + } + return name.substring(0, index); + } + + private class ProgressWatcher implements Runnable + { + private boolean running = true; + + Long toDo; + + Long max; + + ProgressWatcher(Long toDo, Long max) + { + this.toDo = toDo; + this.max = max; + } + + public void run() + { + while (running) + { + try + { + Thread.sleep(60000); + } + catch (InterruptedException e) + { + running = false; + } + + if (running) + { + RetryingTransactionHelper txHelper = transactionService.getRetryingTransactionHelper(); + txHelper.setMaxRetries(1); + Long done = txHelper.doInTransaction(new RetryingTransactionCallback() + { + + public Long execute() throws Throwable + { + return aclDaoComponent.getAVMNodeCountWithNewACLS(max); + } + }, true, true); + + reportProgress(toDo, done); + } + } + } + + } +} diff --git a/source/java/org/alfresco/service/cmr/security/PermissionService.java b/source/java/org/alfresco/service/cmr/security/PermissionService.java index 5f5065268c..a6ea19eb29 100644 --- a/source/java/org/alfresco/service/cmr/security/PermissionService.java +++ b/source/java/org/alfresco/service/cmr/security/PermissionService.java @@ -155,6 +155,14 @@ public interface PermissionService public static final String PROPERTIES = "Properties"; + public static final String WCM_CONTENT_MANAGER = "ContentManager"; + + public static final String WCM_CONTENT_PUBLISHER = "ContentPublisher"; + + public static final String WCM_CONTENT_CONTRIBUTOR = "ContentContributor"; + + public static final String WCM_CONTENT_REVIEWER = "ContentReviewer"; + /** * Get the Owner Authority * diff --git a/source/java/org/alfresco/wcm/sandbox/SandboxFactory.java b/source/java/org/alfresco/wcm/sandbox/SandboxFactory.java index 5af355db80..15087fa7d0 100644 --- a/source/java/org/alfresco/wcm/sandbox/SandboxFactory.java +++ b/source/java/org/alfresco/wcm/sandbox/SandboxFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2008 Alfresco Software Limited. + * Copyright (C) 2005-2009 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 @@ -26,6 +26,7 @@ package org.alfresco.wcm.sandbox; import java.util.ArrayList; import java.util.Date; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -43,6 +44,10 @@ import org.alfresco.service.cmr.avm.locking.AVMLockingService; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.StoreRef; +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.namespace.QName; import org.alfresco.util.DNSNameMangler; @@ -60,6 +65,12 @@ import org.apache.commons.logging.LogFactory; */ public final class SandboxFactory extends WCMUtil { + public static final String[] PERMISSIONS = new String[] { + PermissionService.WCM_CONTENT_MANAGER, + PermissionService.WCM_CONTENT_PUBLISHER, + PermissionService.WCM_CONTENT_CONTRIBUTOR, + PermissionService.WCM_CONTENT_REVIEWER }; + private static Log logger = LogFactory.getLog(SandboxFactory.class); /** Services */ @@ -68,6 +79,7 @@ public final class SandboxFactory extends WCMUtil private AVMService avmService; private AVMLockingService avmLockingService; private VirtServerRegistry virtServerRegistry; + private AuthorityService authorityService; public void setNodeService(NodeService nodeService) { @@ -94,6 +106,10 @@ public final class SandboxFactory extends WCMUtil this.virtServerRegistry = virtServerRegistry; } + public void setAuthorityService(AuthorityService authorityService) + { + this.authorityService = authorityService; + } /** * Private constructor @@ -307,11 +323,12 @@ public final class SandboxFactory extends WCMUtil return new SandboxInfoImpl(wpStoreId, sandboxId, sandboxType, name, storeNames, new Date(storeDesc.getCreateDate()), storeDesc.getCreator()); } - protected void setStagingPermissions(String storeId, NodeRef wpNodeRef) + private void setStagingPermissions(String storeId, NodeRef wpNodeRef) { String storeName = WCMUtil.buildStagingStoreName(storeId); NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, WCMUtil.buildStoreRootPath(storeName)); - + + makeGroupsIfRequired(storeName, dirRef); // Apply specific user permissions as set on the web project // All these will be masked out @@ -322,8 +339,110 @@ public final class SandboxFactory extends WCMUtil String username = userRole.getKey(); String userrole = userRole.getValue(); - permissionService.setPermission(dirRef, username, userrole, true); + // permissionService.setPermission(dirRef, username, userrole, true); + addToGroupIfRequired(storeName, username, userrole); } + + // Add group permissions + for (String permission : PERMISSIONS) + { + String cms = authorityService.getName(AuthorityType.GROUP, storeName + "-" + permission); + permissionService.setPermission(dirRef, cms, permission, true); + } + + // TODO: does everyone get read writes? + permissionService.setPermission(dirRef, PermissionService.ALL_AUTHORITIES, PermissionService.READ, true); + } + + private void makeGroupsIfRequired(final String stagingStoreName, final NodeRef dirRef) + { + AuthenticationUtil.runAs(new RunAsWork(){ + + public Object doWork() throws Exception + { + for (String permission : PERMISSIONS) + { + String shortName = stagingStoreName + "-" + permission; + String group = authorityService.getName(AuthorityType.GROUP, shortName); + if (!authorityService.authorityExists(group)) + { + authorityService.createAuthority(AuthorityType.GROUP, null, shortName); + } + if (!isPermissionSet(dirRef, group, permission)) + { + permissionService.setPermission(dirRef, group, permission, true); + } + } + return null; + }}, AuthenticationUtil.getSystemUserName()); + } + + private boolean isPermissionSet(NodeRef nodeRef, String authority, String permission) + { + Set set = permissionService.getAllSetPermissions(nodeRef); + for (AccessPermission ap : set) + { + if (ap.getAuthority().equals(authority) && ap.isSetDirectly() && ap.getPermission().equals(permission)) + { + return true; + } + } + return false; + } + + private void addToGroupIfRequired(final String stagingStoreName, final String user, final String permission) + { + AuthenticationUtil.runAs(new RunAsWork(){ + + public Object doWork() throws Exception + { + String shortName = stagingStoreName + "-" + permission; + String group = authorityService.getName(AuthorityType.GROUP, shortName); + if (!authorityService.authorityExists(group)) + { + authorityService.createAuthority(AuthorityType.GROUP, null, shortName); + } + Set members = authorityService.getContainedAuthorities(AuthorityType.USER, group, true); + if (!members.contains(user)) + { + authorityService.addAuthority(group, user); + } + return null; + }}, AuthenticationUtil.getSystemUserName()); + + } + + private void removeFromGroupIfRequired(final String stagingStoreName, final String user, final String permission) + { + AuthenticationUtil.runAs(new RunAsWork(){ + + public Object doWork() throws Exception + { + String shortName = stagingStoreName + "-" + permission; + String group = authorityService.getName(AuthorityType.GROUP, shortName); + if (authorityService.authorityExists(group)) + { + Set members = authorityService.getContainedAuthorities(AuthorityType.USER, group, true); + if (members.contains(user)) + { + authorityService.removeAuthority(group, user); + } + } + return null; + }}, AuthenticationUtil.getSystemUserName()); + } + + private boolean isMaskSet(StoreRef storeRef, String authority, String permission) + { + Set set = permissionService.getAllSetPermissions(storeRef); + for (AccessPermission ap : set) + { + if (ap.getAuthority().equals(authority) && ap.isSetDirectly() && ap.getPermission().equals(permission)) + { + return true; + } + } + return false; } public void setStagingPermissionMasks(String storeId) @@ -333,39 +452,73 @@ public final class SandboxFactory extends WCMUtil // Set store permission masks String currentUser = AuthenticationUtil.getFullyAuthenticatedUser(); - permissionService.setPermission(dirRef.getStoreRef(), currentUser, PermissionService.CHANGE_PERMISSIONS, true); - permissionService.setPermission(dirRef.getStoreRef(), currentUser, PermissionService.READ_PERMISSIONS, true); - permissionService.setPermission(dirRef.getStoreRef(), PermissionService.ALL_AUTHORITIES, PermissionService.READ, true); - - // apply READ permissions for all users - permissionService.setPermission(dirRef, PermissionService.ALL_AUTHORITIES, PermissionService.READ, true); + addToGroupIfRequired(storeName, currentUser, PermissionService.WCM_CONTENT_MANAGER); + + String cms = authorityService.getName(AuthorityType.GROUP, storeName + "-" + PermissionService.WCM_CONTENT_MANAGER); + + // read early or the mask prevents access... + boolean setReadPermissions = !isMaskSet(dirRef.getStoreRef(), cms, PermissionService.READ_PERMISSIONS); + + if (!isMaskSet(dirRef.getStoreRef(), cms, PermissionService.CHANGE_PERMISSIONS)) + { + permissionService.setPermission(dirRef.getStoreRef(), cms, PermissionService.CHANGE_PERMISSIONS, true); + } + + if (setReadPermissions) + { + permissionService.setPermission(dirRef.getStoreRef(), cms, PermissionService.READ_PERMISSIONS, true); + } + + if (!isMaskSet(dirRef.getStoreRef(), PermissionService.ALL_AUTHORITIES, PermissionService.READ)) + { + permissionService.setPermission(dirRef.getStoreRef(), PermissionService.ALL_AUTHORITIES, PermissionService.READ, true); + } } + + /* + private Set getGroupMembers(String stagingStoreName, String permission) + { + String shortName = stagingStoreName + "-" + permission; + String group = authorityService.getName(AuthorityType.GROUP, shortName); + Set members = authorityService.getContainedAuthorities(AuthorityType.USER, group, true); + return members; + + } + */ private void updateStagingAreaManagers(String storeId, final List managers) { // The stores have the mask set in updateSandboxManagers String storeName = WCMUtil.buildStagingStoreName(storeId); - - NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, WCMUtil.buildStoreRootPath(storeName)); + + // Set existingMembers = getGroupMembers(storeName, PermissionService.WCM_CONTENT_MANAGER); + + String shortName = storeName + "-" + PermissionService.WCM_CONTENT_MANAGER; + String group = authorityService.getName(AuthorityType.GROUP, shortName); + Set members = authorityService.getContainedAuthorities(AuthorityType.USER, group, true); + Set toRemove = new HashSet(members); + for (String manager : managers) { - permissionService.setPermission(dirRef, manager, WCMUtil.ROLE_CONTENT_MANAGER, true); - - // give the manager change permissions permission in the staging area store - permissionService.setPermission(dirRef.getStoreRef(), manager, - PermissionService.CHANGE_PERMISSIONS, true); - permissionService.setPermission(dirRef.getStoreRef(), manager, - PermissionService.READ_PERMISSIONS, true); + addToGroupIfRequired(storeName, manager, PermissionService.WCM_CONTENT_MANAGER); + toRemove.remove(manager); + } + + for (String remove : toRemove) + { + removeFromGroupIfRequired(storeName, remove, PermissionService.WCM_CONTENT_MANAGER); } } - public void addStagingAreaUser(String wpStoreId, String authority, String role) + public void addStagingAreaUser(String storeId, String authority, String role) { // The stores have the mask set in updateSandboxManagers - String storeName = WCMUtil.buildStagingStoreName(wpStoreId); - - NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, WCMUtil.buildStoreRootPath(storeName)); - permissionService.setPermission(dirRef, authority, role, true); + + //String storeName = WCMUtil.buildStagingStoreName(storeId); + //NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, WCMUtil.buildStoreRootPath(storeName)); + + addToGroupIfRequired(storeId, authority, role); + // permissionService.setPermission(dirRef, authority, role, true); } /** @@ -424,14 +577,18 @@ public final class SandboxFactory extends WCMUtil // apply the user role permissions to the sandbox String currentUser = AuthenticationUtil.getFullyAuthenticatedUser(); - permissionService.setPermission(dirRef.getStoreRef(), currentUser, WCMUtil.ROLE_CONTENT_MANAGER, true); + // permissionService.setPermission(dirRef.getStoreRef(), currentUser, AVMUtil.ROLE_CONTENT_MANAGER, true); + addToGroupIfRequired(stagingStoreName, currentUser, PermissionService.WCM_CONTENT_MANAGER); + String cms = authorityService.getName(AuthorityType.GROUP, stagingStoreName + "-" + PermissionService.WCM_CONTENT_MANAGER); + permissionService.setPermission(dirRef.getStoreRef(), cms, PermissionService.WCM_CONTENT_MANAGER, true); + permissionService.setPermission(dirRef.getStoreRef(), username, PermissionService.ALL_PERMISSIONS, true); permissionService.setPermission(dirRef.getStoreRef(), PermissionService.ALL_AUTHORITIES, PermissionService.READ, true); // apply the manager role permission for each manager in the web project - for (String manager : managers) - { - permissionService.setPermission(dirRef.getStoreRef(), manager, WCMUtil.ROLE_CONTENT_MANAGER, true); - } + // for (String manager : managers) + // { + // permissionService.setPermission(dirRef.getStoreRef(), manager, AVMUtil.ROLE_CONTENT_MANAGER, true); + // } // tag the store with the store type avmService.setStoreProperty(userStoreName, @@ -541,11 +698,11 @@ public final class SandboxFactory extends WCMUtil */ public SandboxInfo createWorkflowSandbox(final String storeId) { - final String stagingStoreName = WCMUtil.buildStagingStoreName(storeId); + String stagingStoreName = WCMUtil.buildStagingStoreName(storeId); // create the workflow 'main' store - final String packageName = WCMUtil.STORE_WORKFLOW + "-" + GUID.generate(); - final String mainStoreName = WCMUtil.buildWorkflowMainStoreName(storeId, packageName); + String packageName = WCMUtil.STORE_WORKFLOW + "-" + GUID.generate(); + String mainStoreName = WCMUtil.buildWorkflowMainStoreName(storeId, packageName); avmService.createStore(mainStoreName); @@ -665,16 +822,18 @@ public final class SandboxFactory extends WCMUtil */ public SandboxInfo createReadOnlyWorkflowSandbox(final String storeId) { - final String stagingStoreName = WCMUtil.buildStagingStoreName(storeId); + String stagingStoreName = WCMUtil.buildStagingStoreName(storeId); // create the workflow 'main' store - final String packageName = WCMUtil.STORE_WORKFLOW + "-" + GUID.generate(); - final String mainStoreName = - WCMUtil.buildWorkflowMainStoreName(storeId, packageName); + String packageName = WCMUtil.STORE_WORKFLOW + "-" + GUID.generate(); + String mainStoreName = WCMUtil.buildWorkflowMainStoreName(storeId, packageName); avmService.createStore(mainStoreName); + if (logger.isDebugEnabled()) + { logger.debug("Created read-only workflow sandbox store: " + mainStoreName); + } // create a layered directory pointing to 'www' in the staging area avmService.createLayeredDirectory(WCMUtil.buildStoreRootPath(stagingStoreName), @@ -734,28 +893,30 @@ public final class SandboxFactory extends WCMUtil String packageName = "workflow-" + GUID.generate(); String workflowStoreName = userStore + STORE_SEPARATOR + packageName; - this.avmService.createStore(workflowStoreName); + avmService.createStore(workflowStoreName); if (logger.isDebugEnabled()) + { logger.debug("Created user workflow sandbox store: " + workflowStoreName); + } // create a layered directory pointing to 'www' in the users store - this.avmService.createLayeredDirectory( + avmService.createLayeredDirectory( userStore + ":/" + JNDIConstants.DIR_DEFAULT_WWW, workflowStoreName + ":/", JNDIConstants.DIR_DEFAULT_WWW); // tag the store with the store type - this.avmService.setStoreProperty(workflowStoreName, + avmService.setStoreProperty(workflowStoreName, SandboxConstants.PROP_SANDBOX_AUTHOR_WORKFLOW_MAIN, new PropertyValue(DataTypeDefinition.TEXT, null)); // tag the store with the name of the author's store this one is layered over - this.avmService.setStoreProperty(workflowStoreName, + avmService.setStoreProperty(workflowStoreName, SandboxConstants.PROP_AUTHOR_NAME, new PropertyValue(DataTypeDefinition.TEXT, userStore)); // tag the store, oddly enough, with its own store name for querying. - this.avmService.setStoreProperty(workflowStoreName, + avmService.setStoreProperty(workflowStoreName, QName.createQName(null, SandboxConstants.PROP_SANDBOX_STORE_PREFIX + workflowStoreName), new PropertyValue(DataTypeDefinition.TEXT, null)); @@ -764,7 +925,7 @@ public final class SandboxFactory extends WCMUtil "/" + JNDIConstants.DIR_DEFAULT_APPBASE; // DNS name mangle the property name - can only contain value DNS characters! String dnsProp = SandboxConstants.PROP_DNS + DNSNameMangler.MakeDNSName(stagingStore, packageName); - this.avmService.setStoreProperty(workflowStoreName, QName.createQName(null, dnsProp), + avmService.setStoreProperty(workflowStoreName, QName.createQName(null, dnsProp), new PropertyValue(DataTypeDefinition.TEXT, path)); // TODO review above and replace with common call to ... @@ -775,31 +936,33 @@ public final class SandboxFactory extends WCMUtil // the main workflow store depends on the main user store (dist=1) String prop_key = SandboxConstants.PROP_BACKGROUND_LAYER + userStore; - this.avmService.setStoreProperty(workflowStoreName, QName.createQName(null, prop_key), + avmService.setStoreProperty(workflowStoreName, QName.createQName(null, prop_key), new PropertyValue(DataTypeDefinition.INT, 1)); // The main workflow store depends on the main staging store (dist=2) prop_key = SandboxConstants.PROP_BACKGROUND_LAYER + stagingStore; - this.avmService.setStoreProperty(workflowStoreName, QName.createQName(null, prop_key), + avmService.setStoreProperty(workflowStoreName, QName.createQName(null, prop_key), new PropertyValue(DataTypeDefinition.INT, 2)); // snapshot the store - this.avmService.createSnapshot(workflowStoreName, null, null); + avmService.createSnapshot(workflowStoreName, null, null); // create the workflow 'preview' store String previewStoreName = workflowStoreName + STORE_SEPARATOR + "preview"; - this.avmService.createStore(previewStoreName); + avmService.createStore(previewStoreName); if (logger.isDebugEnabled()) + { logger.debug("Created user workflow sandbox preview store: " + previewStoreName); + } // create a layered directory pointing to 'www' in the workflow 'main' store - this.avmService.createLayeredDirectory( + avmService.createLayeredDirectory( workflowStoreName + ":/" + JNDIConstants.DIR_DEFAULT_WWW, previewStoreName + ":/", JNDIConstants.DIR_DEFAULT_WWW); // tag the store with the store type - this.avmService.setStoreProperty(previewStoreName, SandboxConstants.PROP_SANDBOX_WORKFLOW_PREVIEW, + avmService.setStoreProperty(previewStoreName, SandboxConstants.PROP_SANDBOX_WORKFLOW_PREVIEW, new PropertyValue(DataTypeDefinition.TEXT, null)); // tag the store with its own store name for querying. @@ -812,7 +975,7 @@ public final class SandboxFactory extends WCMUtil "/" + JNDIConstants.DIR_DEFAULT_APPBASE; // DNS name mangle the property name - can only contain value DNS characters! dnsProp = SandboxConstants.PROP_DNS + DNSNameMangler.MakeDNSName(userStore, packageName, "preview"); - this.avmService.setStoreProperty(previewStoreName, QName.createQName(null, dnsProp), + avmService.setStoreProperty(previewStoreName, QName.createQName(null, dnsProp), new PropertyValue(DataTypeDefinition.TEXT, path)); // TODO review above and replace with common call to ... @@ -823,27 +986,27 @@ public final class SandboxFactory extends WCMUtil // The preview worfkflow store depends on the main workflow store (dist=1) prop_key = SandboxConstants.PROP_BACKGROUND_LAYER + workflowStoreName; - this.avmService.setStoreProperty(previewStoreName, QName.createQName(null, prop_key), + avmService.setStoreProperty(previewStoreName, QName.createQName(null, prop_key), new PropertyValue(DataTypeDefinition.INT, 1)); // The preview workflow store depends on the main user store (dist=2) prop_key = SandboxConstants.PROP_BACKGROUND_LAYER + userStore; - this.avmService.setStoreProperty(previewStoreName, QName.createQName(null, prop_key), + avmService.setStoreProperty(previewStoreName, QName.createQName(null, prop_key), new PropertyValue(DataTypeDefinition.INT, 2)); // The preview workflow store depends on the main staging store (dist=3) prop_key = SandboxConstants.PROP_BACKGROUND_LAYER + stagingStore; - this.avmService.setStoreProperty(previewStoreName, QName.createQName(null, prop_key), + avmService.setStoreProperty(previewStoreName, QName.createQName(null, prop_key), new PropertyValue(DataTypeDefinition.INT, 3)); // snapshot the store - this.avmService.createSnapshot(previewStoreName, null, null); + avmService.createSnapshot(previewStoreName, null, null); // tag all related stores to indicate that they are part of a single sandbox QName sandboxIdProp = QName.createQName(SandboxConstants.PROP_SANDBOXID + GUID.generate()); - this.avmService.setStoreProperty(workflowStoreName, sandboxIdProp, + avmService.setStoreProperty(workflowStoreName, sandboxIdProp, new PropertyValue(DataTypeDefinition.TEXT, null)); - this.avmService.setStoreProperty(previewStoreName, sandboxIdProp, + avmService.setStoreProperty(previewStoreName, sandboxIdProp, new PropertyValue(DataTypeDefinition.TEXT, null)); // return the main workflow store name @@ -932,27 +1095,21 @@ public final class SandboxFactory extends WCMUtil } } - public void updateSandboxManagers(final String wpStoreId, List managers) + /** + * Update the permissions for the list of sandbox managers applied to a user sandbox. + *

+ * Ensures that all managers in the list have full WRITE access to the specified user stores. + * + * @param storeId + * The store id of the sandbox to update + * @param managers + * The list of authorities who have ContentManager role in the web project + */ + public void updateSandboxManagers(final String storeId, final List managers) { - // walk existing user sandboxes and reapply manager permissions to include new managers - List sbInfos = AuthenticationUtil.runAs(new RunAsWork>() - { - public List doWork() throws Exception - { - return listSandboxes(wpStoreId, AuthenticationUtil.getSystemUserName()); - } - }, AuthenticationUtil.getSystemUserName()); - - for (SandboxInfo sbInfo : sbInfos) - { - if (sbInfo.getSandboxType().equals(SandboxConstants.PROP_SANDBOX_AUTHOR_MAIN)) - { - String username = sbInfo.getName(); - updateUserSandboxManagers(wpStoreId, managers, username); - } - } - - updateStagingAreaManagers(wpStoreId, managers); + String stagingStoreName = WCMUtil.buildStagingStoreName(storeId); + + updateStagingAreaManagers(stagingStoreName, managers); } /** @@ -960,75 +1117,16 @@ public final class SandboxFactory extends WCMUtil *

* Ensures that all managers in the list have full WRITE access to the specified user stores. * - * @param storeId The store id of the sandbox to update - * @param managers The list of authorities who have ContentManager role in the web project - * @param username Username of the user sandbox to update + * @param storeId + * The store id of the sandbox to update + * @param managers + * The list of authorities who have ContentManager role in the web project */ - private void updateUserSandboxManagers(final String storeId, final List managers, final String username) + public void removeSandboxManagers(String storeId, List managersToRemove) { - final String userStoreName = WCMUtil.buildUserMainStoreName(storeId, username); - final String previewStoreName = WCMUtil.buildUserPreviewStoreName(storeId, username); - - // Apply masks to the stores - - // apply the manager role permission to the user main sandbox for each manager - NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, WCMUtil.buildStoreRootPath(userStoreName)); - for (String manager : managers) - { - permissionService.setPermission(dirRef.getStoreRef(), manager, WCMUtil.ROLE_CONTENT_MANAGER, true); - } - - // apply the manager role permission to the user preview sandbox for each manager - dirRef = AVMNodeConverter.ToNodeRef(-1, WCMUtil.buildStoreRootPath(previewStoreName)); - for (String manager : managers) - { - permissionService.setPermission(dirRef.getStoreRef(), manager, WCMUtil.ROLE_CONTENT_MANAGER, true); - } + removeStagingAreaManagers(storeId, managersToRemove); } - public void removeSandboxManagers(final String wpStoreId, List managers) - { - // walk existing user sandboxes and remove manager permissions to exclude old managers - List sbInfos = AuthenticationUtil.runAs(new RunAsWork>() - { - public List doWork() throws Exception - { - return listSandboxes(wpStoreId, AuthenticationUtil.getSystemUserName()); - } - }, AuthenticationUtil.getSystemUserName()); - - for (SandboxInfo sbInfo : sbInfos) - { - if (sbInfo.getSandboxType().equals(SandboxConstants.PROP_SANDBOX_AUTHOR_MAIN)) - { - String username = sbInfo.getName(); - removeUserSandboxManagers(wpStoreId, managers, username); - } - } - - removeStagingAreaManagers(wpStoreId, managers); - } - - /** - * Removes the permissions for the list of sandbox ex-managers. - * - * @param storeId The store id of the sandbox to update - * @param managersToRemove The list of authorities who have had ContentManager role in the web project - * @param username Username of the user sandbox to update - */ - private void removeUserSandboxManagers(String storeId, List managersToRemove, String username) - { - final String userStoreName = WCMUtil.buildUserMainStoreName(storeId, username); - final String previewStoreName = WCMUtil.buildUserPreviewStoreName(storeId, username); - - final NodeRef mainDirRef = AVMNodeConverter.ToNodeRef(-1, WCMUtil.buildStoreRootPath(userStoreName)); - final NodeRef previewDirRef = AVMNodeConverter.ToNodeRef(-1, WCMUtil.buildStoreRootPath(previewStoreName)); - for (String manager : managersToRemove) - { - permissionService.deletePermission(mainDirRef.getStoreRef(), manager, WCMUtil.ROLE_CONTENT_MANAGER); - permissionService.deletePermission(previewDirRef.getStoreRef(), manager, WCMUtil.ROLE_CONTENT_MANAGER); - } - } /** * Removes the ContentManager role on staging area to ex-managers. * @@ -1037,19 +1135,12 @@ public final class SandboxFactory extends WCMUtil */ private void removeStagingAreaManagers(String storeId, List managersToRemove) { - final String storeName = WCMUtil.buildStagingStoreName(storeId); - - final NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, WCMUtil.buildStoreRootPath(storeName)); - for (String manager : managersToRemove) + String storeName = WCMUtil.buildStagingStoreName(storeId); + + for (String remove : managersToRemove) { - permissionService.deletePermission(dirRef, manager, WCMUtil.ROLE_CONTENT_MANAGER); - - permissionService.deletePermission(dirRef.getStoreRef(), manager, - PermissionService.CHANGE_PERMISSIONS); - permissionService.deletePermission(dirRef.getStoreRef(), manager, - PermissionService.READ_PERMISSIONS); + removeFromGroupIfRequired(storeName, remove, PermissionService.WCM_CONTENT_MANAGER); } - } public void updateSandboxRoles(final String wpStoreId, List usersToUpdate, Set permissionsList) @@ -1085,11 +1176,7 @@ public final class SandboxFactory extends WCMUtil */ private void updateUserSandboxRole(String storeId, String username, List usersToUpdate, Set permissionsList) { - final String userStoreName = WCMUtil.buildUserMainStoreName(storeId, username); - final String previewStoreName = WCMUtil.buildUserPreviewStoreName(storeId, username); - - final NodeRef mainDirRef = AVMNodeConverter.ToNodeRef(-1, WCMUtil.buildStoreRootPath(userStoreName)); - final NodeRef previewDirRef = AVMNodeConverter.ToNodeRef(-1, WCMUtil.buildStoreRootPath(previewStoreName)); + final String storeName = WCMUtil.buildStagingStoreName(storeId); // If permissionsList is set remove all possible user permissions and set only necessary. // This will fix previous wrong role changes. (paranoid) @@ -1101,22 +1188,18 @@ public final class SandboxFactory extends WCMUtil { for (String permission : permissionsList) { - permissionService.deletePermission(mainDirRef, user.getUserAuth(), permission); - permissionService.deletePermission(previewDirRef, user.getUserAuth(), permission); + removeFromGroupIfRequired(storeName, user.getUserAuth(), permission); } - - permissionService.setPermission(mainDirRef, user.getUserAuth(), user.getNewRole(), true); - permissionService.setPermission(previewDirRef, user.getUserAuth(), user.getNewRole(), true); + + addToGroupIfRequired(storeName, user.getUserAuth(), user.getNewRole()); } } else { - for (UserRoleWrapper user: usersToUpdate) + for (UserRoleWrapper user : usersToUpdate) { - permissionService.deletePermission(mainDirRef, user.getUserAuth(), user.getOldRole()); - permissionService.deletePermission(previewDirRef, user.getUserAuth(), user.getOldRole()); - permissionService.setPermission(mainDirRef, user.getUserAuth(), user.getNewRole(), true); - permissionService.setPermission(previewDirRef, user.getUserAuth(), user.getNewRole(), true); + removeFromGroupIfRequired(storeName, user.getUserAuth(), user.getOldRole()); + addToGroupIfRequired(storeName, user.getUserAuth(), user.getNewRole()); } } } @@ -1131,25 +1214,29 @@ public final class SandboxFactory extends WCMUtil private void updateStagingAreaRole(String storeId, List usersToUpdate, Set permissionsList) { final String storeName = WCMUtil.buildStagingStoreName(storeId); - final NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, WCMUtil.buildStoreRootPath(storeName)); - + + // If permissionsList is set remove all possible user permissions and set only necessary. + // This will fix previous wrong role changes. (paranoid) + // For little better performance just set permissionsList to null. + // But in this case it removes only previous permission. if (permissionsList != null && permissionsList.size() != 0) { for (UserRoleWrapper user : usersToUpdate) { for (String permission : permissionsList) { - permissionService.deletePermission(dirRef, user.getUserAuth(), permission); + removeFromGroupIfRequired(storeName, user.getUserAuth(), permission); } - permissionService.setPermission(dirRef, user.getUserAuth(), user.getNewRole(), true); + + addToGroupIfRequired(storeName, user.getUserAuth(), user.getNewRole()); } } else { for (UserRoleWrapper user : usersToUpdate) { - permissionService.deletePermission(dirRef, user.getUserAuth(), user.getOldRole()); - permissionService.setPermission(dirRef, user.getUserAuth(), user.getNewRole(), true); + removeFromGroupIfRequired(storeName, user.getUserAuth(), user.getOldRole()); + addToGroupIfRequired(storeName, user.getUserAuth(), user.getNewRole()); } } } diff --git a/source/java/org/alfresco/wcm/util/WCMUtil.java b/source/java/org/alfresco/wcm/util/WCMUtil.java index e46327a600..350662880c 100644 --- a/source/java/org/alfresco/wcm/util/WCMUtil.java +++ b/source/java/org/alfresco/wcm/util/WCMUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2008 Alfresco Software Limited. + * Copyright (C) 2005-2009 Alfresco Software Limited. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General protected License @@ -42,6 +42,7 @@ import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.util.ParameterCheck; @@ -771,10 +772,10 @@ public class WCMUtil protected final static String SPACE_ICON_WEBSITE = "space-icon-website"; // web user role permissions - public static final String ROLE_CONTENT_MANAGER = "ContentManager"; - public static final String ROLE_CONTENT_PUBLISHER = "ContentPublisher"; - public static final String ROLE_CONTENT_REVIEWER = "ContentReviewer"; - public static final String ROLE_CONTENT_CONTRIBUTOR = "ContentContributor"; + public static final String ROLE_CONTENT_MANAGER = PermissionService.WCM_CONTENT_MANAGER; + public static final String ROLE_CONTENT_PUBLISHER = PermissionService.WCM_CONTENT_PUBLISHER; + public static final String ROLE_CONTENT_CONTRIBUTOR = PermissionService.WCM_CONTENT_CONTRIBUTOR; + public static final String ROLE_CONTENT_REVIEWER = PermissionService.WCM_CONTENT_REVIEWER; private final static Pattern WEBAPP_RELATIVE_PATH_PATTERN = Pattern.compile("([^:]+:/" + JNDIConstants.DIR_DEFAULT_WWW +