001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.jetspeed.om.page.impl;
018:
019: import java.util.Iterator;
020: import java.util.List;
021:
022: import org.apache.jetspeed.om.common.SecurityConstraints;
023: import org.apache.jetspeed.om.page.PageSecurity;
024: import org.apache.jetspeed.om.page.SecurityConstraintImpl;
025: import org.apache.jetspeed.om.page.SecurityConstraintsDef;
026: import org.apache.jetspeed.page.impl.DatabasePageManagerUtils;
027:
028: /**
029: * SecurityConstraintsImpl
030: *
031: * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
032: * @version $Id$
033: */
034: public class SecurityConstraintsImpl implements SecurityConstraints {
035: private String owner;
036: private List constraints;
037: private List constraintsRefs;
038:
039: private SecurityConstraintList securityConstraints;
040: private SecurityConstraintsRefList securityConstraintsRefs;
041:
042: private List allConstraints;
043:
044: /**
045: * accessConstraintsRefs
046: *
047: * Access mutable persistent collection member for List wrappers.
048: *
049: * @return persistent collection
050: */
051: List accessConstraintsRefs() {
052: // create initial collection if necessary
053: if (constraintsRefs == null) {
054: constraintsRefs = DatabasePageManagerUtils.createList();
055: }
056: return constraintsRefs;
057: }
058:
059: /**
060: * accessConstraints
061: *
062: * Access mutable persistent collection member for List wrappers.
063: *
064: * @return persistent collection
065: */
066: List accessConstraints() {
067: // create initial collection if necessary
068: if (constraints == null) {
069: constraints = DatabasePageManagerUtils.createList();
070: }
071: return constraints;
072: }
073:
074: /**
075: * getSecurityConstraintClass
076: *
077: * Return class of persistent constraint instance.
078: *
079: * @return constraint class
080: */
081: public Class getSecurityConstraintClass() {
082: // none by default
083: return null;
084: }
085:
086: /**
087: * getSecurityConstraintsRefClass
088: *
089: * Return class of persistent constraints reference instance.
090: *
091: * @return constraints reference class
092: */
093: public Class getSecurityConstraintsRefClass() {
094: // none by default
095: return null;
096: }
097:
098: /**
099: * checkConstraints
100: *
101: * @param actions actions to check
102: * @param userPrincipals principal users list
103: * @param rolePrincipals principal roles list
104: * @param groupPrincipals principal group list
105: * @param pageSecurity page security definitions
106: * @throws SecurityException
107: */
108: public void checkConstraints(List actions, List userPrincipals,
109: List rolePrincipals, List groupPrincipals,
110: PageSecurity pageSecurity) throws SecurityException {
111: // if owner defined, override all constraints and allow all access
112: if ((owner != null) && (userPrincipals != null)
113: && userPrincipals.contains(owner)) {
114: return;
115: }
116:
117: // skip missing or empty constraints: permit all access
118: List checkConstraints = getAllSecurityConstraints(pageSecurity);
119: if ((checkConstraints != null) && !checkConstraints.isEmpty()) {
120: // test each action, constraints check passes only
121: // if all actions are permitted for principals
122: Iterator actionsIter = actions.iterator();
123: while (actionsIter.hasNext()) {
124: // check each action:
125: // - if any actions explicity permitted, (including owner),
126: // assume no permissions are permitted by default
127: // - if all constraints do not specify a permission, assume
128: // access is permitted by default
129: String action = (String) actionsIter.next();
130: boolean actionPermitted = false;
131: boolean actionNotPermitted = false;
132: boolean anyActionsPermitted = (getOwner() != null);
133:
134: // check against constraints
135: Iterator checkConstraintsIter = checkConstraints
136: .iterator();
137: while (checkConstraintsIter.hasNext()) {
138: SecurityConstraintImpl constraint = (SecurityConstraintImpl) checkConstraintsIter
139: .next();
140:
141: // if permissions specified, attempt to match constraint
142: if (constraint.getPermissions() != null) {
143: // explicit actions permitted
144: anyActionsPermitted = true;
145:
146: // test action permission match and user/role/group principal match
147: if (constraint.actionMatch(action)
148: && constraint.principalsMatch(
149: userPrincipals, rolePrincipals,
150: groupPrincipals, true)) {
151: actionPermitted = true;
152: break;
153: }
154: } else {
155: // permissions not specified: not permitted if any principal matched
156: if (constraint.principalsMatch(userPrincipals,
157: rolePrincipals, groupPrincipals, false)) {
158: actionNotPermitted = true;
159: break;
160: }
161: }
162: }
163:
164: // fail if any action not permitted
165: if ((!actionPermitted && anyActionsPermitted)
166: || actionNotPermitted) {
167: throw new SecurityException(
168: "SecurityConstraintsImpl.checkConstraints(): Access for "
169: + action + " not permitted.");
170: }
171: }
172: } else {
173: // fail for any action if owner specified
174: // since no other constraints were found
175: if ((getOwner() != null) && !actions.isEmpty()) {
176: String action = (String) actions.get(0);
177: throw new SecurityException(
178: "SecurityConstraintsImpl.checkConstraints(): Access for "
179: + action
180: + " not permitted, (not owner).");
181: }
182: }
183: }
184:
185: /**
186: * resetCachedSecurityConstraints
187: */
188: public void resetCachedSecurityConstraints() {
189: // clear previously cached security constraints
190: clearAllSecurityConstraints();
191: }
192:
193: /**
194: * getAllSecurityConstraints
195: *
196: * @param pageSecurity page security definitions
197: * @return all security constraints
198: */
199: private synchronized List getAllSecurityConstraints(
200: PageSecurity pageSecurity) {
201: // return previously cached security constraints
202: if (allConstraints != null) {
203: return allConstraints;
204: }
205:
206: // construct new ordered security constraints list
207: allConstraints = DatabasePageManagerUtils.createList();
208:
209: // add any defined security constraints
210: if ((getSecurityConstraints() != null)
211: && !getSecurityConstraints().isEmpty()) {
212: allConstraints.addAll(securityConstraints);
213: }
214:
215: // add any security constraints references
216: if ((getSecurityConstraintsRefs() != null)
217: && !getSecurityConstraintsRefs().isEmpty()) {
218: List referencedConstraints = dereferenceSecurityConstraintsRefs(
219: getSecurityConstraintsRefs(), pageSecurity);
220: if (referencedConstraints != null) {
221: allConstraints.addAll(referencedConstraints);
222: }
223: }
224:
225: // add any global decurity constraints references
226: if (pageSecurity != null) {
227: List globalConstraintsRefs = pageSecurity
228: .getGlobalSecurityConstraintsRefs();
229: if ((globalConstraintsRefs != null)
230: && !globalConstraintsRefs.isEmpty()) {
231: List referencedConstraints = dereferenceSecurityConstraintsRefs(
232: globalConstraintsRefs, pageSecurity);
233: if (referencedConstraints != null) {
234: allConstraints.addAll(referencedConstraints);
235: }
236: }
237: }
238:
239: return allConstraints;
240: }
241:
242: /**
243: * clearAllSecurityConstraints
244: */
245: synchronized void clearAllSecurityConstraints() {
246: // clear previously cached security constraints
247: allConstraints = null;
248: }
249:
250: /**
251: * dereferenceSecurityConstraintsRefs
252: *
253: * @param constraintsRefs contstraints references to be dereferenced
254: * @param pageSecurity page security definitions
255: * @return security constraints
256: */
257: private List dereferenceSecurityConstraintsRefs(
258: List constraintsRefs, PageSecurity pageSecurity) {
259: List constraints = null;
260: if (pageSecurity != null) {
261: // dereference each security constraints definition
262: Iterator constraintsRefsIter = constraintsRefs.iterator();
263: while (constraintsRefsIter.hasNext()) {
264: String constraintsRef = (String) constraintsRefsIter
265: .next();
266: SecurityConstraintsDef securityConstraintsDef = pageSecurity
267: .getSecurityConstraintsDef(constraintsRef);
268: if ((securityConstraintsDef != null)
269: && (securityConstraintsDef
270: .getSecurityConstraints() != null)) {
271: if (constraints == null) {
272: constraints = DatabasePageManagerUtils
273: .createList();
274: }
275: constraints.addAll(securityConstraintsDef
276: .getSecurityConstraints());
277: }
278: }
279: }
280: return constraints;
281: }
282:
283: /* (non-Javadoc)
284: * @see org.apache.jetspeed.om.common.SecurityConstraints#getOwner()
285: */
286: public String getOwner() {
287: return owner;
288: }
289:
290: /* (non-Javadoc)
291: * @see org.apache.jetspeed.om.common.SecurityConstraints#setOwner(java.lang.String)
292: */
293: public void setOwner(String owner) {
294: // save new setting and reset cached security constraints
295: this .owner = owner;
296: clearAllSecurityConstraints();
297: }
298:
299: /* (non-Javadoc)
300: * @see org.apache.jetspeed.om.common.SecurityConstraints#getSecurityConstraints()
301: */
302: public List getSecurityConstraints() {
303: // return mutable inline constraint list
304: // by using list wrapper to manage apply order
305: if (securityConstraints == null) {
306: securityConstraints = new SecurityConstraintList(this );
307: }
308: return securityConstraints;
309: }
310:
311: /* (non-Javadoc)
312: * @see org.apache.jetspeed.om.common.SecurityConstraints#setSecurityConstraints(java.util.List)
313: */
314: public void setSecurityConstraints(List constraints) {
315: // set inline constraints by replacing existing
316: // entries with new elements if new collection
317: // is specified
318: List securityConstraints = getSecurityConstraints();
319: if (constraints != securityConstraints) {
320: // replace all constraints
321: securityConstraints.clear();
322: if (constraints != null) {
323: securityConstraints.addAll(constraints);
324: }
325: }
326: // reset cached security constraints
327: clearAllSecurityConstraints();
328: }
329:
330: /* (non-Javadoc)
331: * @see org.apache.jetspeed.om.common.SecurityConstraints#getSecurityConstraintsRefs()
332: */
333: public List getSecurityConstraintsRefs() {
334: // return mutable constraints refs list
335: // by using list wrapper to manage apply
336: // order and element uniqueness
337: if (securityConstraintsRefs == null) {
338: securityConstraintsRefs = new SecurityConstraintsRefList(
339: this );
340: }
341: return securityConstraintsRefs;
342: }
343:
344: /* (non-Javadoc)
345: * @see org.apache.jetspeed.om.common.SecurityConstraints#setSecurityConstraintsRefs(java.util.List)
346: */
347: public void setSecurityConstraintsRefs(List constraintsRefs) {
348: // set constraints refs using ordered ref
349: // names by replacing existing entries with
350: // new elements if new collection is specified
351: List securityConstraintsRefs = getSecurityConstraintsRefs();
352: if (constraintsRefs != securityConstraintsRefs) {
353: // replace all constraints ref names
354: securityConstraintsRefs.clear();
355: if (constraintsRefs != null) {
356: securityConstraintsRefs.addAll(constraintsRefs);
357: }
358: }
359: // reset cached security constraints
360: clearAllSecurityConstraints();
361: }
362:
363: /* (non-Javadoc)
364: * @see org.apache.jetspeed.om.common.SecurityConstraints#isEmpty()
365: */
366: public boolean isEmpty() {
367: // test only persistent members for any specified constraints
368: return ((owner == null)
369: && ((constraints == null) || constraints.isEmpty()) && ((constraintsRefs == null) || constraintsRefs
370: .isEmpty()));
371: }
372: }
|