/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License, version 2 as published by the Free Software * Foundation. * * You should have received a copy of the GNU General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/gpl-2.0.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * 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. * * * Copyright 2006 - 2008 Pentaho Corporation. All rights reserved. * * Created Mar 14, 2006 * @author wseyler */ package org.pentaho.platform.uifoundation.component.xml; import java.util.Comparator; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.StringTokenizer; import java.util.TreeMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.pentaho.platform.api.engine.IAclSolutionFile; import org.pentaho.platform.api.engine.IParameterProvider; import org.pentaho.platform.api.engine.IPentahoSession; import org.pentaho.platform.api.engine.IPentahoUrlFactory; import org.pentaho.platform.api.engine.IPermissionMask; import org.pentaho.platform.api.engine.IPermissionRecipient; import org.pentaho.platform.api.engine.ISolutionFile; import org.pentaho.platform.api.engine.IUserDetailsRoleListService; import org.pentaho.platform.api.engine.PentahoAccessControlException; import org.pentaho.platform.api.repository.ISolutionRepository; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.engine.security.SimplePermissionMask; import org.pentaho.platform.engine.security.SimpleRole; import org.pentaho.platform.engine.security.SimpleUser; import org.pentaho.platform.engine.security.acls.PentahoAclEntry; import org.pentaho.platform.repository.hibernate.HibernateUtil; import org.pentaho.platform.uifoundation.messages.Messages; /** * TODO mlowery Need to remove direct references to PentahoAclEntry permission constants. Instead, reference * ISolutionRepository permission constants. */ public class PropertiesPanelUIComponent extends XmlComponent { private static final long serialVersionUID = 1L; private static final Log logger = LogFactory.getLog(PropertiesPanelUIComponent.class); private static final String TYPE_PARAM = "type"; //$NON-NLS-1$ private static final String ACTION_PARAM = "action"; //$NON-NLS-1$ private static final String ADD_NAME_PARAM = "add_name"; //$NON-NLS-1$ private static final String PATH_PARAM = "path"; //$NON-NLS-1$ private static final String LIST_ACTION = "list"; //$NON-NLS-1$ private static final String ADD_BTN_PARAM = "addBtn"; //$NON-NLS-1$ private static final String UPDATE_BTN_PARAM = "updateBtn"; //$NON-NLS-1$ private static final String ROLE_TYPE = "role"; //$NON-NLS-1$ private static final String PERM_TYPE = "perm"; //$NON-NLS-1$ private static final String ROLE_PREFIX = PropertiesPanelUIComponent.ROLE_TYPE + "_"; //$NON-NLS-1$ // NOTE: not related to PentahoAclEntry.PERMISSION_PREFIX private static final String PERMISSION_PREFIX = PropertiesPanelUIComponent.PERM_TYPE + "_"; //$NON-NLS-1$ private static final String USER_TYPE = "user"; //$NON-NLS-1$ private static final String USER_PREFIX = PropertiesPanelUIComponent.USER_TYPE + "_"; //$NON-NLS-1$ private static final String PERMISSION_SEPERATOR = "#"; //$NON-NLS-1$ private static final String DELETE_PREFIX = "delete_"; //$NON-NLS-1$ private static final String NO_FILE_PATH_NODE_NAME = "no-file-path"; //$NON-NLS-1$ private static final String SET_PERMISSIONS_DENIED_NAME = "set-permissions-denied"; //$NON-NLS-1$ private static final String NO_ACLS_NODE_NAME = "no-acls"; //$NON-NLS-1$ private static final String INPUT_PAGE_NODE_NAME = "input-page"; //$NON-NLS-1$ private static final String FILE_PATH_NODE_NAME = "file-path"; //$NON-NLS-1$ private static final String IS_DIR_NODE_NAME = "is-directory"; //$NON-NLS-1$ private static final String RECIPIENTS_NODE_NAME = "recipients"; //$NON-NLS-1$ private static final String ROLE_NODE_NAME = "role"; //$NON-NLS-1$ private static final String USER_NODE_NAME = "user"; //$NON-NLS-1$ private static final String PERMISSION_NAMES_NODE_NAME = "permission-names"; //$NON-NLS-1$ private static final String NAME_NODE_NAME = "name"; //$NON-NLS-1$ private static final String ACCESS_CONTROL_LIST_NODE_NAME = "ac-list"; //$NON-NLS-1$ private static final String ACCESS_CONTROL_NODE_NAME = "access-control"; //$NON-NLS-1$ private static final String RECIPIENT_NODE_NAME = "recipient"; //$NON-NLS-1$ private static final String PERMISSION_NODE_NAME = "permission"; //$NON-NLS-1$ private static final String PERMITTED_NODE_NAME = "permitted"; //$NON-NLS-1$ private static final String EMPTY_STRING = ""; //$NON-NLS-1$ private static final String TRUE = "true"; //$NON-NLS-1$ private static final String FALSE = "false"; //$NON-NLS-1$ private static final String ON = "on"; //$NON-NLS-1$ private static final String DISPLAY_PATH_NODE_NAME = "display-path"; //$NON-NLS-1$ protected IPentahoSession session = null; protected String baseUrl = null; boolean includeUsers = PentahoSystem.getSystemSetting("access-ui/include-users", "true").equals("true"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ boolean includeRoles = PentahoSystem.getSystemSetting("access-ui/include-roles", "true").equals("true"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ protected ISolutionRepository repository; private List allUsersList; private List allRolesList; protected IUserDetailsRoleListService userDetailsRoleListService; public PropertiesPanelUIComponent(final IPentahoUrlFactory urlFactory, final List messages, final IPentahoSession session) { super(urlFactory, messages, null); this.session = session; setXsl("text/html", "PropertiesPanel.xsl"); //$NON-NLS-1$ //$NON-NLS-2$ setXslProperty("baseUrl", urlFactory.getDisplayUrlBuilder().getUrl()); //$NON-NLS-1$ repository = PentahoSystem.get(ISolutionRepository.class, session); if (!repository.supportsAccessControls()) { error(Messages.getInstance().getString("PropertiesPanelUIComponent.ERROR_0001_BAD_CONFIGURATION")); //$NON-NLS-1$ } userDetailsRoleListService = PentahoSystem.get(IUserDetailsRoleListService.class); } @Override public Document getXmlContent() { if (!repository.supportsAccessControls()) { return noACLSPage(); } String actionStr = this.getParameter(PropertiesPanelUIComponent.ACTION_PARAM, PropertiesPanelUIComponent.EMPTY_STRING); // No // nulls String pathStr = this.getParameter(PropertiesPanelUIComponent.PATH_PARAM, null); ISolutionFile file = null; try { HibernateUtil.beginTransaction(); file = repository.getSolutionFile(pathStr, ISolutionRepository.ACTION_EXECUTE); } catch (Exception e) { // do nothing since we want file to be null if it wasn't found // TODO sbarkdull, arg, let's at least log it } // default action if none is passed is to list (showInputPage) the acls if ((actionStr == null) || actionStr.equalsIgnoreCase(PropertiesPanelUIComponent.LIST_ACTION) || actionStr.equalsIgnoreCase(PropertiesPanelUIComponent.EMPTY_STRING)) { HibernateUtil.commitTransaction(); if (file != null) { return showInputPage(file); } return noPathPage(); } else { IParameterProvider request = ((IParameterProvider) getParameterProviders().get(IParameterProvider.SCOPE_REQUEST)); if ((request.getParameter(PropertiesPanelUIComponent.ADD_BTN_PARAM) != null) && !request.getParameter(PropertiesPanelUIComponent.ADD_BTN_PARAM).equals("")) { //$NON-NLS-1$ doAddToAcls(file); } try { if ((request.getParameter(PropertiesPanelUIComponent.UPDATE_BTN_PARAM) != null) && !request.getParameter(PropertiesPanelUIComponent.UPDATE_BTN_PARAM).equals("")) { //$NON-NLS-1$ doUpdateAcls(file); } } catch (PentahoAccessControlException e) { HibernateUtil.rollbackTransaction(); return setPermissionsFailedPage(e.getLocalizedMessage()); } HibernateUtil.commitTransaction(); repository.resetRepository(); if (file != null) { return showInputPage(file); } return noPathPage(); } } private void doUpdateAcls(final ISolutionFile file) throws PentahoAccessControlException { IParameterProvider request = ((IParameterProvider) getParameterProviders().get(IParameterProvider.SCOPE_REQUEST)); Map permMap = new LinkedHashMap<IPermissionRecipient, IPermissionMask>(); Iterator it = request.getParameterNames(); while (it.hasNext()) { String name = (String) it.next(); if (name.startsWith(PropertiesPanelUIComponent.USER_PREFIX) || name.startsWith(PropertiesPanelUIComponent.ROLE_PREFIX)) { boolean isRole = name.startsWith(PropertiesPanelUIComponent.ROLE_PREFIX); name = name.replaceFirst(isRole ? PropertiesPanelUIComponent.ROLE_PREFIX : PropertiesPanelUIComponent.USER_PREFIX, PropertiesPanelUIComponent.EMPTY_STRING); String lineNumber = name.substring(name.lastIndexOf('_') + 1); name = name.substring(0, name.lastIndexOf('_')); if (!isFlaggedForDelete(name)) { // If this is one being deleted we don't do anything with it IPermissionRecipient permissionRecipient = isRole ? new SimpleRole(name) : new SimpleUser(name); SimplePermissionMask permissionMask = new SimplePermissionMask(); Iterator it1 = request.getParameterNames(); while (it1.hasNext()) { String perm = (String) it1.next(); if (perm.startsWith(PropertiesPanelUIComponent.PERMISSION_PREFIX)) { perm = perm.replaceFirst(PropertiesPanelUIComponent.PERMISSION_PREFIX, PropertiesPanelUIComponent.EMPTY_STRING); String permNumber = perm.substring(perm.lastIndexOf('_') + 1); if (permNumber.equals(lineNumber)) { // Congratulation... we have a winner! perm = perm.substring(0, perm.lastIndexOf('_')); permissionMask.addPermission(((Integer) PentahoAclEntry.getValidPermissionsNameMap().get(perm)) .intValue()); } } } permMap.put(permissionRecipient, permissionMask); } } } if (file instanceof IAclSolutionFile) { repository.setPermissions(file, permMap); } } private boolean isFlaggedForDelete(final String name) { IParameterProvider request = ((IParameterProvider) getParameterProviders().get(IParameterProvider.SCOPE_REQUEST)); return PropertiesPanelUIComponent.ON.equalsIgnoreCase(request.getStringParameter( PropertiesPanelUIComponent.DELETE_PREFIX + name, null)); } private void doAddToAcls(final ISolutionFile file) { IParameterProvider request = ((IParameterProvider) getParameterProviders().get(IParameterProvider.SCOPE_REQUEST)); String[] names = request.getStringArrayParameter(PropertiesPanelUIComponent.ADD_NAME_PARAM, new String[] {}); for (String name : names) { IPermissionRecipient permissionRecipient = null; if (name.startsWith(PropertiesPanelUIComponent.ROLE_PREFIX)) { permissionRecipient = new SimpleRole(name.replaceFirst(PropertiesPanelUIComponent.ROLE_PREFIX, PropertiesPanelUIComponent.EMPTY_STRING)); } else { permissionRecipient = new SimpleUser(name.replaceFirst(PropertiesPanelUIComponent.USER_PREFIX, PropertiesPanelUIComponent.EMPTY_STRING)); } SimplePermissionMask permissionMask = new SimplePermissionMask(); Iterator it = request.getParameterNames(); while (it.hasNext()) { String paramName = it.next().toString(); if (paramName.startsWith(PropertiesPanelUIComponent.PERMISSION_PREFIX)) { String permKey = paramName.replaceFirst(PropertiesPanelUIComponent.PERMISSION_PREFIX, PropertiesPanelUIComponent.EMPTY_STRING); StringTokenizer tokenizer = new StringTokenizer(permKey, PropertiesPanelUIComponent.PERMISSION_SEPERATOR); String permName = tokenizer.nextToken(); String perm = tokenizer.nextToken(); if (permName.equals("Untitled-0")) { //$NON-NLS-1$ permissionMask.addPermission(((Integer) PentahoAclEntry.getValidPermissionsNameMap().get(perm)).intValue()); } } } if (file instanceof IAclSolutionFile) { repository.addPermission(file, permissionRecipient, permissionMask); } } } private Document noPathPage() { Document document = DocumentHelper.createDocument(); document.addElement(PropertiesPanelUIComponent.NO_FILE_PATH_NODE_NAME).addText( Messages.getInstance().getString("PropertiesPanelUIComponent.USER_NO_FILE_SELECTED")); //$NON-NLS-1$ return document; } private Document setPermissionsFailedPage(final String msg) { Document document = DocumentHelper.createDocument(); document.addElement(PropertiesPanelUIComponent.SET_PERMISSIONS_DENIED_NAME).addText(msg); return document; } private Document noACLSPage() { Document document = DocumentHelper.createDocument(); document.addElement(PropertiesPanelUIComponent.NO_ACLS_NODE_NAME).addText( Messages.getInstance().getString("PropertiesPanelUIComponent.ERROR_0001_BAD_CONFIGURATION")); //$NON-NLS-1$ return document; } protected Document showInputPage(final ISolutionFile file) { Document document = DocumentHelper.createDocument(); Element root = document.addElement(PropertiesPanelUIComponent.INPUT_PAGE_NODE_NAME).addText(file.getFullPath()); // Add the info for the file we're working on root.addElement(PropertiesPanelUIComponent.FILE_PATH_NODE_NAME).addText(file.getFullPath()); root.addElement(PropertiesPanelUIComponent.DISPLAY_PATH_NODE_NAME).addText( file.getFullPath().replaceFirst(repository.getRepositoryName(), PropertiesPanelUIComponent.EMPTY_STRING) .replaceFirst("//", "/")); //$NON-NLS-1$//$NON-NLS-2$ root.addElement(PropertiesPanelUIComponent.IS_DIR_NODE_NAME).addText( file.isDirectory() ? PropertiesPanelUIComponent.TRUE : PropertiesPanelUIComponent.FALSE); Element recipients = root.addElement(PropertiesPanelUIComponent.RECIPIENTS_NODE_NAME); Iterator iter = null; if (includeRoles) { // Add all the possible roles List rList = getAllRolesList(); if (rList != null) { iter = rList.iterator(); while (iter.hasNext()) { recipients.addElement(PropertiesPanelUIComponent.ROLE_NODE_NAME).addText(iter.next().toString()); } } } if (includeUsers) { // Add all the possible users List uList = getAllUsersList(); if (uList != null) { iter = uList.iterator(); while (iter.hasNext()) { recipients.addElement(PropertiesPanelUIComponent.USER_NODE_NAME).addText(iter.next().toString()); } } } // Add the names of all the permissions Map permissionsMap = PentahoAclEntry.getValidPermissionsNameMap(); // permissionsMap.remove(Messages.getInstance().getString("PentahoAclEntry.USER_SUBSCRIBE")); //$NON-NLS-1$ Iterator keyIter = permissionsMap.keySet().iterator(); Element permNames = root.addElement(PropertiesPanelUIComponent.PERMISSION_NAMES_NODE_NAME); while (keyIter.hasNext()) { permNames.addElement(PropertiesPanelUIComponent.NAME_NODE_NAME).addText(keyIter.next().toString()); } Element acListNode = root.addElement(PropertiesPanelUIComponent.ACCESS_CONTROL_LIST_NODE_NAME); TreeMap<IPermissionRecipient, IPermissionMask> sortedMap = new TreeMap<IPermissionRecipient, IPermissionMask>( new Comparator<IPermissionRecipient>() { public int compare(IPermissionRecipient arg0, IPermissionRecipient arg1) { return arg0.getName().compareTo(arg1.getName()); } }); sortedMap.putAll(repository.getPermissions(file)); for (Map.Entry<IPermissionRecipient, IPermissionMask> mapEntry : sortedMap.entrySet()) { IPermissionRecipient permissionRecipient = mapEntry.getKey(); Element acNode = acListNode.addElement(PropertiesPanelUIComponent.ACCESS_CONTROL_NODE_NAME); Element recipientNode = acNode.addElement(PropertiesPanelUIComponent.RECIPIENT_NODE_NAME); recipientNode.setText(permissionRecipient.getName()); recipientNode.addAttribute(PropertiesPanelUIComponent.TYPE_PARAM, (permissionRecipient instanceof SimpleRole) ? PropertiesPanelUIComponent.ROLE_TYPE : PropertiesPanelUIComponent.USER_TYPE); // Add individual permissions for this group for (Iterator keyIterator = permissionsMap.keySet().iterator(); keyIterator.hasNext();) { Element aPermission = acNode.addElement(PropertiesPanelUIComponent.PERMISSION_NODE_NAME); String permName = keyIterator.next().toString(); aPermission.addElement(PropertiesPanelUIComponent.NAME_NODE_NAME).setText(permName); int permMask = ((Integer) permissionsMap.get(permName)).intValue(); // boolean isPermitted = repository.hasAccess(permissionRecipient, file, permMask); // broken on purpose boolean isPermitted = false; aPermission.addElement(PropertiesPanelUIComponent.PERMITTED_NODE_NAME).addText( isPermitted ? PropertiesPanelUIComponent.TRUE : PropertiesPanelUIComponent.FALSE); } } return document; } public static void main(String[] args) { } public List getAllUsersList() { if (allUsersList == null) { allUsersList = userDetailsRoleListService.getAllUsers(); } return allUsersList; } public List getAllRolesList() { if (allRolesList == null) { allRolesList = userDetailsRoleListService.getAllRoles(); } return allRolesList; } @Override public Log getLogger() { return PropertiesPanelUIComponent.logger; } @Override public boolean validate() { return true; } }