diff --git a/config/alfresco/messages/webclient.properties b/config/alfresco/messages/webclient.properties index 93804fbe05..a118262766 100644 --- a/config/alfresco/messages/webclient.properties +++ b/config/alfresco/messages/webclient.properties @@ -853,9 +853,9 @@ create_website_finish_instruction=To close this wizard and create your web proje create_website_summary_users=Users and Roles # Invite web users wizard messages -invite_website_users=Invite Website Users -invite_webusers_title=Invite Website Users -invite_webusers_desc=Invite new users and create sandboxes for the web project. +invite_website_users=Invite Web Project Users +invite_webusers_title=Invite Web Project Users +invite_webusers_desc=Invite new users and create sandboxes for the Web Project. invite_webusers_step1_title=Step One - Invite Users invite_webusers_step1_desc=Select users and their roles. invite_webusers_step2_title=Step Two - Notify Users @@ -883,6 +883,7 @@ sandbox_revertselected=Undo Selected sandbox_icon=Browse Website sandbox_snapshot=Create Snapshot sandbox_snapshot_info=Create a snaphost of this sandbox. +sandbox_remove=Delete Sandbox import_website_content=Import Website Content title_browse_sandbox=Browse Sandbox sandbox_info=Use this view to browse the files and folders within the sandbox for a web project. @@ -944,6 +945,9 @@ snapshot_success=Snapshot ''{0}'' created for sandbox: {1} snapshot_failure=Snapshot not created - the sandbox has not been modified since the last snapshot. title_website_details=Web Project Details websitedetails_description=View the details of the web project. +delete_sandbox=Delete Sandbox +delete_sandbox_info=To remove this sandbox and the user from the Web Project, click OK. +delete_sandbox_confirm=Are you sure you want to remove the user sandbox \"{0}\" from the Web Project? # New User Wizard messages new_user_title=New User Wizard @@ -1314,6 +1318,7 @@ error_search=Search failed due to system error: {0} error_exists=A Space or File with that name already exists: {0} error_delete_space=Unable to delete Space due to system error: error_delete_file=Unable to delete File due to system error: +error_delete_sandbox=Unable to delete Sandbox due to system error: error_checkout=Unable to check out Content Node due to system error: error_update=Unable to update Content Node due to system error: error_cancel_checkout=Unable to cancel check out of Content Node due to system error: diff --git a/config/alfresco/web-client-config-dialogs.xml b/config/alfresco/web-client-config-dialogs.xml index 3e5cbfa2e5..a843b4f4e4 100644 --- a/config/alfresco/web-client-config-dialogs.xml +++ b/config/alfresco/web-client-config-dialogs.xml @@ -122,6 +122,10 @@ icon="/images/icons/create_snapshot_large.gif" title-id="sandbox_snapshot" description-id="sandbox_snapshot_info" /> + + @@ -141,7 +145,7 @@ - + diff --git a/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java b/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java index b1569139ef..1a635c9945 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java @@ -62,6 +62,7 @@ import org.alfresco.web.bean.BrowseBean; import org.alfresco.web.bean.NavigationBean; import org.alfresco.web.bean.repository.Node; import org.alfresco.web.bean.repository.Repository; +import org.alfresco.web.bean.repository.User; import org.alfresco.web.bean.wizard.WizardManager; import org.alfresco.web.config.ClientConfigElement; import org.alfresco.web.ui.common.Utils; @@ -538,21 +539,29 @@ public class AVMBrowseBean implements IContextListener { boolean isManager = false; - String currentUser = Application.getCurrentUser(FacesContext.getCurrentInstance()).getUserName(); - Node websiteNode = this.navigator.getCurrentNode(); - List userInfoRefs = this.nodeService.getChildAssocs( - websiteNode.getNodeRef(), ContentModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); - for (ChildAssociationRef ref : userInfoRefs) + User user = Application.getCurrentUser(FacesContext.getCurrentInstance()); + if (user.isAdmin() == false) { - NodeRef userInfoRef = ref.getChildRef(); - String username = (String)nodeService.getProperty(userInfoRef, ContentModel.PROP_WEBUSERNAME); - String userrole = (String)nodeService.getProperty(userInfoRef, ContentModel.PROP_WEBUSERROLE); - if (currentUser.equals(username) && ROLE_CONTENT_MANAGER.equals(userrole)) + String currentUser = user.getUserName(); + Node websiteNode = this.navigator.getCurrentNode(); + List userInfoRefs = this.nodeService.getChildAssocs( + websiteNode.getNodeRef(), ContentModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); + for (ChildAssociationRef ref : userInfoRefs) { - isManager = true; - break; + NodeRef userInfoRef = ref.getChildRef(); + String username = (String)nodeService.getProperty(userInfoRef, ContentModel.PROP_WEBUSERNAME); + String userrole = (String)nodeService.getProperty(userInfoRef, ContentModel.PROP_WEBUSERROLE); + if (currentUser.equals(username) && ROLE_CONTENT_MANAGER.equals(userrole)) + { + isManager = true; + break; + } } } + else + { + isManager = true; + } return isManager; } diff --git a/source/java/org/alfresco/web/bean/wcm/DeleteSandboxDialog.java b/source/java/org/alfresco/web/bean/wcm/DeleteSandboxDialog.java new file mode 100644 index 0000000000..8b96d8470a --- /dev/null +++ b/source/java/org/alfresco/web/bean/wcm/DeleteSandboxDialog.java @@ -0,0 +1,134 @@ +package org.alfresco.web.bean.wcm; + +import java.text.MessageFormat; +import java.util.List; + +import javax.faces.context.FacesContext; + +import org.alfresco.model.ContentModel; +import org.alfresco.service.cmr.avm.AVMService; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.RegexQNamePattern; +import org.alfresco.web.app.AlfrescoNavigationHandler; +import org.alfresco.web.app.Application; +import org.alfresco.web.bean.dialog.BaseDialogBean; +import org.alfresco.web.bean.repository.Node; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Bean implementation for the AVM "Delete Sandbox" dialog + * + * @author kevinr + */ +public class DeleteSandboxDialog extends BaseDialogBean +{ + private static final Log logger = LogFactory.getLog(DeleteSandboxDialog.class); + + protected AVMService avmService; + protected AVMBrowseBean avmBrowseBean; + + + /** + * @param avmBrowseBean The avmBrowseBean to set. + */ + public void setAvmBrowseBean(AVMBrowseBean avmBrowseBean) + { + this.avmBrowseBean = avmBrowseBean; + } + + /** + * @param avmService The avmService to set. + */ + public void setAvmService(AVMService avmService) + { + this.avmService = avmService; + } + + + // ------------------------------------------------------------------------------ + // Dialog implementation + + @Override + protected String finishImpl(FacesContext context, String outcome) + throws Exception + { + // the username for the sandbox to delete + String username = this.avmBrowseBean.getUsername(); + if (username != null) + { + Node website = this.avmBrowseBean.getWebsite(); + + // remove the store reference from the website folder meta-data + List userInfoRefs = this.nodeService.getChildAssocs( + website.getNodeRef(), + ContentModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); + for (ChildAssociationRef ref : userInfoRefs) + { + NodeRef userInfoRef = ref.getChildRef(); + String user = (String)nodeService.getProperty(userInfoRef, ContentModel.PROP_WEBUSERNAME); + String role = (String)nodeService.getProperty(userInfoRef, ContentModel.PROP_WEBUSERROLE); + + if (username.equals(user)) + { + // found the sandbox to remove + String storeRoot = (String)website.getProperties().get(ContentModel.PROP_AVMSTORE); + + // TODO: would it be better to use the .sandbox-id. property to delete all sandboxes? + + // purge the user main sandbox store from the system + String sandbox = AVMConstants.buildAVMUserMainStoreName(storeRoot, username); + this.avmService.purgeAVMStore(sandbox); + + // purge the user preview sandbox store from the system + sandbox = AVMConstants.buildAVMUserPreviewStoreName(storeRoot, username); + this.avmService.purgeAVMStore(sandbox); + + // remove the association to this web project user meta-data + this.nodeService.removeChild(website.getNodeRef(), ref.getChildRef()); + + break; + } + } + } + + return outcome; + } + + @Override + protected String doPostCommitProcessing(FacesContext context, String outcome) + { + return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; + } + + @Override + protected String getErrorMessageId() + { + return "error_delete_sandbox"; + } + + @Override + public boolean getFinishButtonDisabled() + { + return false; + } + + + // ------------------------------------------------------------------------------ + // Bean Getters and Setters + + /** + * Returns the confirmation to display to the user before deleting the user sandbox. + * + * @return The formatted message to display + */ + public String getConfirmMessage() + { + String fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(), + "delete_sandbox_confirm"); + + return MessageFormat.format(fileConfirmMsg, + new Object[] {this.avmBrowseBean.getUsername()}); + } +} diff --git a/source/java/org/alfresco/web/bean/wizard/InviteUsersWizard.java b/source/java/org/alfresco/web/bean/wizard/InviteUsersWizard.java index b3c6ec0dc7..eb37440258 100644 --- a/source/java/org/alfresco/web/bean/wizard/InviteUsersWizard.java +++ b/source/java/org/alfresco/web/bean/wizard/InviteUsersWizard.java @@ -67,6 +67,8 @@ public abstract class InviteUsersWizard extends BaseWizardBean private static final String MSG_INVITED_TO = "invited_to"; private static final String MSG_INVITED_ROLE = "invite_role"; + protected static final String STEP_NOTIFY = "notify"; + private static final String NOTIFY_YES = "yes"; /** NamespaceService bean reference */ @@ -234,6 +236,23 @@ public abstract class InviteUsersWizard extends BaseWizardBean return outcome; } + /** + * @see org.alfresco.web.bean.dialog.BaseDialogBean#getFinishButtonDisabled() + */ + @Override + public boolean getFinishButtonDisabled() + { + boolean disabled = true; + + String stepName = Application.getWizardManager().getCurrentStepName(); + if (STEP_NOTIFY.equals(stepName)) + { + disabled = false; + } + + return disabled; + } + /** * Returns the properties for current user-roles JSF DataModel * @@ -462,7 +481,7 @@ public abstract class InviteUsersWizard extends BaseWizardBean { String stepName = Application.getWizardManager().getCurrentStepName(); - if (stepName.equals("notify")) + if (STEP_NOTIFY.equals(stepName)) { FacesContext context = FacesContext.getCurrentInstance(); 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 87fc0d48c6..5095429841 100644 --- a/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java +++ b/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java @@ -81,6 +81,7 @@ public class UIUserSandboxes extends SelfRenderingComponent private static final String ACT_SANDBOX_SUBMITALL = "sandbox_submitall"; private static final String ACT_SANDBOX_PREVIEW = "sandbox_preview"; private static final String ACT_SANDBOX_ICON = "sandbox_icon"; + private static final String ACT_REMOVE_SANDBOX = "sandbox_remove"; private static final String ACTIONS_FILE = "avm_file_modified"; private static final String ACTIONS_FOLDER = "avm_folder_modified"; @@ -103,12 +104,26 @@ public class UIUserSandboxes extends SelfRenderingComponent private static final String MSG_DELETED_ITEM = "avm_node_deleted"; private static final String MSG_SELECTED = "selected"; + /** Content Manager role name */ + private static final String ROLE_CONTENT_MANAGER = "ContentManager"; + private static final String REQUEST_FORM_REF = "formref"; private static final String SPACE_ICON = "/images/icons/" + BrowseBean.SPACE_SMALL_DEFAULT + ".gif"; public static final String PARAM_FORM_ID = "form-id"; + private static final String SCRIPT_MULTISELECT = + ""; + /** website to show sandboxes for */ private NodeRef value; @@ -253,8 +268,10 @@ public class UIUserSandboxes extends SelfRenderingComponent } String storeRoot = (String)nodeService.getProperty(websiteRef, ContentModel.PROP_AVMSTORE); + // find out if this user is a Content Manager + boolean isManager = isManagerRole(context, nodeService, websiteRef); + // get the list of users who have a sandbox in the website - String currentUser = Application.getCurrentUser(context).getUserName(); int index = 0; List userInfoRefs = nodeService.getChildAssocs( websiteRef, ContentModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); @@ -285,15 +302,7 @@ public class UIUserSandboxes extends SelfRenderingComponent logger.debug("Building sandbox view for user store: " + mainStore); // output a javascript function we need for multi-select functionality - out.write(""); + out.write(SCRIPT_MULTISELECT); // for each user sandbox, generate an outer panel table PanelGenerator.generatePanelStart(out, @@ -334,6 +343,14 @@ public class UIUserSandboxes extends SelfRenderingComponent "#{AVMBrowseBean.revertAll}", null)); out.write(" "); + if (isManager) + { + Utils.encodeRecursive(context, aquireAction( + context, mainStore, username, ACT_REMOVE_SANDBOX, "/images/icons/delete_sandbox.gif", + "#{AVMBrowseBean.setupSandboxAction}", "dialog:deleteSandbox")); + out.write(" "); + } + Utils.encodeRecursive(context, aquireAction( context, mainStore, username, ACT_SANDBOX_BROWSE, "/images/icons/space_small.gif", "#{AVMBrowseBean.setupSandboxAction}", "browseSandbox")); @@ -403,6 +420,29 @@ public class UIUserSandboxes extends SelfRenderingComponent throw new RuntimeException(err); } } + + /** + * @return true if the current user is a Content Manager, false otherwise + */ + private static boolean isManagerRole(FacesContext context, NodeService nodeService, NodeRef websiteRef) + { + boolean isManager = false; + String currentUser = Application.getCurrentUser(context).getUserName(); + List userInfoRefs = nodeService.getChildAssocs( + websiteRef, ContentModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); + for (ChildAssociationRef ref : userInfoRefs) + { + NodeRef userInfoRef = ref.getChildRef(); + String username = (String)nodeService.getProperty(userInfoRef, ContentModel.PROP_WEBUSERNAME); + String userrole = (String)nodeService.getProperty(userInfoRef, ContentModel.PROP_WEBUSERROLE); + if (currentUser.equals(username) && ROLE_CONTENT_MANAGER.equals(userrole)) + { + isManager = true; + break; + } + } + return isManager; + } /** * Render the list of user modified files/folders in the layered sandbox area. diff --git a/source/web/WEB-INF/faces-config-beans.xml b/source/web/WEB-INF/faces-config-beans.xml index b932cb7971..e26e48bdfe 100644 --- a/source/web/WEB-INF/faces-config-beans.xml +++ b/source/web/WEB-INF/faces-config-beans.xml @@ -2379,6 +2379,27 @@ + + + The bean that backs up the Delete User Sandbox Dialog + + DeleteSandboxDialog + org.alfresco.web.bean.wcm.DeleteSandboxDialog + session + + avmService + #{AVMService} + + + avmBrowseBean + #{AVMBrowseBean} + + + nodeService + #{NodeService} + + + The bean that backs up the Create AVM Folder Dialog diff --git a/source/web/images/icons/delete_sandbox.gif b/source/web/images/icons/delete_sandbox.gif new file mode 100644 index 0000000000..4ee6ccfce4 Binary files /dev/null and b/source/web/images/icons/delete_sandbox.gif differ diff --git a/source/web/images/icons/delete_sandbox_large.gif b/source/web/images/icons/delete_sandbox_large.gif new file mode 100644 index 0000000000..cfe75d348b Binary files /dev/null and b/source/web/images/icons/delete_sandbox_large.gif differ