001: /*
002: JSPWiki - a JSP-based WikiWiki clone.
003:
004: Copyright (C) 2001-2004 Janne Jalkanen (Janne.Jalkanen@iki.fi)
005:
006: This program is free software; you can redistribute it and/or modify
007: it under the terms of the GNU Lesser General Public License as published by
008: the Free Software Foundation; either version 2.1 of the License, or
009: (at your option) any later version.
010:
011: This program is distributed in the hope that it will be useful,
012: but WITHOUT ANY WARRANTY; without even the implied warranty of
013: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: GNU Lesser General Public License for more details.
015:
016: You should have received a copy of the GNU Lesser General Public License
017: along with this program; if not, write to the Free Software
018: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: */
020: package com.ecyrd.jspwiki.auth.acl;
021:
022: import java.security.Permission;
023: import java.security.Principal;
024: import java.util.Enumeration;
025: import java.util.Iterator;
026: import java.util.Vector;
027:
028: /**
029: * JSPWiki implementation of an Access Control List.
030: * @author Janne Jalkanen
031: * @author Andrew Jaquith
032: * @since 2.3
033: */
034: public class AclImpl implements Acl {
035: private final Vector m_entries = new Vector();
036:
037: /**
038: * Constructs a new AclImpl instance.
039: */
040: public AclImpl() {
041: }
042:
043: /**
044: * Returns all Principal objects assigned a given Permission in the access
045: * control list. The Princiapls returned are those that have been granted
046: * either the supplied permission, or a permission implied by the supplied
047: * permission. Principals are not "expanded" if they are a role or group.
048: * @param permission the permission to search for
049: * @return an array of Principals posessing the permission
050: */
051: public Principal[] findPrincipals(Permission permission) {
052: Vector principals = new Vector();
053: Enumeration entries = entries();
054:
055: while (entries.hasMoreElements()) {
056: AclEntry entry = (AclEntry) entries.nextElement();
057: Enumeration permissions = entry.permissions();
058: while (permissions.hasMoreElements()) {
059: Permission perm = (Permission) permissions
060: .nextElement();
061: if (perm.implies(permission)) {
062: principals.add(entry.getPrincipal());
063: }
064: }
065: }
066: return (Principal[]) principals
067: .toArray(new Principal[principals.size()]);
068: }
069:
070: private boolean hasEntry(AclEntry entry) {
071: if (entry == null) {
072: return false;
073: }
074:
075: for (Iterator i = m_entries.iterator(); i.hasNext();) {
076: AclEntry e = (AclEntry) i.next();
077:
078: Principal ep = e.getPrincipal();
079: Principal entryp = entry.getPrincipal();
080:
081: if (ep == null || entryp == null) {
082: throw new IllegalArgumentException(
083: "Entry is null; check code, please (entry="
084: + entry + "; e=" + e + ")");
085: }
086:
087: if (ep.getName().equals(entryp.getName())) {
088: return true;
089: }
090: }
091:
092: return false;
093: }
094:
095: /**
096: * Adds an ACL entry to this ACL. An entry associates a principal (e.g., an
097: * individual or a group) with a set of permissions. Each principal can have
098: * at most one positive ACL entry, specifying permissions to be granted to
099: * the principal. If there is already an ACL entry already in the ACL, false
100: * is returned.
101: * @param entry - the ACL entry to be added to this ACL
102: * @return true on success, false if an entry of the same type (positive or
103: * negative) for the same principal is already present in this ACL
104: */
105: public synchronized boolean addEntry(AclEntry entry) {
106: if (entry.getPrincipal() == null) {
107: throw new IllegalArgumentException(
108: "Entry principal cannot be null");
109: }
110:
111: if (hasEntry(entry)) {
112: return false;
113: }
114:
115: m_entries.add(entry);
116:
117: return true;
118: }
119:
120: /**
121: * Removes an ACL entry from this ACL.
122: * @param entry the ACL entry to be removed from this ACL
123: * @return true on success, false if the entry is not part of this ACL
124: */
125: public synchronized boolean removeEntry(AclEntry entry) {
126: return m_entries.remove(entry);
127: }
128:
129: /**
130: * Returns an enumeration of the entries in this ACL. Each element in the
131: * enumeration is of type AclEntry.
132: * @return an enumeration of the entries in this ACL.
133: */
134: public Enumeration entries() {
135: return m_entries.elements();
136: }
137:
138: /**
139: * Returns an AclEntry for a supplied Principal, or <code>null</code> if
140: * the Principal does not have a matching AclEntry.
141: * @param principal the principal to search for
142: * @return the AclEntry associated with the principal, or <code>null</code>
143: */
144: public AclEntry getEntry(Principal principal) {
145: for (Enumeration e = m_entries.elements(); e.hasMoreElements();) {
146: AclEntry entry = (AclEntry) e.nextElement();
147:
148: if (entry.getPrincipal().getName().equals(
149: principal.getName())) {
150: return entry;
151: }
152: }
153:
154: return null;
155: }
156:
157: /**
158: * Returns a string representation of the contents of this Acl.
159: * @return the string representation
160: */
161: public String toString() {
162: StringBuffer sb = new StringBuffer();
163:
164: for (Enumeration myEnum = entries(); myEnum.hasMoreElements();) {
165: AclEntry entry = (AclEntry) myEnum.nextElement();
166:
167: Principal pal = entry.getPrincipal();
168:
169: if (pal != null)
170: sb.append(" user = " + pal.getName() + ": ");
171: else
172: sb.append(" user = null: ");
173:
174: sb.append("(");
175: for (Enumeration perms = entry.permissions(); perms
176: .hasMoreElements();) {
177: Permission perm = (Permission) perms.nextElement();
178: sb.append(perm.toString());
179: }
180: sb.append(")\n");
181: }
182:
183: return sb.toString();
184: }
185:
186: /**
187: * Returns <code>true</code>, if this Acl is empty.
188: * @return the result
189: * @since 2.4.68
190: */
191: public boolean isEmpty() {
192: return m_entries.isEmpty();
193: }
194:
195: }
|