View Javadoc
1   package org.apache.fulcrum.security.model.turbine;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.HashMap;
23  import java.util.Map;
24  import java.util.Set;
25  
26  import org.apache.avalon.framework.logger.Logger;
27  import org.apache.fulcrum.security.GroupManager;
28  import org.apache.fulcrum.security.RoleManager;
29  import org.apache.fulcrum.security.entity.Group;
30  import org.apache.fulcrum.security.entity.Permission;
31  import org.apache.fulcrum.security.entity.Role;
32  import org.apache.fulcrum.security.model.turbine.entity.TurbineRole;
33  import org.apache.fulcrum.security.model.turbine.entity.TurbineUserGroupRole;
34  import org.apache.fulcrum.security.util.FulcrumSecurityException;
35  import org.apache.fulcrum.security.util.GroupSet;
36  import org.apache.fulcrum.security.util.PermissionSet;
37  import org.apache.fulcrum.security.util.RoleSet;
38  
39  /**
40   * This is a control class that makes it easy to find out if a
41   * particular User has a given Permission.  It also determines if a
42   * User has a a particular Role.
43   *
44   * @author <a href="mailto:jmcnally@collab.net">John D. McNally</a>
45   * @author <a href="mailto:bmclaugh@algx.net">Brett McLaughlin</a>
46   * @author <a href="mailto:greg@shwoop.com">Greg Ritter</a>
47   * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
48   * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
49   * @author <a href="mailto:marco@intermeta.de">Marco Kn&uuml;ttel</a>
50   * @version $Id: TurbineAccessControlList.java 1096130 2019-03-25 10:37:19Z painter $
51   */
52  @SuppressWarnings("rawtypes")
53  public class TurbineAccessControlListImpl
54          implements TurbineAccessControlList
55  {
56      /** Serial version */
57  	private static final long serialVersionUID = 2678947159949477950L;
58  
59      /** The sets of roles that the user has in different groups */
60      private Map<Group, RoleSet> roleSets;
61      
62      /** The sets of permissions that the user has in different groups */
63      private Map<Group, PermissionSet> permissionSets;
64      
65      /** The global group */
66      private Group globalGroup;
67      
68      /** The group manager */
69      private GroupManager groupManager;
70      
71      /** The distinct list of groups that this user is part of */
72      private GroupSety/util/GroupSet.html#GroupSet">GroupSet groupSet = new GroupSet();
73      
74      /** The distinct list of roles that this user is part of */
75      private RoleSetity/util/RoleSet.html#RoleSet">RoleSet roleSet = new RoleSet();
76      
77      /** the distinct list of permissions that this user has */
78      private PermissionSetmissionSet.html#PermissionSet">PermissionSet permissionSet = new PermissionSet();
79      
80      /** the Avalon logger */
81      private transient Logger logger;
82  
83      /**
84       * Constructs a new AccessControlList.
85       *
86       * This class follows 'immutable' pattern - it's objects can't be modified
87       * once they are created. This means that the permissions the users have are
88       * in effect form the moment they log in to the moment they log out, and
89       * changes made to the security settings in that time are not reflected
90       * in the state of this object. If you need to reset an user's permissions
91       * you need to invalidate his session. <br>
92       *
93       * @param turbineUserGroupRoleSet
94       *            The set of user/group/role relations that this acl is built from
95       * @param groupManager the Group manager
96       * @param roleManager the Role manager
97       * @param modelManager the model Manager
98       * @param logger 
99       *
100      * @throws FulcrumSecurityException if the global group cannot be retrieved
101      */
102     public TurbineAccessControlListImpl(
103     		Set<? extends TurbineUserGroupRole> turbineUserGroupRoleSet,
104     		GroupManager groupManager, RoleManager roleManager, TurbineModelManager modelManager, Logger logger) throws FulcrumSecurityException
105     {
106         this.roleSets = new HashMap<Group, RoleSet>();
107         this.permissionSets = new HashMap<Group, PermissionSet>();
108         this.groupManager = groupManager;
109         
110         this.logger = logger;
111 
112         for (TurbineUserGroupRole ugr : turbineUserGroupRoleSet)
113         {
114             Group group = ugr.getGroup();
115             // check if group matches
116             if (this.logger != null && this.groupManager != null && group.getClass() != this.groupManager.getGroupInstance().getClass()) {
117                 this.logger.warn( "Turbine group classes do not match, some lookup might fail, check in componentConfiguration.xml. Expected class: " +
118                         this.groupManager.getGroupInstance().getClass() + ", actual class: " +group.getClass()
119             );
120             }
121             groupSet.add(group);
122 
123             Role role = ugr.getRole();
124             if (!roleSet.containsId(role.getId()))
125             {
126                 // get fresh reference from role manager to make sure the related
127                 // permissions are populated
128                 if (roleManager != null)
129                 {
130                     role = roleManager.getRoleById(role.getId());
131                 }
132                 roleSet.add(role);
133             }
134             else
135             {
136                 role = roleSet.getById(role.getId());
137             }
138             if (roleSets.containsKey(group))
139             {
140             	roleSets.get(group).add(role);
141             }
142             else
143             {
144             	RoleSet rs = new RoleSet();
145             	rs.add(role);
146             	roleSets.put(group, rs);
147             }
148             // if required, otherwise skip
149             if (role instanceof TurbineRole) {
150 	            PermissionSet ps = ((TurbineRole) role).getPermissions();
151 	            permissionSet.add(ps);
152 	            if (permissionSets.containsKey(group))
153 	            {
154 	            	permissionSets.get(group).add(ps);
155 	            }
156 	            else
157 	            {
158 	            	permissionSets.put(group, ps);
159 	            }
160             }
161         }
162         // this check might be not needed any more, required for custom group
163         if (modelManager != null)
164         {
165         	this.globalGroup = modelManager.getGlobalGroup();
166         }
167     }
168 
169     /**
170      * Retrieves a set of Roles an user is assigned in a Group.
171      *
172      * @param group the Group
173      * @return the set of Roles this user has within the Group.
174      */
175     @Override
176     public RoleSet getRoles(Group group)
177     {
178         if (group == null)
179         {
180             return null;
181         }
182         return roleSets.get(group);
183     }
184 
185     /**
186      * Retrieves a set of Roles an user is assigned in the global Group.
187      *
188      * @return the set of Roles this user has within the global Group or null.
189      */
190     @Override
191     public RoleSet getRoles()
192     {
193         return getRoles(globalGroup);
194     }
195 
196     /**
197      * Retrieves a set of Permissions an user is assigned in a Group.
198      *
199      * @param group the Group
200      * @return the set of Permissions this user has within the Group.
201      */
202     @Override
203     public PermissionSet getPermissions(Group group)
204     {
205         if (group == null)
206         {
207             return null;
208         }
209         return permissionSets.get(group);
210     }
211 
212     /**
213      * Retrieves a set of Permissions an user is assigned in the global Group.
214      *
215      * @return the set of Permissions this user has within the global Group.
216      */
217     @Override
218     public PermissionSet getPermissions()
219     {
220         return getPermissions(globalGroup);
221     }
222 
223     /**
224      * Checks if the user is assigned a specific Role in the Group.
225      *
226      * @param role the Role
227      * @param group the Group
228      * @return <code>true</code> if the user is assigned the Role in the Group.
229      */
230     @Override
231     public boolean hasRole(Role role, Group group)
232     {
233         RoleSet set = getRoles(group);
234         if (set == null || role == null)
235         {
236             return false;
237         }
238         return set.contains(role);
239     }
240 
241     /**
242      * Checks if the user is assigned a specific Role in any of the given
243      * Groups
244      *
245      * @param role the Role
246      * @param groupset a Groupset
247      * @return <code>true</code> if the user is assigned the Role in any of
248      *         the given Groups.
249      */
250     @Override
251     public boolean hasRole(Role role, GroupSet groupset)
252     {
253         if (role == null)
254         {
255             return false;
256         }
257 
258         for (Group group : groupset)
259         {
260             RoleSet roles = getRoles(group);
261             if (roles != null && roles.contains(role))
262             {
263                 return true;
264             }
265         }
266 
267         return false;
268     }
269 
270     /**
271      * Checks if the user is assigned a specific Role in the Group.
272      *
273      * @param roleName the Role name
274      * @param groupName the Group name
275      * @return <code>true</code> if the user is assigned the Role in the Group.
276      */
277     @Override
278     public boolean hasRole(String roleName, String groupName)
279     {
280         try
281         {
282         	return hasRole(roleSet.getByName(roleName), groupSet.getByName(groupName));
283         }
284         catch (Exception e)
285         {
286             return false;
287         }
288     }
289 
290     /**
291      * Checks if the user is assigned a specific Role in any of the given
292      * Groups
293      *
294      * @param rolename the name of the Role
295      * @param groupset a Groupset
296      * @return <code>true</code> if the user is assigned the Role in any of
297      *         the given Groups.
298      */
299     @Override
300     public boolean hasRole(String rolename, GroupSet groupset)
301     {
302         try
303         {
304         	return hasRole(roleSet.getByName(rolename), groupset);
305         }
306         catch (Exception e)
307         {
308             return false;
309         }
310     }
311 
312     /**
313      * Checks if the user is assigned a specific Role in the global Group.
314      *
315      * @param role the Role
316      * @return <code>true</code> if the user is assigned the Role in the global Group.
317      */
318     @Override
319     public boolean hasRole(Role role)
320     {
321         return hasRole(role, globalGroup);
322     }
323 
324     /**
325      * Checks if the user is assigned a specific Role in the global Group.
326      *
327      * @param role the Role
328      * @return <code>true</code> if the user is assigned the Role in the global Group.
329      */
330     @Override
331     public boolean hasRole(String role)
332     {
333         try
334         {
335             return hasRole(roleSet.getByName(role));
336         }
337         catch (Exception e)
338         {
339             return false;
340         }
341     }
342 
343     /**
344      * Checks if the user is assigned a specific Permission in the Group.
345      *
346      * @param permission the Permission
347      * @param group the Group
348      * @return <code>true</code> if the user is assigned the Permission in the Group.
349      */
350     @Override
351     public boolean hasPermission(Permission permission, Group group)
352     {
353         PermissionSet set = getPermissions(group);
354         if (set == null || permission == null)
355         {
356             return false;
357         }
358         return set.contains(permission);
359     }
360 
361     /**
362      * Checks if the user is assigned a specific Permission in any of the given
363      * Groups
364      *
365      * @param permission the Permission
366      * @param groupset a Groupset
367      * @return <code>true</code> if the user is assigned the Permission in any
368      *         of the given Groups.
369      */
370     @Override
371     public boolean hasPermission(Permission permission, GroupSet groupset)
372     {
373         if (permission == null)
374         {
375             return false;
376         }
377 
378         for (Group group : groupset)
379         {
380             PermissionSet permissions = getPermissions(group);
381             if (permissions != null && permissions.contains(permission))
382             {
383                 return true;
384             }
385         }
386 
387         return false;
388     }
389 
390     /**
391      * Checks if the user is assigned a specific Permission in the Group.
392      *
393      * @param permission the Permission
394      * @param group the Group
395      * @return <code>true</code> if the user is assigned the Permission in the Group.
396      */
397     @Override
398     public boolean hasPermission(String permission, String group)
399     {
400         try
401         {
402             return hasPermission(permissionSet.getByName(permission), groupSet.getByName(group));
403         }
404         catch (Exception e)
405         {
406             return false;
407         }
408     }
409 
410     /**
411      * Checks if the user is assigned a specific Permission in the Group.
412      *
413      * @param permission the Permission
414      * @param group the Group
415      * @return <code>true</code> if the user is assigned the Permission in the Group.
416      */
417     @Override
418     public boolean hasPermission(String permission, Group group)
419     {
420         try
421         {
422             return hasPermission(permissionSet.getByName(permission), group);
423         }
424         catch (Exception e)
425         {
426             return false;
427         }
428     }
429 
430     /**
431      * Checks if the user is assigned a specific Permission in any of the given
432      * Groups
433      *
434      * @param permissionName the name of the Permission
435      * @param groupset a Groupset
436      * @return <code>true</code> if the user is assigned the Permission in any
437      *         of the given Groups.
438      */
439     @Override
440     public boolean hasPermission(String permissionName, GroupSet groupset)
441     {
442         Permission permission;
443         try
444         {
445             permission = permissionSet.getByName(permissionName);
446         }
447         catch (Exception e)
448         {
449             return false;
450         }
451         
452         if (permission == null)
453         {
454             return false;
455         }
456         
457         for (Group group : groupset)
458         {
459             PermissionSet permissions = getPermissions(group);
460             if (permissions != null && permissions.contains(permission))
461             {
462             	return true;
463             }
464         }
465         return false;
466     }
467 
468     /**
469      * Checks if the user is assigned a specific Permission in the global Group.
470      *
471      * @param permission the Permission
472      * @return <code>true</code> if the user is assigned the Permission in the global Group.
473      */
474     @Override
475     public boolean hasPermission(Permission permission)
476     {
477         return hasPermission(permission, globalGroup);
478     }
479 
480     /**
481      * Checks if the user is assigned a specific Permission in the global Group.
482      *
483      * @param permission the Permission
484      * @return <code>true</code> if the user is assigned the Permission in the global Group.
485      */
486     @Override
487     public boolean hasPermission(String permission)
488     {
489         try
490         {
491             return hasPermission(permissionSet.getByName(permission));
492         }
493         catch (Exception e)
494         {
495             return false;
496         }
497     }
498 
499     /**
500      * Returns all groups defined in the system.
501      *
502      * This is useful for debugging, when you want to display all roles
503      * and permissions an user is assigned. This method is needed
504      * because you can't call static methods of TurbineSecurity class
505      * from within WebMacro/Velocity template
506      *
507      * @return A Group [] of all groups in the system.
508      */
509     @Override
510     public Group[] getAllGroups()
511     {
512         try
513         {
514             return (groupManager != null)? groupManager.getAllGroups().toArray(new Group[0])
515                     : new Group[0];
516         }
517         catch (FulcrumSecurityException e)
518         {
519             return new Group[0];
520         }
521     }
522 
523     @Override
524     public GroupSet getGroupSet()
525     {
526         return groupSet;
527     }
528 }