001: /*
002: * Copyright 2005 Pentaho Corporation. All rights reserved.
003: * This software was developed by Pentaho Corporation and is provided under the terms
004: * of the Mozilla Public License, Version 1.1, or any later version. You may not use
005: * this file except in compliance with the license. If you need a copy of the license,
006: * please go to http://www.mozilla.org/MPL/MPL-1.1.txt. The Original Code is the Pentaho
007: * BI Platform. The Initial Developer is Pentaho Corporation.
008: *
009: * Software distributed under the Mozilla Public License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
011: * the license for the specific language governing your rights and limitations.
012: *
013: * Created Mar 14, 2006
014: * @author wseyler
015: */
016:
017: package org.pentaho.ui.component;
018:
019: import java.util.ArrayList;
020: import java.util.Enumeration;
021: import java.util.Iterator;
022: import java.util.List;
023: import java.util.Map;
024: import java.util.StringTokenizer;
025:
026: import javax.servlet.http.HttpServletRequest;
027:
028: import org.acegisecurity.GrantedAuthorityImpl;
029: import org.apache.commons.logging.Log;
030: import org.apache.commons.logging.LogFactory;
031: import org.dom4j.Document;
032: import org.dom4j.DocumentHelper;
033: import org.dom4j.Element;
034: import org.pentaho.core.repository.ISolutionRepository;
035: import org.pentaho.core.session.IPentahoSession;
036: import org.pentaho.core.solution.HttpRequestParameterProvider;
037: import org.pentaho.core.solution.ISolutionFile;
038: import org.pentaho.core.system.PentahoSystem;
039: import org.pentaho.core.ui.IPentahoUrlFactory;
040: import org.pentaho.messages.Messages;
041: import org.pentaho.repository.HibernateUtil;
042: import org.pentaho.ui.XmlComponent;
043:
044: import com.pentaho.security.UserDetailsRoleListService;
045: import com.pentaho.security.acls.IAclSolutionFile;
046: import com.pentaho.security.acls.PentahoAclEntry;
047:
048: public class PropertiesPanelUIComponent extends XmlComponent {
049:
050: private static final long serialVersionUID = 1L;
051:
052: private static final Log logger = LogFactory
053: .getLog(PropertiesPanelUIComponent.class);
054:
055: private static final String TYPE_PARAM = "type"; //$NON-NLS-1$
056:
057: private static final String ACTION_PARAM = "action"; //$NON-NLS-1$
058:
059: private static final String ADD_NAME_PARAM = "add_name"; //$NON-NLS-1$
060:
061: private static final String PATH_PARAM = "path"; //$NON-NLS-1$
062:
063: private static final String LIST_ACTION = "list"; //$NON-NLS-1$
064:
065: private static final String ADD_BTN_PARAM = "addBtn"; //$NON-NLS-1$
066:
067: private static final String UPDATE_BTN_PARAM = "updateBtn"; //$NON-NLS-1$
068:
069: private static final String PERMISSION_PREFIX = "perm_"; //$NON-NLS-1$
070:
071: private static final String ROLE_TYPE = "role"; //$NON-NLS-1$
072:
073: private static final String ROLE_PREFIX = ROLE_TYPE + "_"; //$NON-NLS-1$
074:
075: private static final String USER_TYPE = "user"; //$NON-NLS-1$
076:
077: private static final String USER_PREFIX = USER_TYPE + "_"; //$NON-NLS-1$
078:
079: private static final String PERMISSION_SEPERATOR = "#"; //$NON-NLS-1$
080:
081: private static final String DELETE_PREFIX = "delete_"; //$NON-NLS-1$
082:
083: private static final String NO_FILE_PATH_NODE_NAME = "no-file-path"; //$NON-NLS-1$
084:
085: private static final String NO_ACLS_NODE_NAME = "no-acls"; //$NON-NLS-1$
086:
087: private static final String INPUT_PAGE_NODE_NAME = "input-page"; //$NON-NLS-1$
088:
089: private static final String FILE_PATH_NODE_NAME = "file-path"; //$NON-NLS-1$
090:
091: private static final String IS_DIR_NODE_NAME = "is-directory"; //$NON-NLS-1$
092:
093: private static final String RECIPIENTS_NODE_NAME = "recipients"; //$NON-NLS-1$
094:
095: private static final String ROLE_NODE_NAME = "role"; //$NON-NLS-1$
096:
097: private static final String USER_NODE_NAME = "user"; //$NON-NLS-1$
098:
099: private static final String PERMISSION_NAMES_NODE_NAME = "permission-names"; //$NON-NLS-1$
100:
101: private static final String NAME_NODE_NAME = "name"; //$NON-NLS-1$
102:
103: private static final String ACCESS_CONTROL_LIST_NODE_NAME = "ac-list"; //$NON-NLS-1$
104:
105: private static final String ACCESS_CONTROL_NODE_NAME = "access-control"; //$NON-NLS-1$
106:
107: private static final String RECIPIENT_NODE_NAME = "recipient"; //$NON-NLS-1$
108:
109: private static final String PERMISSION_NODE_NAME = "permission"; //$NON-NLS-1$
110:
111: private static final String PERMITTED_NODE_NAME = "permitted"; //$NON-NLS-1$
112:
113: private static final String EMPTY_STRING = ""; //$NON-NLS-1$
114:
115: private static final String TRUE = "true"; //$NON-NLS-1$
116:
117: private static final String FALSE = "false"; //$NON-NLS-1$
118:
119: private static final String ON = "on"; //$NON-NLS-1$
120:
121: private static final String DISPLAY_PATH_NODE_NAME = "display-path"; //$NON-NLS-1$
122:
123: protected IPentahoSession session = null;
124:
125: protected String baseUrl = null;
126:
127: boolean includeUsers = PentahoSystem.getSystemSetting(
128: "access-ui/include-users", "true").equals("true"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
129:
130: boolean includeRoles = PentahoSystem.getSystemSetting(
131: "access-ui/include-roles", "true").equals("true"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
132:
133: protected ISolutionRepository repository;
134:
135: private List allUsersList;
136:
137: private List allRolesList;
138:
139: protected UserDetailsRoleListService userDetailsRoleListService;
140:
141: public PropertiesPanelUIComponent(IPentahoUrlFactory urlFactory,
142: List messages, IPentahoSession session) {
143: super (urlFactory, messages, null);
144: this .session = session;
145: setXsl("text/html", "PropertiesPanel.xsl"); //$NON-NLS-1$ //$NON-NLS-2$
146: setXslProperty(
147: "baseUrl", urlFactory.getDisplayUrlBuilder().getUrl()); //$NON-NLS-1$
148: repository = PentahoSystem.getSolutionRepository(session);
149: if (!repository.supportsACLS()) {
150: error(Messages
151: .getString("PropertiesPanelUIComponent.ERROR_0001_BAD_CONFIGURATION")); //$NON-NLS-1$
152: }
153: userDetailsRoleListService = PentahoSystem
154: .getUserDetailsRoleListService();
155: }
156:
157: public Document getXmlContent() {
158: if (!repository.supportsACLS()) {
159: return noACLSPage();
160: }
161:
162: String actionStr = this
163: .getParameter(ACTION_PARAM, EMPTY_STRING); // No
164: // nulls
165: String pathStr = this .getParameter(PATH_PARAM, null);
166: ISolutionFile file = null;
167: try {
168: HibernateUtil.beginTransaction();
169: file = repository.getFileByPath(pathStr);
170: } catch (Exception e) {
171: // do nothing since we want file to be null if it wasn't found
172: }
173:
174: // default action if none is passed is to list (showInputPage) the acls
175: if (actionStr == null
176: || actionStr.equalsIgnoreCase(LIST_ACTION)
177: || actionStr.equalsIgnoreCase(EMPTY_STRING)) {
178: HibernateUtil.commitTransaction();
179: if (file != null) {
180: return showInputPage(file);
181: }
182: return noPathPage();
183: } else {
184: HttpServletRequest request = ((HttpRequestParameterProvider) getParameterProviders()
185: .get(HttpRequestParameterProvider.SCOPE_REQUEST))
186: .getRequest();
187: if (request.getParameter(ADD_BTN_PARAM) != null
188: && !request.getParameter(ADD_BTN_PARAM).equals("")) { //$NON-NLS-1$
189: doAddToAcls(file);
190: }
191: if (request.getParameter(UPDATE_BTN_PARAM) != null
192: && !request.getParameter(UPDATE_BTN_PARAM).equals(
193: "")) { //$NON-NLS-1$
194: doUpdateAcls(file);
195: }
196: HibernateUtil.commitTransaction();
197: repository.resetRepository();
198: if (file != null) {
199: return showInputPage(file);
200: }
201: return noPathPage();
202: }
203: }
204:
205: private void doUpdateAcls(ISolutionFile file) {
206: HttpServletRequest request = ((HttpRequestParameterProvider) getParameterProviders()
207: .get(HttpRequestParameterProvider.SCOPE_REQUEST))
208: .getRequest();
209:
210: Object[] acls = new Object[request.getParameterMap().size()]; // At least the size of all the parameters
211: List aclList = new ArrayList();
212:
213: Enumeration enum1 = request.getParameterNames();
214: while (enum1.hasMoreElements()) {
215: String name = (String) enum1.nextElement();
216: if (name.startsWith(USER_PREFIX)
217: || name.startsWith(ROLE_PREFIX)) {
218: boolean isRole = name.startsWith(ROLE_PREFIX);
219: name = name.replaceFirst(isRole ? ROLE_PREFIX
220: : USER_PREFIX, EMPTY_STRING);
221:
222: String lineNumber = name.substring(name
223: .lastIndexOf('_') + 1);
224: name = name.substring(0, name.lastIndexOf('_'));
225: if (!isFlaggedForDelete(name)) { // If this is one being deleted we don't do anything with it
226: PentahoAclEntry entry = new PentahoAclEntry();
227: if (isRole) { // Check to see if this is a role name
228: entry.setRecipient(new GrantedAuthorityImpl(
229: name));
230: } else { // Otherwise assume that it's a user name
231: entry.setRecipient(name);
232: }
233: Enumeration enum2 = request.getParameterNames();
234: while (enum2.hasMoreElements()) {
235: String perm = (String) enum2.nextElement();
236: if (perm.startsWith(PERMISSION_PREFIX)) {
237: perm = perm.replaceFirst(PERMISSION_PREFIX,
238: EMPTY_STRING);
239: String permNumber = perm.substring(perm
240: .lastIndexOf('_') + 1);
241: if (permNumber.equals(lineNumber)) { // Congratulation... we have a winner!
242: perm = perm.substring(0, perm
243: .lastIndexOf('_'));
244: entry
245: .addPermission(((Integer) PentahoAclEntry
246: .getValidPermissionsNameMap()
247: .get(perm)).intValue());
248: }
249: }
250: }
251: int lineNum = Integer.parseInt(lineNumber) - 1;
252: acls[lineNum] = entry;
253: }
254: }
255: }
256: for (int i = 0; i < acls.length; i++) {
257: if (acls[i] != null) {
258: aclList.add(acls[i]);
259: }
260: }
261:
262: if (file instanceof IAclSolutionFile) {
263: ((IAclSolutionFile) file).resetAccessControls(aclList);
264: }
265: }
266:
267: private boolean isFlaggedForDelete(String name) {
268: HttpServletRequest request = ((HttpRequestParameterProvider) getParameterProviders()
269: .get(HttpRequestParameterProvider.SCOPE_REQUEST))
270: .getRequest();
271: return ON.equalsIgnoreCase(request.getParameter(DELETE_PREFIX
272: + name));
273: }
274:
275: private void doAddToAcls(ISolutionFile file) {
276: HttpServletRequest request = ((HttpRequestParameterProvider) getParameterProviders()
277: .get(HttpRequestParameterProvider.SCOPE_REQUEST))
278: .getRequest();
279: String[] names = request.getParameterValues(ADD_NAME_PARAM);
280:
281: for (int i = 0; i < names.length; i++) {
282: String name = names[i];
283: PentahoAclEntry entry = new PentahoAclEntry();
284:
285: if (name.startsWith(ROLE_PREFIX)) { // Check to see if this is a role name
286: String roleName = name.replaceFirst(ROLE_PREFIX,
287: EMPTY_STRING);
288: entry.setRecipient(new GrantedAuthorityImpl(roleName));
289: } else { // Otherwise assume that it's a user name
290: String userName = name.replaceFirst(USER_PREFIX,
291: EMPTY_STRING);
292: entry.setRecipient(userName);
293: }
294:
295: Enumeration enumeration = request.getParameterNames();
296: while (enumeration.hasMoreElements()) {
297: String paramName = enumeration.nextElement().toString();
298: if (paramName.startsWith(PERMISSION_PREFIX)) {
299: String permKey = paramName.replaceFirst(
300: PERMISSION_PREFIX, EMPTY_STRING);
301: StringTokenizer tokenizer = new StringTokenizer(
302: permKey, PERMISSION_SEPERATOR);
303: String permName = tokenizer.nextToken();
304: String perm = tokenizer.nextToken();
305:
306: if (permName.equals("Untitled-0")) { //$NON-NLS-1$
307: entry
308: .addPermission(((Integer) PentahoAclEntry
309: .getValidPermissionsNameMap()
310: .get(perm)).intValue());
311: }
312: }
313: }
314: if (file instanceof IAclSolutionFile) {
315: ((IAclSolutionFile) file).getAccessControls()
316: .add(entry);
317: }
318: }
319: }
320:
321: private Document noPathPage() {
322: Document document = DocumentHelper.createDocument();
323: document
324: .addElement(NO_FILE_PATH_NODE_NAME)
325: .addText(
326: Messages
327: .getString("PropertiesPanelUIComponent.USER_NO_FILE_SELECTED")); //$NON-NLS-1$
328:
329: return document;
330: }
331:
332: private Document noACLSPage() {
333: Document document = DocumentHelper.createDocument();
334: document
335: .addElement(NO_ACLS_NODE_NAME)
336: .addText(
337: Messages
338: .getString("PropertiesPanelUIComponent.ERROR_0001_BAD_CONFIGURATION")); //$NON-NLS-1$
339:
340: return document;
341: }
342:
343: protected Document showInputPage(ISolutionFile file) {
344: Document document = DocumentHelper.createDocument();
345: Element root = document.addElement(INPUT_PAGE_NODE_NAME)
346: .addText(file.getFullPath());
347:
348: // Add the info for the file we're working on
349: root.addElement(FILE_PATH_NODE_NAME)
350: .addText(file.getFullPath());
351: root.addElement(DISPLAY_PATH_NODE_NAME).addText(
352: file.getFullPath().replaceFirst(
353: repository.getRepositoryName(), EMPTY_STRING)
354: .replaceFirst("//", "/")); //$NON-NLS-1$//$NON-NLS-2$
355: root.addElement(IS_DIR_NODE_NAME).addText(
356: file.isDirectory() ? TRUE : FALSE);
357: Element recipients = root.addElement(RECIPIENTS_NODE_NAME);
358:
359: Iterator iter = null;
360: if (includeRoles) {
361: // Add all the possible roles
362: List rList = getAllRolesList();
363: if (rList != null) {
364: iter = rList.iterator();
365: while (iter.hasNext()) {
366: recipients.addElement(ROLE_NODE_NAME).addText(
367: iter.next().toString());
368: }
369: }
370: }
371: if (includeUsers) {
372: // Add all the possible users
373: List uList = getAllUsersList();
374: if (uList != null) {
375: iter = uList.iterator();
376: while (iter.hasNext()) {
377: recipients.addElement(USER_NODE_NAME).addText(
378: iter.next().toString());
379: }
380: }
381: }
382: // Add the names of all the permissions
383: Map permissionsMap = PentahoAclEntry
384: .getValidPermissionsNameMap();
385: // permissionsMap.remove(Messages.getString("PentahoAclEntry.USER_SUBSCRIBE")); //$NON-NLS-1$
386: Iterator keyIter = permissionsMap.keySet().iterator();
387: Element permNames = root.addElement(PERMISSION_NAMES_NODE_NAME);
388: while (keyIter.hasNext()) {
389: permNames.addElement(NAME_NODE_NAME).addText(
390: keyIter.next().toString());
391: }
392:
393: // Add the each of the group permissions
394: if (file instanceof IAclSolutionFile) {
395: iter = ((IAclSolutionFile) file).getAccessControls()
396: .iterator();
397: }
398: Element acListNode = root
399: .addElement(ACCESS_CONTROL_LIST_NODE_NAME);
400:
401: while (iter.hasNext()) {
402: Element acNode = acListNode
403: .addElement(ACCESS_CONTROL_NODE_NAME);
404: PentahoAclEntry acl = (PentahoAclEntry) iter.next();
405: Element recipientNode = acNode
406: .addElement(RECIPIENT_NODE_NAME);
407: recipientNode.setText(acl.getRecipient().toString());
408: recipientNode
409: .addAttribute(
410: TYPE_PARAM,
411: acl.getRecipient() instanceof GrantedAuthorityImpl ? ROLE_TYPE
412: : USER_TYPE);
413:
414: // Add individual permissions for this group
415: keyIter = permissionsMap.keySet().iterator();
416: while (keyIter.hasNext()) {
417: Element aPermission = acNode
418: .addElement(PERMISSION_NODE_NAME);
419: String permName = keyIter.next().toString();
420: aPermission.addElement(NAME_NODE_NAME)
421: .setText(permName);
422: int permMask = ((Integer) permissionsMap.get(permName))
423: .intValue();
424: boolean isPermitted = acl.isPermitted(permMask);
425: aPermission.addElement(PERMITTED_NODE_NAME).addText(
426: isPermitted ? TRUE : FALSE);
427: }
428: }
429:
430: return document;
431: }
432:
433: public List getAllUsersList() {
434: if (allUsersList == null) {
435: allUsersList = userDetailsRoleListService.getAllUsers();
436: }
437: return allUsersList;
438: }
439:
440: public List getAllRolesList() {
441: if (allRolesList == null) {
442: allRolesList = userDetailsRoleListService.getAllRoles();
443: }
444: return allRolesList;
445: }
446:
447: public Log getLogger() {
448: return logger;
449: }
450:
451: public boolean validate() {
452: return true;
453: }
454: }
|