001: /*
002: * Copyright 2007 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: package com.pentaho.security.acls.voter;
014:
015: import org.acegisecurity.Authentication;
016: import org.acegisecurity.acl.AclEntry;
017: import org.acegisecurity.acl.basic.BasicAclEntry;
018: import org.acegisecurity.userdetails.UserDetails;
019: import org.pentaho.core.session.IPentahoSession;
020:
021: import com.pentaho.security.acls.IAclHolder;
022:
023: /**
024: * Extends the PentahoBasicAclVoter class, and overrides the getEffectiveAcls method
025: * to stipulate that if the current user occurrs in the access control list, that
026: * whatever access controls are listed for that user, those are the only ones returned.
027: * <p>
028: * For example, if the user (sally) belongs to the following roles:
029: * <pre>
030: * <table>
031: * <tr>
032: * <th>User Id</th><th>Role</th>
033: * </tr>
034: * <tr>
035: * <td>sally</td><td>dev</td>
036: * </tr>
037: * <tr>
038: * <td></td><td>mgr</td>
039: * </tr>
040: * </table>
041: * </pre>
042: * And the object has the following defined access controls:
043: * <pre>
044: * <table>
045: * <tr>
046: * <th>Role</th><th>Access</th>
047: * </tr>
048: * <tr>
049: * <td>dev</td><td>Execute</td>
050: * </tr>
051: * <tr>
052: * <td>sales</td><td>Execute and Subscribe</td>
053: * </tr>
054: * <tr>
055: * <td>sally</td><td>Nothing</td>
056: * </tr>
057: * </table>
058: * </pre>
059: * With the standard <tt>PentahoBasicAclVoter</tt>, sally would have Execute permissions on this
060: * object because that voter will simply aggregate all applicable access controls. With this voter,
061: * the returned access controls for sally will be <tt>PentahoAclEntry.NOTHING</tt>.
062: *
063: *
064: * @author mbatchel
065: *
066: */
067:
068: public class PentahoUserOverridesVoter extends PentahoBasicAclVoter {
069:
070: public AclEntry[] getEffectiveAcls(IPentahoSession session,
071: IAclHolder holder) {
072: Authentication auth = getAuthentication(session);
073: // User is un-authenticated. Return no access controls.
074: if (auth == null) {
075: return null;
076: }
077: AclEntry[] objectAcls = super .getEffectiveAcls(session, holder);
078: if (objectAcls == null) {
079: return null;
080: }
081: Object principal = auth.getPrincipal();
082: String userName = null;
083: if (principal instanceof UserDetails) {
084: userName = ((UserDetails) principal).getUsername();
085: } else {
086: userName = principal.toString();
087: }
088: for (int i = 0; i < objectAcls.length; i++) {
089: // First, search for the user name in the objectAcls. If it's there,
090: // then that
091: // overrides anything else. It's the only acl returned.
092: BasicAclEntry entry = (BasicAclEntry) objectAcls[i];
093: String recipient = entry.getRecipient().toString();
094: // Found the user in there - That means that his/her access to the
095: // object
096: // has been spelled out. Therefore, we need to simply return that
097: // ACL.
098: if (recipient.equals(userName)) {
099: return new AclEntry[] { entry };
100: }
101: }
102: // Wasn't anything specifically on the user. So, return default
103: // settings.
104: return objectAcls;
105: }
106:
107: }
|