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.psml;
018:
019: import java.util.ArrayList;
020: import java.util.Collections;
021: import java.util.Iterator;
022: import java.util.List;
023:
024: import org.apache.commons.logging.Log;
025: import org.apache.commons.logging.LogFactory;
026: import org.apache.jetspeed.om.common.SecurityConstraints;
027: import org.apache.jetspeed.om.page.PageSecurity;
028: import org.apache.jetspeed.om.page.SecurityConstraintImpl;
029: import org.apache.jetspeed.om.page.SecurityConstraintsDef;
030:
031: /**
032: * <p>
033: * SecurityConstraintsImpl
034: * </p>
035: * <p>
036: *
037: * </p>
038: * @author <a href="mailto:rwatler@finali.com">Randy Watler</a>
039: * @version $Id: SecurityConstraintsImpl.java 568811 2007-08-23 03:00:37Z woonsan $
040: *
041: */
042: public class SecurityConstraintsImpl implements SecurityConstraints {
043: private final static Log log = LogFactory
044: .getLog(SecurityConstraintsImpl.class);
045:
046: private String owner;
047:
048: private List constraints;
049:
050: private List constraintsRefs;
051:
052: private List allConstraints;
053:
054: /**
055: * <p>
056: * getOwner
057: * </p>
058: *
059: * @see org.apache.jetspeed.om.common.SecurityConstraints#getOwner()
060: * @return
061: */
062: public String getOwner() {
063: return owner;
064: }
065:
066: /**
067: * <p>
068: * setOwner
069: * </p>
070: *
071: * @see org.apache.jetspeed.om.common.SecurityConstraints#setOwner(java.lang.String)
072: * @param owner
073: */
074: public void setOwner(String owner) {
075: this .owner = owner;
076: }
077:
078: /**
079: * <p>
080: * getSecurityConstraints
081: * </p>
082: *
083: * @see org.apache.jetspeed.om.common.SecurityConstraints#getSecurityConstraints()
084: * @return
085: */
086: public List getSecurityConstraints() {
087: if (this .constraints == null) {
088: this .constraints = Collections
089: .synchronizedList(new ArrayList());
090: }
091: return constraints;
092: }
093:
094: /**
095: * <p>
096: * setSecurityConstraint
097: * </p>
098: *
099: * @see org.apache.jetspeed.om.common.SecurityConstraints#setSecurityConstraints(java.util.List)
100: * @param constraints
101: */
102: public void setSecurityConstraints(List constraints) {
103: this .constraints = constraints;
104: }
105:
106: /**
107: * <p>
108: * getSecurityConstraintsRefs
109: * </p>
110: *
111: * @see org.apache.jetspeed.om.common.SecurityConstraints#getSecurityConstraintsRefs()
112: * @return
113: */
114: public List getSecurityConstraintsRefs() {
115: if (this .constraintsRefs == null) {
116: this .constraintsRefs = Collections
117: .synchronizedList(new ArrayList());
118: }
119: return constraintsRefs;
120: }
121:
122: /**
123: * <p>
124: * setSecurityConstraintsRefs
125: * </p>
126: *
127: * @see org.apache.jetspeed.om.common.SecurityConstraints#setSecurityConstraintsRefs(java.util.List)
128: * @param constraintsRefs
129: */
130: public void setSecurityConstraintsRefs(List constraintsRefs) {
131: this .constraintsRefs = constraintsRefs;
132: }
133:
134: /**
135: * <p>
136: * isEmpty
137: * </p>
138: *
139: * @see org.apache.jetspeed.om.common.SecurityConstraints#isEmpty()
140: * @return flag indicating whether there are constraints or owner set
141: */
142: public boolean isEmpty() {
143: return ((owner == null) && (constraints == null) && (constraintsRefs == null));
144: }
145:
146: /**
147: * <p>
148: * checkConstraints
149: * </p>
150: *
151: * @param actions
152: * @param userPrincipals
153: * @param rolePrincipals
154: * @param groupPrincipals
155: * @param pageSecurity page security definitions
156: * @throws SecurityException
157: */
158: public void checkConstraints(List actions, List userPrincipals,
159: List rolePrincipals, List groupPrincipals,
160: PageSecurity pageSecurity) throws SecurityException {
161: // if owner defined, override all constraints and allow all access
162: if ((owner != null) && (userPrincipals != null)
163: && userPrincipals.contains(owner)) {
164: return;
165: }
166:
167: // skip missing or empty constraints: permit all access
168: List checkConstraints = getAllSecurityConstraints(pageSecurity);
169: if ((checkConstraints != null) && !checkConstraints.isEmpty()) {
170: // test each action, constraints check passes only
171: // if all actions are permitted for principals
172: Iterator actionsIter = actions.iterator();
173: while (actionsIter.hasNext()) {
174: // check each action:
175: // - if any actions explicity permitted, assume no permissions
176: // are permitted by default
177: // - if all constraints do not specify a permission, assume
178: // access is permitted by default
179: String action = (String) actionsIter.next();
180: boolean actionPermitted = false;
181: boolean actionNotPermitted = false;
182: boolean anyActionsPermitted = false;
183:
184: // check against constraints
185: Iterator checkConstraintsIter = checkConstraints
186: .iterator();
187: while (checkConstraintsIter.hasNext()) {
188: SecurityConstraintImpl constraint = (SecurityConstraintImpl) checkConstraintsIter
189: .next();
190:
191: // if permissions specified, attempt to match constraint
192: if (constraint.getPermissions() != null) {
193: // explicit actions permitted
194: anyActionsPermitted = true;
195:
196: // test action permission match and user/role/group principal match
197: if (constraint.actionMatch(action)
198: && constraint.principalsMatch(
199: userPrincipals, rolePrincipals,
200: groupPrincipals, true)) {
201: actionPermitted = true;
202: break;
203: }
204: } else {
205: // permissions not specified: not permitted if any principal matched
206: if (constraint.principalsMatch(userPrincipals,
207: rolePrincipals, groupPrincipals, false)) {
208: actionNotPermitted = true;
209: break;
210: }
211: }
212: }
213:
214: // fail if any action not permitted
215: if ((!actionPermitted && anyActionsPermitted)
216: || actionNotPermitted) {
217: throw new SecurityException(
218: "SecurityConstraintsImpl.checkConstraints(): Access for "
219: + action + " not permitted.");
220: }
221: }
222: }
223: }
224:
225: /**
226: * <p>
227: * getAllSecurityConstraints
228: * </p>
229: *
230: * @param pageSecurity
231: * @return all security constraints
232: */
233: private synchronized List getAllSecurityConstraints(
234: PageSecurity pageSecurity) {
235: // return previously cached security constraints; note that
236: // cache is assumed valid until owning document is evicted
237: if (allConstraints != null) {
238: return allConstraints;
239: }
240:
241: // construct new ordered security constraints list
242: allConstraints = Collections.synchronizedList(new ArrayList(8));
243:
244: // add any defined security constraints
245: if (constraints != null) {
246: allConstraints.addAll(constraints);
247: }
248:
249: // add any security constraints references
250: if ((constraintsRefs != null) && !constraintsRefs.isEmpty()) {
251: List referencedConstraints = dereferenceSecurityConstraintsRefs(
252: constraintsRefs, pageSecurity);
253: if (referencedConstraints != null) {
254: allConstraints.addAll(referencedConstraints);
255: }
256: }
257:
258: // add any global decurity constraints references
259: if (pageSecurity != null) {
260: List globalConstraintsRefs = pageSecurity
261: .getGlobalSecurityConstraintsRefs();
262: if ((globalConstraintsRefs != null)
263: && !globalConstraintsRefs.isEmpty()) {
264: List referencedConstraints = dereferenceSecurityConstraintsRefs(
265: globalConstraintsRefs, pageSecurity);
266: if (referencedConstraints != null) {
267: allConstraints.addAll(referencedConstraints);
268: }
269: }
270: }
271:
272: return allConstraints;
273: }
274:
275: /**
276: * <p>
277: * dereferenceSecurityConstraintsRefs
278: * </p>
279: *
280: * @param constraintsRefs
281: * @param pageSecurity
282: * @return security constraints
283: */
284: private List dereferenceSecurityConstraintsRefs(
285: List constraintsRefs, PageSecurity pageSecurity) {
286: // access security document to dereference security
287: // constriants definitions
288: List constraints = null;
289: if (pageSecurity != null) {
290: // dereference each security constraints definition
291: Iterator constraintsRefsIter = constraintsRefs.iterator();
292: while (constraintsRefsIter.hasNext()) {
293: String constraintsRef = (String) constraintsRefsIter
294: .next();
295: SecurityConstraintsDef securityConstraintsDef = pageSecurity
296: .getSecurityConstraintsDef(constraintsRef);
297: if ((securityConstraintsDef != null)
298: && (securityConstraintsDef
299: .getSecurityConstraints() != null)) {
300: if (constraints == null) {
301: constraints = Collections
302: .synchronizedList(new ArrayList(
303: constraintsRefs.size()));
304: }
305: constraints.addAll(securityConstraintsDef
306: .getSecurityConstraints());
307: } else {
308: log
309: .error("dereferenceSecurityConstraintsRefs(): Unable to dereference \""
310: + constraintsRef
311: + "\" security constraints definition.");
312: }
313: }
314: } else {
315: log
316: .error("dereferenceSecurityConstraintsRefs(): Missing page security, unable to dereference security constraints definitions.");
317: }
318:
319: return constraints;
320: }
321: }
|