/* * Copyright (C) 2005 Alfresco, Inc. * * Licensed under the Mozilla Public License version 1.1 * with a permitted attribution clause. You may obtain a * copy of the License at * * http://www.alfresco.org/legal/license.txt * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific * language governing permissions and limitations under the * License. */ package org.alfresco.web.bean.users; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.faces.application.FacesMessage; import javax.faces.component.UISelectOne; import javax.faces.context.FacesContext; import javax.faces.event.ActionEvent; import javax.faces.event.ValueChangeEvent; import javax.faces.model.DataModel; import javax.faces.model.ListDataModel; import javax.transaction.UserTransaction; import org.alfresco.model.ContentModel; import org.alfresco.service.cmr.repository.InvalidNodeRefException; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.security.AccessPermission; import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.AuthorityType; import org.alfresco.service.cmr.security.OwnableService; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PersonService; import org.alfresco.web.app.Application; import org.alfresco.web.app.context.UIContextService; import org.alfresco.web.bean.BrowseBean; import org.alfresco.web.bean.repository.MapNode; 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.ui.common.Utils; import org.alfresco.web.ui.common.component.UIActionLink; import org.alfresco.web.ui.common.component.data.UIRichList; import org.alfresco.web.ui.repo.WebResources; /** * @author Kevin Roast */ public class UserMembersBean { private static final String MSG_SUCCESS_INHERIT_NOT = "success_not_inherit_permissions"; private static final String MSG_SUCCESS_INHERIT = "success_inherit_permissions"; private static final String ERROR_DELETE = "error_remove_user"; private static final String OUTCOME_FINISH = "finish"; /** NodeService bean reference */ private NodeService nodeService; /** SearchService bean reference */ private SearchService searchService; /** PermissionService bean reference */ private PermissionService permissionService; /** PersonService bean reference */ private PersonService personService; /** BrowseBean bean refernce */ private BrowseBean browseBean; /** OwnableService bean reference */ private OwnableService ownableService; /** Component reference for Users RichList control */ private UIRichList usersRichList; /** action context */ private String personAuthority = null; /** action context */ private String personName = null; /** datamodel for table of roles for current person */ private DataModel personRolesDataModel = null; /** roles for current person */ private List personRoles = null; // ------------------------------------------------------------------------------ // Bean property getters and setters /** * @param nodeService The NodeService to set. */ public void setNodeService(NodeService nodeService) { this.nodeService = nodeService; } /** * @param searchService The search service */ public void setSearchService(SearchService searchService) { this.searchService = searchService; } /** * @param permissionService The PermissionService to set. */ public void setPermissionService(PermissionService permissionService) { this.permissionService = permissionService; } /** * @param ownableService The ownableService to set. */ public void setOwnableService(OwnableService ownableService) { this.ownableService = ownableService; } /** * @param personService The personService to set. */ public void setPersonService(PersonService personService) { this.personService = personService; } /** * @param browseBean The BrowseBean to set. */ public void setBrowseBean(BrowseBean browseBean) { this.browseBean = browseBean; } /** * @return The space to work against */ public Node getSpace() { return this.browseBean.getActionSpace(); } /** * @return Returns the usersRichList. */ public UIRichList getUsersRichList() { return this.usersRichList; } /** * @param usersRichList The usersRichList to set. */ public void setUsersRichList(UIRichList usersRichList) { this.usersRichList = usersRichList; // force refresh on exit of the page (as this property is set by JSF on view restore) this.usersRichList.setValue(null); } /** * Returns the properties for current Person roles JSF DataModel * * @return JSF DataModel representing the current Person roles */ public DataModel getPersonRolesDataModel() { if (this.personRolesDataModel == null) { this.personRolesDataModel = new ListDataModel(); } this.personRolesDataModel.setWrappedData(this.personRoles); return this.personRolesDataModel; } /** * @return Returns the current person authority. */ public String getPersonAuthority() { return this.personAuthority; } /** * @param person The person person authority to set. */ public void setPersonAuthority(String person) { this.personAuthority = person; } /** * @return Returns the personName. */ public String getPersonName() { return this.personName; } /** * @param personName The personName to set. */ public void setPersonName(String personName) { this.personName = personName; } /** * @return true if the current user can change permissions on this Space */ public boolean getHasChangePermissions() { return getSpace().hasPermission(PermissionService.CHANGE_PERMISSIONS); } /** * @return Returns the inherit parent permissions flag set for the current space. */ public boolean isInheritPermissions() { return this.permissionService.getInheritParentPermissions(getSpace().getNodeRef()); } /** * @param inheritPermissions The inheritPermissions to set. */ public void setInheritPermissions(boolean inheritPermissions) { // stub - no impl as changes are made immediately using a ValueChanged listener } /** * Return the owner username */ public String getOwner() { return this.ownableService.getOwner(getSpace().getNodeRef()); } /** * @return the list of user nodes for list data binding */ public List getUsers() { FacesContext context = FacesContext.getCurrentInstance(); List personNodes = null; UserTransaction tx = null; try { tx = Repository.getUserTransaction(context, true); tx.begin(); // Return all the permissions set against the current node // for any authentication instance (user). // Then combine them into a single list for each authentication found. User user = Application.getCurrentUser(context); Map> permissionMap = new HashMap>(13, 1.0f); Set permissions = permissionService.getAllSetPermissions(getSpace().getNodeRef()); if (permissions != null) { for (AccessPermission permission : permissions) { // we are only interested in Allow and not groups/owner etc. if (permission.getAccessStatus() == AccessStatus.ALLOWED && (permission.getAuthorityType() == AuthorityType.USER || permission.getAuthorityType() == AuthorityType.GROUP || permission.getAuthorityType() == AuthorityType.EVERYONE)) { String authority = permission.getAuthority(); List userPermissions = permissionMap.get(authority); if (userPermissions == null) { // create for first time userPermissions = new ArrayList(4); permissionMap.put(authority, userPermissions); } // add the permission name for this authority userPermissions.add(permission.getPermission()); } } } // for each authentication (username key) found we get the Person // node represented by it and use that for our list databinding object personNodes = new ArrayList(permissionMap.size()); for (String authority : permissionMap.keySet()) { // check if we are dealing with a person (User Authority) if (personService.personExists(authority)) { NodeRef nodeRef = personService.getPerson(authority); if (nodeRef != null) { // create our Node representation MapNode node = new MapNode(nodeRef); // set data binding properties // this will also force initialisation of the props now during the UserTransaction // it is much better for performance to do this now rather than during page bind Map props = node.getProperties(); props.put("fullName", ((String)props.get("firstName")) + ' ' + ((String)props.get("lastName"))); String userName = (String)props.get("userName"); props.put("roles", listToString(context, permissionMap.get(authority))); props.put("icon", WebResources.IMAGE_PERSON); personNodes.add(node); } } else { // need a map (dummy node) to represent props for this Group Authority Map node = new HashMap(5, 1.0f); node.put("fullName", authority.substring(PermissionService.GROUP_PREFIX.length())); node.put("userName", authority); node.put("id", authority); node.put("roles", listToString(context, permissionMap.get(authority))); node.put("icon", WebResources.IMAGE_GROUP); personNodes.add(node); } } // commit the transaction tx.commit(); } catch (InvalidNodeRefException refErr) { Utils.addErrorMessage(MessageFormat.format(Application.getMessage( context, Repository.ERROR_NODEREF), new Object[] {"root"}) ); personNodes = Collections.emptyList(); try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} } catch (Exception err) { Utils.addErrorMessage(MessageFormat.format(Application.getMessage( context, Repository.ERROR_GENERIC), err.getMessage()), err ); personNodes = Collections.emptyList(); try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} } return personNodes; } private static String listToString(FacesContext context, List list) { StringBuilder buf = new StringBuilder(); if (list != null) { for (int i=0; i params = link.getParameterMap(); String authority = params.get("userName"); if (authority != null && authority.length() != 0) { try { if (this.personService.personExists(authority)) { // create the node ref, then our node representation NodeRef ref = personService.getPerson(authority); Node node = new Node(ref); // setup convience function for current user full name setPersonName((String)node.getProperties().get(ContentModel.PROP_FIRSTNAME) + ' ' + (String)node.getProperties().get(ContentModel.PROP_LASTNAME)); } else { setPersonName(authority); } // setup roles for this Authority List userPermissions = new ArrayList(4); Set permissions = permissionService.getAllSetPermissions(getSpace().getNodeRef()); if (permissions != null) { for (AccessPermission permission : permissions) { // we are only interested in Allow permissions if (permission.getAccessStatus() == AccessStatus.ALLOWED) { if (authority.equals(permission.getAuthority())) { // found a permission for this user authentiaction PermissionWrapper wrapper = new PermissionWrapper( permission.getPermission(), Application.getMessage(context, permission.getPermission())); userPermissions.add(wrapper); } } } } // action context setup this.personRoles = userPermissions; setPersonAuthority(authority); } catch (Exception err) { Utils.addErrorMessage(MessageFormat.format(Application.getMessage(FacesContext .getCurrentInstance(), Repository.ERROR_GENERIC), new Object[] { err.getMessage() })); } } else { setPersonAuthority(null); } } /** * Inherit parent Space permissions value changed by the user */ public void inheritPermissionsValueChanged(ValueChangeEvent event) { try { // change the value to the new selected value boolean inheritPermissions = (Boolean)event.getNewValue(); this.permissionService.setInheritParentPermissions(getSpace().getNodeRef(), inheritPermissions); // inform the user that the change occured FacesContext context = FacesContext.getCurrentInstance(); String msg; if (inheritPermissions) { msg = Application.getMessage(context, MSG_SUCCESS_INHERIT); } else { msg = Application.getMessage(context, MSG_SUCCESS_INHERIT_NOT); } FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg); context.addMessage(event.getComponent().getClientId(context), facesMsg); } catch (Throwable e) { Utils.addErrorMessage(MessageFormat.format(Application.getMessage( FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), e.getMessage()), e); } } /** * Action handler called when the Add Role button is pressed to process the current selection */ public void addRole(ActionEvent event) { UISelectOne rolePicker = (UISelectOne)event.getComponent().findComponent("roles"); String role = (String)rolePicker.getValue(); if (role != null) { FacesContext context = FacesContext.getCurrentInstance(); PermissionWrapper wrapper = new PermissionWrapper(role, Application.getMessage(context, role)); this.personRoles.add(wrapper); } } /** * Action handler called when the Remove button is pressed to remove a role from current user */ public void removeRole(ActionEvent event) { PermissionWrapper wrapper = (PermissionWrapper)this.personRolesDataModel.getRowData(); if (wrapper != null) { this.personRoles.remove(wrapper); } } /** * Action handler called when the Finish button is clicked on the Edit User Roles page */ public String finishOK() { String outcome = OUTCOME_FINISH; FacesContext context = FacesContext.getCurrentInstance(); // persist new user permissions if (this.personRoles != null && getPersonAuthority() != null) { UserTransaction tx = null; try { tx = Repository.getUserTransaction(context); tx.begin(); // clear the currently set permissions for this user // and add each of the new permissions in turn NodeRef nodeRef = getSpace().getNodeRef(); this.permissionService.clearPermission(nodeRef, getPersonAuthority()); for (PermissionWrapper wrapper : personRoles) { this.permissionService.setPermission( nodeRef, getPersonAuthority(), wrapper.getPermission(), true); } tx.commit(); } catch (Exception err) { Utils.addErrorMessage(MessageFormat.format(Application.getMessage( context, Repository.ERROR_GENERIC), err.getMessage()), err ); try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} outcome = null; } } return outcome; } /** * Action handler called when the OK button is clicked on the Remove User page */ public String removeOK() { UserTransaction tx = null; try { FacesContext context = FacesContext.getCurrentInstance(); tx = Repository.getUserTransaction(context); tx.begin(); // remove the invited User if (getPersonAuthority() != null) { // clear permissions for the specified Authority this.permissionService.clearPermission(getSpace().getNodeRef(), getPersonAuthority()); } // commit the transaction tx.commit(); } catch (Exception e) { // rollback the transaction try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} Utils.addErrorMessage(MessageFormat.format(Application.getMessage(FacesContext .getCurrentInstance(), ERROR_DELETE), e.getMessage()), e); } return OUTCOME_FINISH; } // ------------------------------------------------------------------------------ // Inner classes /** * Wrapper class for list data model to display current roles for user */ public static class PermissionWrapper { public PermissionWrapper(String permission, String label) { this.permission = permission; this.label = label; } public String getRole() { return this.label; } public String getPermission() { return this.permission; } private String label; private String permission; } }