View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.jetspeed.om.page.psml;
18  
19  import java.util.ArrayList;
20  import java.util.Collections;
21  import java.util.Iterator;
22  import java.util.List;
23  
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  import org.apache.jetspeed.om.common.SecurityConstraints;
27  import org.apache.jetspeed.om.page.PageSecurity;
28  import org.apache.jetspeed.om.page.SecurityConstraintImpl;
29  import org.apache.jetspeed.om.page.SecurityConstraintsDef;
30  
31  /***
32   * <p>
33   * SecurityConstraintsImpl
34   * </p>
35   * <p>
36   *
37   * </p>
38   * @author <a href="mailto:rwatler@finali.com">Randy Watler</a>
39   * @version $Id: SecurityConstraintsImpl.java 568811 2007-08-23 03:00:37Z woonsan $
40   *
41   */
42  public class SecurityConstraintsImpl implements SecurityConstraints
43  {
44      private final static Log log = LogFactory.getLog(SecurityConstraintsImpl.class);
45  
46      private String owner;
47  
48      private List constraints;
49  
50      private List constraintsRefs;
51  
52      private List allConstraints;
53  
54      /***
55       * <p>
56       * getOwner
57       * </p>
58       *
59       * @see org.apache.jetspeed.om.common.SecurityConstraints#getOwner()
60       * @return
61       */
62      public String getOwner()
63      {
64          return owner;
65      }
66      
67      /***
68       * <p>
69       * setOwner
70       * </p>
71       *
72       * @see org.apache.jetspeed.om.common.SecurityConstraints#setOwner(java.lang.String)
73       * @param owner
74       */
75      public void setOwner(String owner)
76      {
77          this.owner = owner;
78      }
79  
80      /***
81       * <p>
82       * getSecurityConstraints
83       * </p>
84       *
85       * @see org.apache.jetspeed.om.common.SecurityConstraints#getSecurityConstraints()
86       * @return
87       */
88      public List getSecurityConstraints()
89      {
90          if (this.constraints == null)
91          {
92              this.constraints = Collections.synchronizedList(new ArrayList());
93          }                
94          return constraints;
95      }
96      
97      /***
98       * <p>
99       * setSecurityConstraint
100      * </p>
101      *
102      * @see org.apache.jetspeed.om.common.SecurityConstraints#setSecurityConstraints(java.util.List)
103      * @param constraints
104      */
105     public void setSecurityConstraints(List constraints)
106     {        
107         this.constraints = constraints;
108     }
109 
110     /***
111      * <p>
112      * getSecurityConstraintsRefs
113      * </p>
114      *
115      * @see org.apache.jetspeed.om.common.SecurityConstraints#getSecurityConstraintsRefs()
116      * @return
117      */
118     public List getSecurityConstraintsRefs()
119     {
120         if (this.constraintsRefs == null)
121         {
122             this.constraintsRefs = Collections.synchronizedList(new ArrayList());
123         }        
124         return constraintsRefs;
125     }
126     
127     /***
128      * <p>
129      * setSecurityConstraintsRefs
130      * </p>
131      *
132      * @see org.apache.jetspeed.om.common.SecurityConstraints#setSecurityConstraintsRefs(java.util.List)
133      * @param constraintsRefs
134      */
135     public void setSecurityConstraintsRefs(List constraintsRefs)
136     {
137         this.constraintsRefs = constraintsRefs;
138     }
139 
140     /***
141      * <p>
142      * isEmpty
143      * </p>
144      *
145      * @see org.apache.jetspeed.om.common.SecurityConstraints#isEmpty()
146      * @return flag indicating whether there are constraints or owner set
147      */
148     public boolean isEmpty()
149     {
150         return ((owner == null) && (constraints == null) && (constraintsRefs == null));
151     }
152 
153     /***
154      * <p>
155      * checkConstraints
156      * </p>
157      *
158      * @param actions
159      * @param userPrincipals
160      * @param rolePrincipals
161      * @param groupPrincipals
162      * @param pageSecurity page security definitions
163      * @throws SecurityException
164      */
165     public void checkConstraints(List actions, List userPrincipals, List rolePrincipals,
166                                  List groupPrincipals, PageSecurity pageSecurity) throws SecurityException
167     {
168         // if owner defined, override all constraints and allow all access
169         if ((owner != null) && (userPrincipals != null) && userPrincipals.contains(owner))
170         {
171             return;
172         }
173 
174         // skip missing or empty constraints: permit all access
175         List checkConstraints = getAllSecurityConstraints(pageSecurity);
176         if ((checkConstraints != null) && !checkConstraints.isEmpty())
177         {
178             // test each action, constraints check passes only
179             // if all actions are permitted for principals
180             Iterator actionsIter = actions.iterator();
181             while (actionsIter.hasNext())
182             {
183                 // check each action:
184                 // - if any actions explicity permitted, assume no permissions
185                 //   are permitted by default
186                 // - if all constraints do not specify a permission, assume
187                 //   access is permitted by default
188                 String action = (String)actionsIter.next();
189                 boolean actionPermitted = false;
190                 boolean actionNotPermitted = false;
191                 boolean anyActionsPermitted = false;
192                 
193                 // check against constraints
194                 Iterator checkConstraintsIter = checkConstraints.iterator();
195                 while (checkConstraintsIter.hasNext())
196                 {
197                     SecurityConstraintImpl constraint = (SecurityConstraintImpl)checkConstraintsIter.next();
198                     
199                     // if permissions specified, attempt to match constraint
200                     if (constraint.getPermissions() != null)
201                     {
202                         // explicit actions permitted
203                         anyActionsPermitted = true;
204 
205                         // test action permission match and user/role/group principal match
206                         if (constraint.actionMatch(action) &&
207                             constraint.principalsMatch(userPrincipals, rolePrincipals, groupPrincipals, true))
208                         {
209                             actionPermitted = true;
210                             break;
211                         }
212                     }
213                     else
214                     {
215                         // permissions not specified: not permitted if any principal matched
216                         if (constraint.principalsMatch(userPrincipals, rolePrincipals, groupPrincipals, false))
217                         {
218                             actionNotPermitted = true;
219                             break;
220                         }
221                     }
222                 }
223                 
224                 // fail if any action not permitted
225                 if ((!actionPermitted && anyActionsPermitted) || actionNotPermitted)
226                 {
227                     throw new SecurityException("SecurityConstraintsImpl.checkConstraints(): Access for " + action + " not permitted.");
228                 }
229             }
230         }
231     }
232 
233     /***
234      * <p>
235      * getAllSecurityConstraints
236      * </p>
237      *
238      * @param pageSecurity
239      * @return all security constraints
240      */
241     private synchronized List getAllSecurityConstraints(PageSecurity pageSecurity)
242     {
243         // return previously cached security constraints; note that
244         // cache is assumed valid until owning document is evicted
245         if (allConstraints != null)
246         {
247             return allConstraints;
248         }
249 
250         // construct new ordered security constraints list
251         allConstraints = Collections.synchronizedList(new ArrayList(8));
252 
253         // add any defined security constraints
254         if (constraints != null)
255         {
256             allConstraints.addAll(constraints);
257         }
258 
259         // add any security constraints references
260         if ((constraintsRefs != null) && !constraintsRefs.isEmpty())
261         {
262             List referencedConstraints = dereferenceSecurityConstraintsRefs(constraintsRefs, pageSecurity);
263             if (referencedConstraints != null)
264             {
265                 allConstraints.addAll(referencedConstraints);
266             }
267         }
268 
269         // add any global decurity constraints references
270         if (pageSecurity != null)
271         {
272             List globalConstraintsRefs = pageSecurity.getGlobalSecurityConstraintsRefs();
273             if ((globalConstraintsRefs != null) && !globalConstraintsRefs.isEmpty())
274             {
275                 List referencedConstraints = dereferenceSecurityConstraintsRefs(globalConstraintsRefs, pageSecurity);
276                 if (referencedConstraints != null)
277                 {
278                     allConstraints.addAll(referencedConstraints);
279                 }
280             }
281         }   
282 
283         return allConstraints;
284     }
285 
286     /***
287      * <p>
288      * dereferenceSecurityConstraintsRefs
289      * </p>
290      *
291      * @param constraintsRefs
292      * @param pageSecurity
293      * @return security constraints
294      */
295     private List dereferenceSecurityConstraintsRefs(List constraintsRefs, PageSecurity pageSecurity)
296     {
297         // access security document to dereference security
298         // constriants definitions
299         List constraints = null;
300         if (pageSecurity != null)
301         {   
302             // dereference each security constraints definition
303             Iterator constraintsRefsIter = constraintsRefs.iterator();
304             while (constraintsRefsIter.hasNext())
305             {
306                 String constraintsRef = (String)constraintsRefsIter.next();
307                 SecurityConstraintsDef securityConstraintsDef = pageSecurity.getSecurityConstraintsDef(constraintsRef);
308                 if ((securityConstraintsDef != null) && (securityConstraintsDef.getSecurityConstraints() != null))
309                 {
310                     if (constraints == null)
311                     {
312                         constraints = Collections.synchronizedList(new ArrayList(constraintsRefs.size()));
313                     }
314                     constraints.addAll(securityConstraintsDef.getSecurityConstraints());
315                 }
316                 else
317                 {
318                     log.error("dereferenceSecurityConstraintsRefs(): Unable to dereference \"" + constraintsRef + "\" security constraints definition.");
319                 }
320             }
321         }
322         else
323         {
324             log.error("dereferenceSecurityConstraintsRefs(): Missing page security, unable to dereference security constraints definitions.");
325         }
326         
327         return constraints;
328     }
329 }