001: /******************************************************************************
002: * JBoss, a division of Red Hat *
003: * Copyright 2006, Red Hat Middleware, LLC, and individual *
004: * contributors as indicated by the @authors tag. See the *
005: * copyright.txt in the distribution for a full listing of *
006: * individual contributors. *
007: * *
008: * This is free software; you can redistribute it and/or modify it *
009: * under the terms of the GNU Lesser General Public License as *
010: * published by the Free Software Foundation; either version 2.1 of *
011: * the License, or (at your option) any later version. *
012: * *
013: * This software is distributed in the hope that it will be useful, *
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of *
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
016: * Lesser General Public License for more details. *
017: * *
018: * You should have received a copy of the GNU Lesser General Public *
019: * License along with this software; if not, write to the Free *
020: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
021: * 02110-1301 USA, or see the FSF site: http://www.fsf.org. *
022: ******************************************************************************/package org.jboss.portal.core.model.portal;
023:
024: import org.jboss.portal.security.PortalPermission;
025: import org.jboss.portal.security.PortalPermissionCollection;
026: import org.jboss.portal.security.PortalSecurityException;
027: import org.jboss.portal.security.spi.provider.PermissionRepository;
028:
029: import javax.security.auth.Subject;
030: import java.security.Permission;
031: import java.security.Principal;
032: import java.util.Collection;
033: import java.util.Iterator;
034: import java.util.Set;
035: import java.util.StringTokenizer;
036:
037: /**
038: * The permission for portal objects hierarchy.
039: *
040: * @author <a href="mailto:julien@jboss.org">Julien Viet</a>
041: * @version $Revision: 9081 $
042: */
043: public final class PortalObjectPermission extends PortalPermission {
044:
045: /** The serialVersionUID */
046: private static final long serialVersionUID = -4796595968918579499L;
047:
048: /** The create action name. */
049: public static final String CREATE_ACTION = "create";
050:
051: /** The view action name. */
052: public static final String VIEW_ACTION = "view";
053:
054: /** The view recursive action name. */
055: public static final String VIEW_RECURSIVE_ACTION = "viewrecursive";
056:
057: /** The personalize action name. */
058: public static final String PERSONALIZE_ACTION = "personalize";
059:
060: /** The personalize action name. */
061: public static final String PERSONALIZE_RECURSIVE_ACTION = "personalizerecursive";
062:
063: /** The create action name. */
064: public static final String DASHBOARD_ACTION = "dashboard";
065:
066: /** No Perms mask. */
067: public static final int NONE_MASK = 0x00;
068:
069: /** The view mask. */
070: public static final int VIEW_MASK = 0x01;
071:
072: /** The create mask. */
073: public static final int CREATE_MASK = 0x02;
074:
075: /** The create mask. */
076: public static final int PERSONALIZE_MASK = 0x04;
077:
078: /** The dashboard mask. */
079: public static final int DASHBOARD_MASK = 0x08;
080:
081: /** The action names. */
082: private static final String[] ACTION_NAMES = { VIEW_ACTION,
083: CREATE_ACTION, PERSONALIZE_ACTION, DASHBOARD_ACTION };
084:
085: /** . */
086: private PortalObjectId id;
087:
088: /** The imply mask. */
089: private int mask;
090:
091: /** The recursive imply mask. */
092: private int recursiveMask;
093:
094: /** The actions string. */
095: private String actions;
096:
097: /** . */
098: public static final String PERMISSION_TYPE = "portalobject";
099:
100: public PortalObjectPermission(PortalPermissionCollection collection) {
101: super ("portalobjectpermission", collection);
102: }
103:
104: public PortalObjectPermission(PortalObjectId id, Collection actions) {
105: super ("portalobjectpermission", id
106: .toString(PortalObjectPath.CANONICAL_FORMAT));
107:
108: //
109: if (actions == null) {
110: throw new IllegalArgumentException(
111: "Actions agurment cannot be null");
112: }
113:
114: //
115: this .id = id;
116:
117: //
118: for (Iterator i = actions.iterator(); i.hasNext();) {
119: String action = (String) i.next();
120: addAction(action);
121: }
122:
123: // Update the mask with the recursive mask
124: mask |= recursiveMask;
125: }
126:
127: public PortalObjectPermission(PortalObjectId id, String actions) {
128: super ("portalobjectpermission", id
129: .toString(PortalObjectPath.CANONICAL_FORMAT));
130: if (actions == null) {
131: throw new IllegalArgumentException(
132: "Actions agurment cannot be null");
133: }
134:
135: //
136: this .id = id;
137:
138: // Parse the actions into the mask
139: StringTokenizer tokenizer = new StringTokenizer(actions, ",");
140: while (tokenizer.hasMoreTokens()) {
141: String action = tokenizer.nextToken();
142: addAction(action);
143: }
144:
145: // Update the mask with the recursive mask
146: mask |= recursiveMask;
147: }
148:
149: public PortalObjectPermission(PortalObjectId id, int mask,
150: int recursiveMask) {
151: super ("portalobjectpermission", id
152: .toString(PortalObjectPath.CANONICAL_FORMAT));
153:
154: //
155: this .id = id;
156: this .mask = mask | recursiveMask;
157: this .recursiveMask = recursiveMask;
158: }
159:
160: public PortalObjectPermission(PortalObjectId id, int mask) {
161: super ("portalobjectpermission", id
162: .toString(PortalObjectPath.CANONICAL_FORMAT));
163:
164: //
165: this .id = id;
166: this .mask = mask;
167: this .recursiveMask = 0;
168: }
169:
170: private void addAction(String action)
171: throws IllegalArgumentException {
172: if (VIEW_ACTION.equals(action)) {
173: mask |= VIEW_MASK;
174: } else if (VIEW_RECURSIVE_ACTION.equals(action)) {
175: recursiveMask |= VIEW_MASK;
176: } else if (CREATE_ACTION.equals(action)) {
177: mask |= CREATE_MASK;
178: } else if (PERSONALIZE_ACTION.equals(action)) {
179: mask |= PERSONALIZE_MASK;
180: } else if (PERSONALIZE_RECURSIVE_ACTION.equals(action)) {
181: recursiveMask |= PERSONALIZE_MASK;
182: } else if (DASHBOARD_ACTION.equals(action)) {
183: mask |= DASHBOARD_MASK;
184: } else {
185: throw new IllegalArgumentException("Illegal action "
186: + action);
187: }
188: }
189:
190: public boolean implies(PermissionRepository repository,
191: Subject caller, String roleName, PortalPermission permission)
192: throws PortalSecurityException {
193: if (permission instanceof PortalObjectPermission) {
194: PortalObjectPermission pop = (PortalObjectPermission) permission;
195:
196: // If no uri then the permission is a container
197: if (pop.isContainer()) {
198: return false;
199: } else {
200: String namespace = pop.id.getNamespace();
201: PortalObjectPath path = pop.id.getPath();
202:
203: //
204: while (true) {
205: String uri = PortalObjectId.toString(namespace,
206: path, PortalObjectPath.CANONICAL_FORMAT);
207:
208: // Try to load the permission from the repository
209: PortalObjectPermission loaded = (PortalObjectPermission) repository
210: .getPermission(roleName, uri);
211:
212: // If it is loaded and implies then we return true
213: if (loaded != null && loaded.implies(pop, caller)) {
214: return true;
215: }
216:
217: // Get the parent uri
218: if (path.getLength() == 0) {
219: return false;
220: }
221:
222: // Get parent path
223: path = path.getParent();
224: }
225: }
226: }
227: return false;
228: }
229:
230: public boolean implies(Permission permission) {
231: return implies(permission, null);
232: }
233:
234: public boolean implies(Permission permission, Subject caller) {
235: if (permission instanceof PortalObjectPermission
236: && !isContainer()) {
237: PortalObjectPermission that = (PortalObjectPermission) permission;
238:
239: //
240: if (!that.isContainer()) {
241: if (!id.getNamespace().equals(that.id.getNamespace())) {
242: return false;
243: }
244:
245: PortalObjectPath this Path = id.getPath();
246: PortalObjectPath thatPath = that.id.getPath();
247:
248: //
249: if ((this .mask & DASHBOARD_MASK) == DASHBOARD_MASK
250: && caller != null
251: && this Path.getLength() < thatPath.getLength()) {
252: Set tmp = caller.getPrincipals();
253: if (tmp.size() > 0) {
254: Iterator i1 = this Path.names();
255: Iterator i2 = thatPath.names();
256:
257: //
258: while (i1.hasNext()) {
259: String name1 = (String) i1.next();
260: String name2 = (String) i2.next();
261: if (!name1.equals(name2)) {
262: return false;
263: }
264: }
265:
266: //
267: Iterator i = tmp.iterator();
268: Principal user = (Principal) i.next();
269: String userName = user.getName();
270:
271: //
272: return userName.equals(i2.next());
273: }
274: }
275:
276: // Could check namespace and id instead
277: if (that.uri.equals(this .uri)) {
278: if (that.recursiveMask != 0
279: && (this .recursiveMask & that.mask) != that.mask) {
280: return false;
281: }
282: return (this .mask & that.mask) == that.mask;
283: } else if (that.uri.startsWith(this .uri)) {
284: return (this .recursiveMask & that.mask) == that.mask;
285: }
286: }
287: }
288: return false;
289: }
290:
291: public boolean equals(Object obj) {
292: if (obj == this ) {
293: return true;
294: }
295: if (obj instanceof PortalObjectPermission) {
296: PortalObjectPermission that = (PortalObjectPermission) obj;
297: if (this .isContainer()) {
298: return that.isContainer();
299: }
300: return this .mask == that.mask && this .uri.equals(that.uri);
301: }
302: return false;
303: }
304:
305: public int hashCode() {
306: if (isContainer()) {
307: return 0;
308: } else {
309: return uri.hashCode() * 43 + mask;
310: }
311: }
312:
313: public String getActions() {
314: if (actions == null) {
315: StringBuffer tmp = new StringBuffer();
316:
317: //
318: for (int i = 0; i < ACTION_NAMES.length; i++) {
319: int mask = 2 >> i;
320: if ((this .mask & mask) == mask) {
321: tmp.append(ACTION_NAMES[i]);
322: if ((recursiveMask & mask) == mask) {
323: tmp.append("recursive,");
324: } else {
325: tmp.append(',');
326: }
327: } else if ((recursiveMask & mask) == mask) {
328: tmp.append(ACTION_NAMES[i]).append("recursive,");
329: }
330:
331: }
332:
333: //
334: int length = tmp.length();
335: if (length > 0) {
336: tmp.setLength(length - 1);
337: }
338: actions = tmp.toString();
339: }
340: return actions;
341: }
342:
343: public String getType() {
344: return PERMISSION_TYPE;
345: }
346:
347: public PortalObjectId getId() {
348: return id;
349: }
350: }
|