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.impl;
18  
19  import java.util.Iterator;
20  import java.util.List;
21  
22  import org.apache.jetspeed.om.common.SecurityConstraints;
23  import org.apache.jetspeed.om.page.PageSecurity;
24  import org.apache.jetspeed.om.page.SecurityConstraintImpl;
25  import org.apache.jetspeed.om.page.SecurityConstraintsDef;
26  import org.apache.jetspeed.page.impl.DatabasePageManagerUtils;
27  
28  /***
29   * SecurityConstraintsImpl
30   *
31   * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
32   * @version $Id$
33   */
34  public class SecurityConstraintsImpl implements SecurityConstraints
35  {
36      private String owner;
37      private List constraints;
38      private List constraintsRefs;
39  
40      private SecurityConstraintList securityConstraints;
41      private SecurityConstraintsRefList securityConstraintsRefs;
42  
43      private List allConstraints;
44  
45      /***
46       * accessConstraintsRefs
47       *
48       * Access mutable persistent collection member for List wrappers.
49       *
50       * @return persistent collection
51       */
52      List accessConstraintsRefs()
53      {
54          // create initial collection if necessary
55          if (constraintsRefs == null)
56          {
57              constraintsRefs = DatabasePageManagerUtils.createList();
58          }
59          return constraintsRefs;
60      }
61  
62      /***
63       * accessConstraints
64       *
65       * Access mutable persistent collection member for List wrappers.
66       *
67       * @return persistent collection
68       */
69      List accessConstraints()
70      {
71          // create initial collection if necessary
72          if (constraints == null)
73          {
74              constraints = DatabasePageManagerUtils.createList();
75          }
76          return constraints;
77      }
78  
79      /***
80       * getSecurityConstraintClass
81       *
82       * Return class of persistent constraint instance.
83       *
84       * @return constraint class
85       */
86      public Class getSecurityConstraintClass()
87      {
88          // none by default
89          return null;
90      }
91  
92      /***
93       * getSecurityConstraintsRefClass
94       *
95       * Return class of persistent constraints reference instance.
96       *
97       * @return constraints reference class
98       */
99      public Class getSecurityConstraintsRefClass()
100     {
101         // none by default
102         return null;
103     }
104 
105     /***
106      * checkConstraints
107      *
108      * @param actions actions to check
109      * @param userPrincipals principal users list
110      * @param rolePrincipals principal roles list
111      * @param groupPrincipals principal group list
112      * @param pageSecurity page security definitions
113      * @throws SecurityException
114      */
115     public void checkConstraints(List actions, List userPrincipals, List rolePrincipals, List groupPrincipals, PageSecurity pageSecurity) throws SecurityException
116     {
117         // if owner defined, override all constraints and allow all access
118         if ((owner != null) && (userPrincipals != null) && userPrincipals.contains(owner))
119         {
120             return;
121         }
122 
123         // skip missing or empty constraints: permit all access
124         List checkConstraints = getAllSecurityConstraints(pageSecurity);
125         if ((checkConstraints != null) && !checkConstraints.isEmpty())
126         {
127             // test each action, constraints check passes only
128             // if all actions are permitted for principals
129             Iterator actionsIter = actions.iterator();
130             while (actionsIter.hasNext())
131             {
132                 // check each action:
133                 // - if any actions explicity permitted, (including owner),
134                 //   assume no permissions are permitted by default
135                 // - if all constraints do not specify a permission, assume
136                 //   access is permitted by default
137                 String action = (String)actionsIter.next();
138                 boolean actionPermitted = false;
139                 boolean actionNotPermitted = false;
140                 boolean anyActionsPermitted = (getOwner() != null);
141                 
142                 // check against constraints
143                 Iterator checkConstraintsIter = checkConstraints.iterator();
144                 while (checkConstraintsIter.hasNext())
145                 {
146                     SecurityConstraintImpl constraint = (SecurityConstraintImpl)checkConstraintsIter.next();
147                     
148                     // if permissions specified, attempt to match constraint
149                     if (constraint.getPermissions() != null)
150                     {
151                         // explicit actions permitted
152                         anyActionsPermitted = true;
153 
154                         // test action permission match and user/role/group principal match
155                         if (constraint.actionMatch(action) &&
156                             constraint.principalsMatch(userPrincipals, rolePrincipals, groupPrincipals, true))
157                         {
158                             actionPermitted = true;
159                             break;
160                         }
161                     }
162                     else
163                     {
164                         // permissions not specified: not permitted if any principal matched
165                         if (constraint.principalsMatch(userPrincipals, rolePrincipals, groupPrincipals, false))
166                         {
167                             actionNotPermitted = true;
168                             break;
169                         }
170                     }
171                 }
172                 
173                 // fail if any action not permitted
174                 if ((!actionPermitted && anyActionsPermitted) || actionNotPermitted)
175                 {
176                     throw new SecurityException("SecurityConstraintsImpl.checkConstraints(): Access for " + action + " not permitted.");
177                 }
178             }
179         }
180         else
181         {
182             // fail for any action if owner specified
183             // since no other constraints were found
184             if ((getOwner() != null) && !actions.isEmpty())
185             {
186                 String action = (String)actions.get(0);
187                 throw new SecurityException("SecurityConstraintsImpl.checkConstraints(): Access for " + action + " not permitted, (not owner).");
188             }
189         }
190     }
191 
192     /***
193      * resetCachedSecurityConstraints
194      */
195     public void resetCachedSecurityConstraints()
196     {
197         // clear previously cached security constraints
198         clearAllSecurityConstraints();
199     }
200 
201     /***
202      * getAllSecurityConstraints
203      *
204      * @param pageSecurity page security definitions
205      * @return all security constraints
206      */
207     private synchronized List getAllSecurityConstraints(PageSecurity pageSecurity)
208     {
209         // return previously cached security constraints
210         if (allConstraints != null)
211         {
212             return allConstraints;
213         }
214 
215         // construct new ordered security constraints list
216         allConstraints = DatabasePageManagerUtils.createList();
217 
218         // add any defined security constraints
219         if ((getSecurityConstraints() != null) && !getSecurityConstraints().isEmpty())
220         {
221             allConstraints.addAll(securityConstraints);
222         }
223 
224         // add any security constraints references
225         if ((getSecurityConstraintsRefs() != null) && !getSecurityConstraintsRefs().isEmpty())
226         {
227             List referencedConstraints = dereferenceSecurityConstraintsRefs(getSecurityConstraintsRefs(), pageSecurity);
228             if (referencedConstraints != null)
229             {
230                 allConstraints.addAll(referencedConstraints);
231             }
232         }
233         
234         // add any global decurity constraints references
235         if (pageSecurity != null)
236         {
237             List globalConstraintsRefs = pageSecurity.getGlobalSecurityConstraintsRefs();
238             if ((globalConstraintsRefs != null) && !globalConstraintsRefs.isEmpty())
239             {
240                 List referencedConstraints = dereferenceSecurityConstraintsRefs(globalConstraintsRefs, pageSecurity);
241                 if (referencedConstraints != null)
242                 {
243                     allConstraints.addAll(referencedConstraints);
244                 }
245             }
246         }
247         
248         return allConstraints;
249     }
250 
251     /***
252      * clearAllSecurityConstraints
253      */
254     synchronized void clearAllSecurityConstraints()
255     {
256         // clear previously cached security constraints
257         allConstraints = null;
258     }
259 
260     /***
261      * dereferenceSecurityConstraintsRefs
262      *
263      * @param constraintsRefs contstraints references to be dereferenced
264      * @param pageSecurity page security definitions
265      * @return security constraints
266      */
267     private List dereferenceSecurityConstraintsRefs(List constraintsRefs, PageSecurity pageSecurity)
268     {
269         List constraints = null;
270         if (pageSecurity != null)
271         {   
272             // dereference each security constraints definition
273             Iterator constraintsRefsIter = constraintsRefs.iterator();
274             while (constraintsRefsIter.hasNext())
275             {
276                 String constraintsRef = (String)constraintsRefsIter.next();
277                 SecurityConstraintsDef securityConstraintsDef = pageSecurity.getSecurityConstraintsDef(constraintsRef);
278                 if ((securityConstraintsDef != null) && (securityConstraintsDef.getSecurityConstraints() != null))
279                 {
280                     if (constraints == null)
281                     {
282                         constraints = DatabasePageManagerUtils.createList();
283                     }
284                     constraints.addAll(securityConstraintsDef.getSecurityConstraints());
285                 }
286             }
287         }
288         return constraints;
289     }
290 
291     /* (non-Javadoc)
292      * @see org.apache.jetspeed.om.common.SecurityConstraints#getOwner()
293      */
294     public String getOwner()
295     {
296         return owner;
297     }
298     
299     /* (non-Javadoc)
300      * @see org.apache.jetspeed.om.common.SecurityConstraints#setOwner(java.lang.String)
301      */
302     public void setOwner(String owner)
303     {
304         // save new setting and reset cached security constraints
305         this.owner = owner;
306         clearAllSecurityConstraints();
307     }
308 
309     /* (non-Javadoc)
310      * @see org.apache.jetspeed.om.common.SecurityConstraints#getSecurityConstraints()
311      */
312     public List getSecurityConstraints()
313     {
314         // return mutable inline constraint list
315         // by using list wrapper to manage apply order
316         if (securityConstraints == null)
317         {
318             securityConstraints = new SecurityConstraintList(this);
319         }
320         return securityConstraints;
321     }
322     
323     /* (non-Javadoc)
324      * @see org.apache.jetspeed.om.common.SecurityConstraints#setSecurityConstraints(java.util.List)
325      */
326     public void setSecurityConstraints(List constraints)
327     {
328         // set inline constraints by replacing existing
329         // entries with new elements if new collection
330         // is specified
331         List securityConstraints = getSecurityConstraints();
332         if (constraints != securityConstraints)
333         {
334             // replace all constraints
335             securityConstraints.clear();
336             if (constraints != null)
337             {
338                 securityConstraints.addAll(constraints);
339             }
340         }
341         // reset cached security constraints
342         clearAllSecurityConstraints();
343     }
344 
345     /* (non-Javadoc)
346      * @see org.apache.jetspeed.om.common.SecurityConstraints#getSecurityConstraintsRefs()
347      */
348     public List getSecurityConstraintsRefs()
349     {
350         // return mutable constraints refs list
351         // by using list wrapper to manage apply
352         // order and element uniqueness
353         if (securityConstraintsRefs == null)
354         {
355             securityConstraintsRefs = new SecurityConstraintsRefList(this);
356         }
357         return securityConstraintsRefs;
358     }
359     
360     /* (non-Javadoc)
361      * @see org.apache.jetspeed.om.common.SecurityConstraints#setSecurityConstraintsRefs(java.util.List)
362      */
363     public void setSecurityConstraintsRefs(List constraintsRefs)
364     {
365         // set constraints refs using ordered ref
366         // names by replacing existing entries with
367         // new elements if new collection is specified
368         List securityConstraintsRefs = getSecurityConstraintsRefs();
369         if (constraintsRefs != securityConstraintsRefs)
370         {
371             // replace all constraints ref names
372             securityConstraintsRefs.clear();
373             if (constraintsRefs != null)
374             {
375                 securityConstraintsRefs.addAll(constraintsRefs);
376             }
377         }
378         // reset cached security constraints
379         clearAllSecurityConstraints();
380     }
381 
382     /* (non-Javadoc)
383      * @see org.apache.jetspeed.om.common.SecurityConstraints#isEmpty()
384      */
385     public boolean isEmpty()
386     {
387         // test only persistent members for any specified constraints
388         return ((owner == null) &&
389                 ((constraints == null) || constraints.isEmpty()) &&
390                 ((constraintsRefs == null) || constraintsRefs.isEmpty()));
391     }
392 }