diff --git a/source/java/org/alfresco/web/bean/wcm/DeleteSandboxDialog.java b/source/java/org/alfresco/web/bean/wcm/DeleteSandboxDialog.java index 6b55aeeea6..2c91121658 100644 --- a/source/java/org/alfresco/web/bean/wcm/DeleteSandboxDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/DeleteSandboxDialog.java @@ -101,7 +101,7 @@ public class DeleteSandboxDialog extends BaseDialogBean String sandbox = AVMConstants.buildUserMainStoreName(storeRoot, username); String path = AVMConstants.buildStoreWebappPath(sandbox, this.avmBrowseBean.getWebapp()); - // Notifiy virtualisation server about removing this sandbox. + // Notify virtualisation server about removing this sandbox. // // Implementation note: // @@ -117,10 +117,8 @@ public class DeleteSandboxDialog extends BaseDialogBean // dependent order, so clients don't have to worry about // accessing a preview layer whose main layer has been torn // out from under it. - AVMConstants.removeVServerWebapp(path, true); - // TODO: Use the .sandbox-id. property to delete all sandboxes, // rather than assume a sandbox always had a single preview // layer attached. @@ -128,7 +126,6 @@ public class DeleteSandboxDialog extends BaseDialogBean // purge the user main sandbox store from the system this.avmService.purgeStore(sandbox); - // purge the user preview sandbox store from the system sandbox = AVMConstants.buildUserPreviewStoreName(storeRoot, username); this.avmService.purgeStore(sandbox); @@ -136,7 +133,6 @@ public class DeleteSandboxDialog extends BaseDialogBean // remove the association to this web project user meta-data this.nodeService.removeChild(website.getNodeRef(), ref.getChildRef()); - break; } } diff --git a/source/java/org/alfresco/web/bean/wcm/InviteWebsiteUsersWizard.java b/source/java/org/alfresco/web/bean/wcm/InviteWebsiteUsersWizard.java index 624ba11e7d..34f7d164f9 100644 --- a/source/java/org/alfresco/web/bean/wcm/InviteWebsiteUsersWizard.java +++ b/source/java/org/alfresco/web/bean/wcm/InviteWebsiteUsersWizard.java @@ -109,7 +109,7 @@ public class InviteWebsiteUsersWizard extends InviteUsersWizard // create a sandbox for each user appropriately with permissions based on role // build a list of managers who will have full permissions on ALL staging areas this.managers = new ArrayList(4); - Set excludeUsers = new HashSet(4); + Set existingUsers = new HashSet(8); if (isStandalone() == false) { // no website created yet - so we need to build the list of managers from the @@ -168,7 +168,7 @@ public class InviteWebsiteUsersWizard extends InviteUsersWizard } // add each existing user to the exclude this - we cannot add them more than once! - excludeUsers.add(username); + existingUsers.add(username); } } @@ -176,16 +176,18 @@ public class InviteWebsiteUsersWizard extends InviteUsersWizard // and create an association to a node to represent each invited user this.sandboxInfoList = new LinkedList(); + boolean managersUpdateRequired = false; for (UserGroupRole userRole : this.userGroupRoles) { for (String userAuth : findNestedUserAuthorities(userRole.getAuthority())) { - if (excludeUsers.contains(userAuth) == false) + // create the sandbox if the invited user does not already have one + if (existingUsers.contains(userAuth) == false) { SandboxInfo info = SandboxFactory.createUserSandbox( getAvmStore(), this.managers, userAuth, userRole.getRole()); - sandboxInfoList.add(info); + this.sandboxInfoList.add(info); // create an app:webuser instance for each authority and assoc to the website node Map props = new HashMap(2, 1.0f); @@ -196,6 +198,27 @@ public class InviteWebsiteUsersWizard extends InviteUsersWizard WCMAppModel.ASSOC_WEBUSER, WCMAppModel.TYPE_WEBUSER, props); + + // if this new user is a manager, we'll need to update the manager permissions applied + // to each existing user sandbox - to ensure that new managers have access to them + managersUpdateRequired |= (AVMConstants.ROLE_CONTENT_MANAGER.equals(userRole.getRole())); + } + } + } + + if (isStandalone() == true && managersUpdateRequired == true) + { + // walk existing sandboxes and reapply manager permissions to include any new manager users + List userInfoRefs = this.nodeService.getChildAssocs( + getNode().getNodeRef(), WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); + for (ChildAssociationRef ref : userInfoRefs) + { + NodeRef userInfoRef = ref.getChildRef(); + String username = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME); + if (existingUsers.contains(username)) + { + // only need to modify the sandboxes we haven't just created + SandboxFactory.updateSandboxManagers(getAvmStore(), this.managers, username); } } } @@ -288,7 +311,7 @@ public class InviteWebsiteUsersWizard extends InviteUsersWizard buf.append(userRole.getLabel()); buf.append("
"); } - if (foundCurrentUser == false) + if (isStandalone() == false && foundCurrentUser == false) { buf.append(buildLabelForUserAuthorityRole( currentUser, AVMConstants.ROLE_CONTENT_MANAGER)); diff --git a/source/java/org/alfresco/web/bean/wcm/SandboxFactory.java b/source/java/org/alfresco/web/bean/wcm/SandboxFactory.java index 7bfb3c9a33..e45002432d 100644 --- a/source/java/org/alfresco/web/bean/wcm/SandboxFactory.java +++ b/source/java/org/alfresco/web/bean/wcm/SandboxFactory.java @@ -423,6 +423,39 @@ public final class SandboxFactory return new SandboxInfo( new String[] { mainStoreName, previewStoreName } ); } + /** + * 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 + * @param username Username of the user sandbox to update + */ + public static void updateSandboxManagers( + final String storeId, final List managers, final String username) + { + final ServiceRegistry services = Repository.getServiceRegistry(FacesContext.getCurrentInstance()); + final PermissionService permissionService = services.getPermissionService(); + + final String userStoreName = AVMConstants.buildUserMainStoreName(storeId, username); + final String previewStoreName = AVMConstants.buildUserPreviewStoreName(storeId, username); + + // apply the manager role permission to the user main sandbox for each manager + NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, AVMConstants.buildStoreRootPath(userStoreName)); + for (String manager : managers) + { + permissionService.setPermission(dirRef, manager, AVMConstants.ROLE_CONTENT_MANAGER, true); + } + + // apply the manager role permission to the user preview sandbox for each manager + dirRef = AVMNodeConverter.ToNodeRef(-1, AVMConstants.buildStoreRootPath(previewStoreName)); + for (String manager : managers) + { + permissionService.setPermission(dirRef, manager, AVMConstants.ROLE_CONTENT_MANAGER, true); + } + } + /** * Tag a named store with a DNS path meta-data attribute. * The DNS meta-data attribute is set to the system path 'store:/www/avm_webapps' diff --git a/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java b/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java index 2152b60bcb..eb30ad69d9 100644 --- a/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java +++ b/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java @@ -60,6 +60,7 @@ import org.alfresco.web.app.Application; import org.alfresco.web.app.servlet.DownloadContentServlet; import org.alfresco.web.bean.BrowseBean; import org.alfresco.web.bean.repository.Repository; +import org.alfresco.web.bean.repository.User; import org.alfresco.web.bean.wcm.AVMConstants; import org.alfresco.web.bean.wcm.AVMNode; import org.alfresco.web.bean.wcm.WebProject; @@ -301,13 +302,17 @@ public class UIUserSandboxes extends SelfRenderingComponent // find out the current user role in the web project List userInfoRefs = nodeService.getChildAssocs( websiteRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); - String currentUserName = Application.getCurrentUser(context).getUserName(); - String currentUserRole = getWebProjectUserRole(nodeService, websiteRef, currentUserName, userInfoRefs); + User currentUser = Application.getCurrentUser(context); + String currentUserName = currentUser.getUserName(); + String currentUserRole = getWebProjectUserRole(nodeService, websiteRef, currentUser, userInfoRefs); // sort the user list alphabetically and insert the current user at the top of the list List userRoleWrappers = buildSortedUserRoles(nodeService, currentUserName, userInfoRefs); - // get the list of users who have a sandbox in the website + // output a javascript function we need for multi-select functionality + out.write(SCRIPT_MULTISELECT); + + // walk the list of users who have a sandbox in the website int index = 0; for (UserRoleWrapper wrapper : userRoleWrappers) { @@ -334,9 +339,6 @@ public class UIUserSandboxes extends SelfRenderingComponent if (logger.isDebugEnabled()) logger.debug("Building sandbox view for user store: " + mainStore); - // output a javascript function we need for multi-select functionality - out.write(SCRIPT_MULTISELECT); - // for each user sandbox, generate an outer panel table PanelGenerator.generatePanelStart(out, context.getExternalContext().getRequestContextPath(), @@ -535,19 +537,27 @@ public class UIUserSandboxes extends SelfRenderingComponent * @return the role of this user in the current Web Project, or null for no assigned role */ private static String getWebProjectUserRole( - NodeService nodeService, NodeRef websiteRef, String currentUser, List userInfoRefs) + NodeService nodeService, NodeRef websiteRef, User currentUser, List userInfoRefs) { String userrole = null; - for (ChildAssociationRef ref : userInfoRefs) + if (currentUser.isAdmin()) { - NodeRef userInfoRef = ref.getChildRef(); - String username = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME); - String role = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE); - if (currentUser.equals(username)) + // fake the Content Manager role for an admin user + userrole = AVMConstants.ROLE_CONTENT_MANAGER; + } + else + { + for (ChildAssociationRef ref : userInfoRefs) { - userrole = role; - break; + NodeRef userInfoRef = ref.getChildRef(); + String username = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME); + String role = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE); + if (currentUser.getUserName().equals(username)) + { + userrole = role; + break; + } } }