/* * Copyright (C) 2003-2008 eXo Platform SAS. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation; either version 3 * 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, see<http://www.gnu.org/licenses/>. */ package org.exoplatform.wcm.webui.dialog.permission; import java.security.AccessControlException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.jcr.AccessDeniedException; import javax.jcr.Node; import javax.jcr.Session; import org.exoplatform.commons.utils.LazyPageList; import org.exoplatform.commons.utils.ListAccess; import org.exoplatform.commons.utils.ListAccessImpl; import org.exoplatform.ecm.webui.form.UIFormInputSetWithAction; import org.exoplatform.ecm.webui.selector.UIGroupMemberSelector; import org.exoplatform.ecm.webui.selector.UISelectable; import org.exoplatform.services.jcr.access.AccessControlEntry; import org.exoplatform.services.jcr.access.PermissionType; import org.exoplatform.services.jcr.core.ExtendedNode; import org.exoplatform.services.security.IdentityConstants; import org.exoplatform.services.wcm.core.NodeLocation; import org.exoplatform.wcm.webui.Utils; import org.exoplatform.wcm.webui.dialog.UIContentDialogForm; import org.exoplatform.wcm.webui.selector.account.UIUserContainer; import org.exoplatform.web.application.ApplicationMessage; import org.exoplatform.webui.config.annotation.ComponentConfig; import org.exoplatform.webui.config.annotation.EventConfig; import org.exoplatform.webui.core.UIGrid; import org.exoplatform.webui.core.UIPopupContainer; import org.exoplatform.webui.core.lifecycle.UIFormLifecycle; import org.exoplatform.webui.event.Event; import org.exoplatform.webui.event.EventListener; import org.exoplatform.webui.form.UIForm; import org.exoplatform.webui.form.UIFormStringInput; import org.exoplatform.webui.form.input.UICheckBoxInput; /** * Created by The eXo Platform SAS * Author : Phan Le Thanh Chuong * chuong.phan@exoplatform.com, phan.le.thanh.chuong@gmail.com * Oct 29, 2009 */ @ComponentConfig ( lifecycle = UIFormLifecycle.class, template = "classpath:groovy/wcm/webui/dialog/permission/UIPermissionManager.gtmpl", events = { @EventConfig(listeners = UIPermissionManager.DeleteActionListener.class, confirm = "UIPermissionManagerGrid.msg.confirm-delete-permission"), @EventConfig(listeners = UIPermissionManager.EditActionListener.class), @EventConfig(listeners = UIPermissionManager.SaveActionListener.class), @EventConfig(listeners = UIPermissionManager.ClearActionListener.class), @EventConfig(listeners = UIPermissionManager.SelectUserActionListener.class), @EventConfig(listeners = UIPermissionManager.SelectMemberActionListener.class), @EventConfig(listeners = UIPermissionManager.AddAnyActionListener.class) } ) public class UIPermissionManager extends UIForm implements UISelectable { /** The Constant PERMISSION_MANAGER_GRID. */ public static final String PERMISSION_MANAGER_GRID = "UIPermissionManagerGrid"; /** The Constant PERMISSION_INPUT_SET. */ public static final String PERMISSION_INPUT_SET = "UIPermissionInputSetWithAction"; /** The Constant PERMISSION_STRING_INPUT. */ public static final String PERMISSION_STRING_INPUT = "UIPermissionStringInput"; /** The Constant ACCESSIBLE_CHECKBOX_INPUT. */ public static final String ACCESSIBLE_CHECKBOX_INPUT = "UIAccessibleCheckboxInput"; /** The Constant EDITABLE_CHECKBOX_INPUT. */ public static final String EDITABLE_CHECKBOX_INPUT = "UIEditableCheckboxInput"; public static final String USER_SELECTOR_POPUP_WINDOW = "UIUserSelectorPopupWindow"; public static final String GROUP_SELECTOR_POPUP_WINDOW = "UIGroupSelectorPopupWindow"; private String popupId; public String getPopupId() { return popupId; } public void setPopupId(String popupId) { this.popupId = popupId; } /** * Instantiates a new uI permission info. * * @throws Exception the exception */ public UIPermissionManager() throws Exception { UIGrid uiGrid = createUIComponent(UIGrid.class, null, PERMISSION_MANAGER_GRID); uiGrid.setLabel(PERMISSION_MANAGER_GRID); uiGrid.configure("owner", new String[] {"owner", "accessible", "editable"}, new String[] {"Edit", "Delete"}); addChild(uiGrid); UIFormInputSetWithAction permissionInputSet = new UIFormInputSetWithAction(PERMISSION_INPUT_SET); UIFormStringInput formStringInput = new UIFormStringInput(PERMISSION_STRING_INPUT, PERMISSION_STRING_INPUT, null); formStringInput.setReadOnly(true); permissionInputSet.addChild(formStringInput); permissionInputSet.setActionInfo(PERMISSION_STRING_INPUT, new String[] {"SelectUser", "SelectMember", "AddAny"}); permissionInputSet.showActionInfo(true); addChild(permissionInputSet); addChild(new UICheckBoxInput(ACCESSIBLE_CHECKBOX_INPUT, ACCESSIBLE_CHECKBOX_INPUT, null)); addChild(new UICheckBoxInput(EDITABLE_CHECKBOX_INPUT, EDITABLE_CHECKBOX_INPUT, null)); setActions(new String[] {"Save", "Clear"}); } /** * Update grid. * * @throws Exception the exception */ public void updateGrid() throws Exception { // Get node UIContentDialogForm contentDialogForm = getAncestorOfType(UIPopupContainer.class).getChild(UIContentDialogForm.class); NodeLocation webcontentNodeLocation = contentDialogForm.getWebcontentNodeLocation(); Node node = NodeLocation.getNodeByLocation(webcontentNodeLocation); ExtendedNode webcontent = (ExtendedNode) node; // Convert permission entries to map List<UIPermissionConfig> permissionConfigs = new ArrayList<UIPermissionConfig>(); Map<String, List<String>> permissionMap = new HashMap<String, List<String>>(); List<AccessControlEntry> accessControlEntries = webcontent.getACL().getPermissionEntries(); for (AccessControlEntry accessControlEntry : accessControlEntries) { String identity = accessControlEntry.getIdentity(); String permission = accessControlEntry.getPermission(); List<String> currentPermissions = permissionMap.get(identity); if (!permissionMap.containsKey(identity)) { permissionMap.put(identity, null); } if (currentPermissions == null) currentPermissions = new ArrayList<String>(); if (!currentPermissions.contains(permission)) { currentPermissions.add(permission); } permissionMap.put(identity, currentPermissions); } // Add owner's permission String owner = IdentityConstants.SYSTEM; if (webcontent.hasProperty("exo:owner")) owner = webcontent.getProperty("exo:owner").getString(); UIPermissionConfig permissionConfig = new UIPermissionConfig(); if (!permissionMap.containsKey(owner)) { permissionConfig.setOwner(owner); permissionConfig.setAccessible(true); permissionConfig.setEditable(true); permissionConfigs.add(permissionConfig); } // Add node's permission Iterator<String> permissionIterator = permissionMap.keySet().iterator(); while (permissionIterator.hasNext()) { String identity = (String) permissionIterator.next(); List<String> userPermissions = permissionMap.get(identity); UIPermissionConfig permBean = new UIPermissionConfig(); permBean.setOwner(identity); int numberPermission = 0; for (String p : PermissionType.ALL) { if (!userPermissions.contains(p)) break; numberPermission++; } if (numberPermission == PermissionType.ALL.length) { permBean.setEditable(true); permBean.setAccessible(true); } else { permBean.setAccessible(true); } permissionConfigs.add(permBean); } ListAccess<UIPermissionConfig> permConfigList = new ListAccessImpl<UIPermissionConfig>(UIPermissionConfig.class, permissionConfigs); LazyPageList<UIPermissionConfig> dataPageList = new LazyPageList<UIPermissionConfig>(permConfigList, 10); UIGrid uiGrid = getChildById(PERMISSION_MANAGER_GRID); uiGrid.getUIPageIterator().setPageList(dataPageList); } /* (non-Javadoc) * @see org.exoplatform.ecm.webui.selector.UISelectable#doSelect(java.lang.String, java.lang.Object) */ public void doSelect(String selectField, Object value) throws Exception { UIFormInputSetWithAction permissionInputSet = getChildById(PERMISSION_INPUT_SET); permissionInputSet.getUIStringInput(PERMISSION_STRING_INPUT).setValue(value.toString()); Utils.closePopupWindow(this, popupId); } /** * Checks for change permission right. * * @param node the node * * @return true, if successful * * @throws Exception the exception */ private boolean hasChangePermissionRight(ExtendedNode node) throws Exception { try { node.checkPermission(PermissionType.ADD_NODE); node.checkPermission(PermissionType.REMOVE); node.checkPermission(PermissionType.SET_PROPERTY); return true; } catch (AccessControlException e) { return false; } } /** * The listener interface for receiving deleteAction events. * The class that is interested in processing a deleteAction * event implements this interface, and the object created * with that class is registered with a component using the * component's <code>addDeleteActionListener</code> method. When * the deleteAction event occurs, that object's appropriate * method is invoked. */ public static class DeleteActionListener extends EventListener<UIPermissionManager> { /* (non-Javadoc) * @see org.exoplatform.webui.event.EventListener#execute(org.exoplatform.webui.event.Event) */ public void execute(Event<UIPermissionManager> event) throws Exception { UIPermissionManager permissionManager = event.getSource(); UIContentDialogForm contentDialogForm = permissionManager.getAncestorOfType(UIPopupContainer.class) .getChild(UIContentDialogForm.class); NodeLocation webcontentNodeLocation = contentDialogForm.getWebcontentNodeLocation(); Node node = NodeLocation.getNodeByLocation(webcontentNodeLocation); ExtendedNode webcontent = (ExtendedNode) node; Session session = webcontent.getSession(); String name = event.getRequestContext().getRequestParameter(OBJECTID); String nodeOwner = webcontent.getProperty("exo:owner").getString(); if (name.equals(nodeOwner)) { Utils.createPopupMessage(permissionManager, "UIPermissionManagerGrid.msg.no-permission-remove", null, ApplicationMessage.WARNING); return; } if (permissionManager.hasChangePermissionRight(webcontent)) { if (webcontent.canAddMixin("exo:privilegeable")) { webcontent.addMixin("exo:privilegeable"); webcontent.setPermission(nodeOwner, PermissionType.ALL); } try { webcontent.removePermission(name); session.save(); permissionManager.updateGrid(); } catch (AccessControlException e) { Object[] args = {webcontent.getPath()}; Utils.createPopupMessage(permissionManager, "UIPermissionManagerGrid.msg.node-locked", args, ApplicationMessage.WARNING); return; } catch (AccessDeniedException ace) { Utils.createPopupMessage(permissionManager, "UIPermissionManagerGrid.msg.access-denied", null, ApplicationMessage.WARNING); return; } } } } /** * The listener interface for receiving editAction events. * The class that is interested in processing a editAction * event implements this interface, and the object created * with that class is registered with a component using the * component's <code>addEditActionListener</code> method. When * the editAction event occurs, that object's appropriate * method is invoked. */ public static class EditActionListener extends EventListener<UIPermissionManager> { /* (non-Javadoc) * @see org.exoplatform.webui.event.EventListener#execute(org.exoplatform.webui.event.Event) */ public void execute(Event<UIPermissionManager> event) throws Exception { UIPermissionManager permissionManager = event.getSource(); UIContentDialogForm contentDialogForm = permissionManager.getAncestorOfType(UIPopupContainer.class) .getChild(UIContentDialogForm.class); NodeLocation webcontentNodeLocation = contentDialogForm.getWebcontentNodeLocation(); Node node = NodeLocation.getNodeByLocation(webcontentNodeLocation); ExtendedNode webcontent = (ExtendedNode) node; String name = event.getRequestContext().getRequestParameter(OBJECTID); UIFormInputSetWithAction permissionInputSet = permissionManager.getChildById(PERMISSION_INPUT_SET); permissionInputSet.getUIStringInput(PERMISSION_STRING_INPUT).setValue(name); String owner = node.getProperty("exo:owner").getString(); if (name.equals(owner)) { permissionManager.getUICheckBoxInput(ACCESSIBLE_CHECKBOX_INPUT).setChecked(true); permissionManager.getUICheckBoxInput(EDITABLE_CHECKBOX_INPUT).setChecked(true); permissionManager.setActions(new String[] {"Clear"}); permissionInputSet.setActionInfo(PERMISSION_STRING_INPUT, null); } else { List<AccessControlEntry> permsList = webcontent.getACL().getPermissionEntries(); StringBuilder userPermission = new StringBuilder(); for (AccessControlEntry accessControlEntry : permsList) { if (name.equals(accessControlEntry.getIdentity())) { userPermission.append(accessControlEntry.getPermission()).append(" "); } } int numPermission = 0; for (String perm : PermissionType.ALL) { if (userPermission.toString().contains(perm)) numPermission++; } if (numPermission == PermissionType.ALL.length) { permissionManager.getUICheckBoxInput(ACCESSIBLE_CHECKBOX_INPUT).setChecked(true); permissionManager.getUICheckBoxInput(EDITABLE_CHECKBOX_INPUT).setChecked(true); } else { permissionManager.getUICheckBoxInput(ACCESSIBLE_CHECKBOX_INPUT).setChecked(true); permissionManager.getUICheckBoxInput(EDITABLE_CHECKBOX_INPUT).setChecked(false); } permissionManager.setActions(new String[] {"Save", "Clear"}); permissionInputSet.setActionInfo(PERMISSION_STRING_INPUT, new String[] { "SelectUser", "SelectMember", "AddAny" }); } } } /** * The listener interface for receiving saveAction events. * The class that is interested in processing a saveAction * event implements this interface, and the object created * with that class is registered with a component using the * component's <code>addSaveActionListener</code> method. When * the saveAction event occurs, that object's appropriate * method is invoked. */ public static class SaveActionListener extends EventListener<UIPermissionManager> { /* (non-Javadoc) * @see org.exoplatform.webui.event.EventListener#execute(org.exoplatform.webui.event.Event) */ public void execute(Event<UIPermissionManager> event) throws Exception { UIPermissionManager permissionManager = event.getSource(); UIContentDialogForm contentDialogForm = permissionManager.getAncestorOfType(UIPopupContainer.class) .getChild(UIContentDialogForm.class); NodeLocation webcontentNodeLocation = contentDialogForm.getWebcontentNodeLocation(); Node node = NodeLocation.getNodeByLocation(webcontentNodeLocation); ExtendedNode webcontent = (ExtendedNode) node; Session session = webcontent.getSession(); UIFormInputSetWithAction formInputSet = permissionManager.getChildById(PERMISSION_INPUT_SET); String identity = ((UIFormStringInput) formInputSet.getChildById(PERMISSION_STRING_INPUT)).getValue(); List<String> permsList = new ArrayList<String>(); if (!webcontent.isCheckedOut()) { Utils.createPopupMessage(permissionManager, "UIPermissionManagerGrid.msg.node-checkedin", null, ApplicationMessage.WARNING); return; } if (permissionManager.getUICheckBoxInput(ACCESSIBLE_CHECKBOX_INPUT).isChecked()) { permsList.clear(); permsList.add(PermissionType.READ); } if (permissionManager.getUICheckBoxInput(EDITABLE_CHECKBOX_INPUT).isChecked()) { permsList.clear(); for (String perm : PermissionType.ALL) permsList.add(perm); } if (identity == null || identity.trim().length() == 0) { Utils.createPopupMessage(permissionManager, "UIPermissionManagerGrid.msg.userOrGroup-required", null, ApplicationMessage.WARNING); return; } if (permsList.size() == 0) { Utils.createPopupMessage(permissionManager, "UIPermissionManagerGrid.msg.checkbox-require", null, ApplicationMessage.WARNING); return; } String[] permsArray = permsList.toArray(new String[permsList.size()]); if (webcontent.canAddMixin("exo:privilegeable")) { webcontent.addMixin("exo:privilegeable"); webcontent.setPermission(webcontent.getProperty("exo:owner").getString(), PermissionType.ALL); } try { webcontent.setPermission(identity, permsArray); } catch (AccessControlException e) { Object[] args = {webcontent.getPath()}; Utils.createPopupMessage(permissionManager, "UIPermissionManagerGrid.msg.node-locked", args, ApplicationMessage.WARNING); return; } session.save(); permissionManager.updateGrid(); UIFormInputSetWithAction permissionInputSet = permissionManager.getChildById(PERMISSION_INPUT_SET); ((UIFormStringInput) permissionInputSet.getChildById(PERMISSION_STRING_INPUT)).setValue(""); permissionManager.getUICheckBoxInput(ACCESSIBLE_CHECKBOX_INPUT).setChecked(false); permissionManager.getUICheckBoxInput(EDITABLE_CHECKBOX_INPUT).setChecked(false); } } /** * The listener interface for receiving resetAction events. * The class that is interested in processing a resetAction * event implements this interface, and the object created * with that class is registered with a component using the * component's <code>addResetActionListener</code> method. When * the resetAction event occurs, that object's appropriate * method is invoked. */ public static class ClearActionListener extends EventListener<UIPermissionManager> { /* (non-Javadoc) * @see org.exoplatform.webui.event.EventListener#execute(org.exoplatform.webui.event.Event) */ public void execute(Event<UIPermissionManager> event) throws Exception { UIPermissionManager permissionManager = event.getSource(); UIFormInputSetWithAction permissionInputSet = permissionManager.getChildById(PERMISSION_INPUT_SET); ((UIFormStringInput) permissionInputSet.getChildById(PERMISSION_STRING_INPUT)).setValue(""); permissionManager.getUICheckBoxInput(ACCESSIBLE_CHECKBOX_INPUT).setChecked(false); permissionManager.getUICheckBoxInput(EDITABLE_CHECKBOX_INPUT).setChecked(false); permissionManager.setActions(new String[] {"Save", "Clear"}); permissionInputSet.setActionInfo(PERMISSION_STRING_INPUT, new String[] { "SelectUser", "SelectMember", "AddAny" }); } } /** * The listener interface for receiving selectUserAction events. * The class that is interested in processing a selectUserAction * event implements this interface, and the object created * with that class is registered with a component using the * component's <code>addSelectUserActionListener</code> method. When * the selectUserAction event occurs, that object's appropriate * method is invoked. */ public static class SelectUserActionListener extends EventListener<UIPermissionManager> { /* (non-Javadoc) * @see org.exoplatform.webui.event.EventListener#execute(org.exoplatform.webui.event.Event) */ public void execute(Event<UIPermissionManager> event) throws Exception { UIPermissionManager permissionManager = event.getSource(); UIUserContainer userContainer = permissionManager.createUIComponent(UIUserContainer.class, null, null); userContainer.setSelectable(permissionManager); userContainer.setSourceComponent(PERMISSION_STRING_INPUT); Utils.createPopupWindow(permissionManager, userContainer, USER_SELECTOR_POPUP_WINDOW, 740); permissionManager.setPopupId(USER_SELECTOR_POPUP_WINDOW); } } /** * The listener interface for receiving selectMemberAction events. * The class that is interested in processing a selectMemberAction * event implements this interface, and the object created * with that class is registered with a component using the * component's <code>addSelectMemberActionListener</code> method. When * the selectMemberAction event occurs, that object's appropriate * method is invoked. */ public static class SelectMemberActionListener extends EventListener<UIPermissionManager> { /* (non-Javadoc) * @see org.exoplatform.webui.event.EventListener#execute(org.exoplatform.webui.event.Event) */ public void execute(Event<UIPermissionManager> event) throws Exception { UIPermissionManager permissionManager = event.getSource(); UIGroupMemberSelector groupContainer = permissionManager.createUIComponent(UIGroupMemberSelector.class, null, null); groupContainer.setShowAnyPermission(false); groupContainer.setSourceComponent(permissionManager, new String[] {PERMISSION_STRING_INPUT}); Utils.createPopupWindow(permissionManager, groupContainer, GROUP_SELECTOR_POPUP_WINDOW, 600); permissionManager.setPopupId(GROUP_SELECTOR_POPUP_WINDOW); } } /** * The listener interface for receiving addAnyAction events. * The class that is interested in processing a addAnyAction * event implements this interface, and the object created * with that class is registered with a component using the * component's <code>addAddAnyActionListener</code> method. When * the addAnyAction event occurs, that object's appropriate * method is invoked. */ public static class AddAnyActionListener extends EventListener<UIPermissionManager> { /* (non-Javadoc) * @see org.exoplatform.webui.event.EventListener#execute(org.exoplatform.webui.event.Event) */ public void execute(Event<UIPermissionManager> event) throws Exception { UIPermissionManager permissionManager = event.getSource(); UIFormInputSetWithAction permisionInputSet = permissionManager.getChildById(PERMISSION_INPUT_SET); ((UIFormStringInput) permisionInputSet.getChildById(PERMISSION_STRING_INPUT)).setValue(IdentityConstants.ANY); permissionManager.getUICheckBoxInput(ACCESSIBLE_CHECKBOX_INPUT).setChecked(true); permissionManager.getUICheckBoxInput(EDITABLE_CHECKBOX_INPUT).setChecked(false); } } }