001package org.apache.fulcrum.security.model.dynamic;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.util.Map;
023
024import org.apache.fulcrum.security.entity.Group;
025import org.apache.fulcrum.security.entity.Permission;
026import org.apache.fulcrum.security.entity.Role;
027import org.apache.fulcrum.security.util.GroupSet;
028import org.apache.fulcrum.security.util.PermissionSet;
029import org.apache.fulcrum.security.util.RoleSet;
030
031/**
032 * This is a control class that makes it easy to find out if a particular User
033 * has a given Permission. It also determines if a User has a a particular Role.
034 *
035 * @author <a href="mailto:epugh@upstate.com">Eric Pugh</a>
036 * @version $Id$
037 */
038public class DynamicAccessControlListImpl implements DynamicAccessControlList 
039{
040        // TODO Need to rethink the two maps.. Why not just a single list of groups?
041        // That would then cascade down to all the other roles and so on..
042
043        /**
044         * Serial number
045         */
046        private static final long serialVersionUID = -5180551537096244085L;
047
048        /** The sets of roles that the user has in different groups */
049        private Map<? extends Group, ? extends RoleSet> roleSets;
050        
051        /** The sets of permissions that the user has in different groups */
052        private Map<? extends Role, ? extends PermissionSet> permissionSets;
053        
054        /** The distinct list of groups that this user is part of */
055        private GroupSet groupSet = new GroupSet();
056        
057        /** The distinct list of roles that this user is part of */
058        private RoleSet roleSet = new RoleSet();
059        
060        /** the distinct list of permissions that this user has */
061        private PermissionSet permissionSet = new PermissionSet();
062
063        /**
064         * Constructs a new AccessControlList.
065         *
066         * This class follows 'immutable' pattern - it's objects can't be modified once
067         * they are created. This means that the permissions the users have are in
068         * effect form the moment they log in to the moment they log out, and changes
069         * made to the security settings in that time are not reflected in the state of
070         * this object. If you need to reset an user's permissions you need to
071         * invalidate his session. <br>
072         * The objects that constructs an AccessControlList must supply hashtables of
073         * role/permission sets keyed with group objects. <br>
074         *
075         * @param roleSets       a hashtable containing RoleSet objects keyed with Group
076         *                       objects
077         * @param permissionSets a hashtable containing PermissionSet objects keyed with
078         *                       Roles objects
079         */
080        public DynamicAccessControlListImpl(Map<? extends Group, ? extends RoleSet> roleSets,
081                        Map<? extends Role, ? extends PermissionSet> permissionSets) {
082                this.roleSets = roleSets;
083                this.permissionSets = permissionSets;
084                for (Map.Entry<? extends Group, ? extends RoleSet> entry : roleSets.entrySet()) 
085                {
086                        Group group = entry.getKey();
087                        groupSet.add(group);
088                        RoleSet rs = entry.getValue();
089                        roleSet.add(rs);
090                }
091                
092                for (Map.Entry<? extends Role, ? extends PermissionSet> entry : permissionSets.entrySet()) 
093                {
094                        Role role = entry.getKey();
095                        roleSet.add(role);
096                        PermissionSet ps = entry.getValue();
097                        permissionSet.add(ps);
098                }
099        }
100
101        /**
102         * Retrieves a set of Roles an user is assigned in a Group.
103         *
104         * @param group the Group
105         * @return the set of Roles this user has within the Group.
106         */
107        public RoleSet getRoles(Group group) {
108                if (group == null) 
109                {
110                        return null;
111                }
112
113                return roleSets.get(group);
114        }
115
116        /**
117         * Retrieves a set of Roles an user is assigned in the global Group.
118         *
119         * @return the set of Roles this user has within the global Group.
120         */
121        public RoleSet getRoles() {
122                return roleSet;
123        }
124
125        /**
126         * Retrieves a set of Permissions an user is assigned in a Group.
127         *
128         * @param group the Group
129         * @return the set of Permissions this user has within the Group.
130         */
131        public PermissionSet getPermissions(Group group) {
132                PermissionSet permissionSet = new PermissionSet();
133                if (roleSets.containsKey(group)) 
134                {
135                        for (Role role : roleSets.get(group)) 
136                        {
137                                if (permissionSets.containsKey(role)) 
138                                {
139                                        permissionSet.add(permissionSets.get(role));
140                                }
141                        }
142                }
143                return permissionSet;
144        }
145
146        /**
147         * Retrieves a set of Permissions an user is assigned in the global Group.
148         *
149         * @return the set of Permissions this user has within the global Group.
150         */
151        public PermissionSet getPermissions() {
152                return permissionSet;
153        }
154
155        /**
156         * Checks if the user is assigned a specific Role in the Group.
157         *
158         * @param role  the Role
159         * @param group the Group
160         * @return <code>true</code> if the user is assigned the Role in the Group.
161         */
162        public boolean hasRole(Role role, Group group) {
163                RoleSet set = getRoles(group);
164                if (set == null || role == null) 
165                {
166                        return false;
167                }
168                return set.contains(role);
169        }
170
171        /**
172         * Checks if the user is assigned a specific Role in any of the given Groups
173         *
174         * @param role     the Role
175         * @param groupset a Groupset
176         * @return <code>true</code> if the user is assigned the Role in any of the
177         *         given Groups.
178         */
179        public boolean hasRole(Role role, GroupSet groupset) {
180                if (role == null) 
181                {
182                        return false;
183                }
184
185                for (Group group : groupset) 
186                {
187                        RoleSet roles = getRoles(group);
188                        if (roles != null && roles.contains(role)) 
189                        {
190                                return true;
191                        }
192                }
193                return false;
194        }
195
196        /**
197         * Checks if the user is assigned a specific Role in the Group.
198         *
199         * @param role  the Role
200         * @param group the Group
201         * @return <code>true</code> if the user is assigned the Role in the Group.
202         */
203        public boolean hasRole(String role, String group) {
204                boolean roleFound = false;
205                try 
206                {
207                        for (Map.Entry<? extends Group, ? extends RoleSet> entry : roleSets.entrySet()) 
208                        {
209                                Group g = entry.getKey();
210                                if (g.getName().equalsIgnoreCase(group)) 
211                                {
212                                        RoleSet rs = entry.getValue();
213                                        roleFound = rs.containsName(role);
214                                }
215                        }
216                } 
217                catch (Exception e) 
218                {
219                        roleFound = false;
220                }
221                return roleFound;
222        }
223
224        /**
225         * Checks if the user is assigned a specific Role in any of the given Groups
226         *
227         * @param rolename the name of the Role
228         * @param groupset a Groupset
229         * @return <code>true</code> if the user is assigned the Role in any of the
230         *         given Groups.
231         */
232        public boolean hasRole(String rolename, GroupSet groupset) {
233                Role role;
234                try 
235                {
236                        role = roleSet.getByName(rolename);
237                } 
238                catch (Exception e) 
239                {
240                        return false;
241                }
242                
243                if (role == null) 
244                {
245                        return false;
246                }
247                
248                for (Group group : groupset) 
249                {
250                        RoleSet roles = getRoles(group);
251                        if (roles != null && roles.contains(role)) 
252                        {
253                                return true;
254                        }
255                }
256                return false;
257        }
258
259        /**
260         * Checks if the user is assigned a specific Role
261         *
262         * @param role the Role
263         * @return <code>true</code> if the user is assigned the Role in the global
264         *         Group.
265         */
266        public boolean hasRole(Role role) {
267                return roleSet.contains(role);
268        }
269
270        /**
271         * Checks if the user is assigned a specific Role .
272         *
273         * @param role the Role
274         * @return <code>true</code> if the user is assigned the Role .
275         */
276        public boolean hasRole(String role) {
277                try 
278                {
279                        return roleSet.containsName(role);
280                } 
281                catch (Exception e) 
282                {
283                        return false;
284                }
285        }
286
287        /**
288         * Checks if the user is assigned a specific Permission in the Group.
289         *
290         * @param permission the Permission
291         * @param group      the Group
292         * @return <code>true</code> if the user is assigned the Permission in the
293         *         Group.
294         */
295        public boolean hasPermission(Permission permission, Group group) {
296                PermissionSet set = getPermissions(group);
297                if (set == null || permission == null) 
298                {
299                        return false;
300                }
301                return set.contains(permission);
302        }
303
304        /**
305         * Checks if the user is assigned a specific Permission in any of the given
306         * Groups
307         *
308         * @param permission the Permission
309         * @param groupset   a Groupset
310         * @return <code>true</code> if the user is assigned the Permission in any of
311         *         the given Groups.
312         */
313        public boolean hasPermission(Permission permission, GroupSet groupset) {
314                if (permission == null) 
315                {
316                        return false;
317                }
318                
319                for (Group group : groupset) 
320                {
321                        PermissionSet permissions = getPermissions(group);
322                        if (permissions != null && permissions.contains(permission)) 
323                        {
324                                return true;
325                        }
326                }
327                return false;
328        }
329
330        /**
331         * Checks if the user is assigned a specific Permission in the Group.
332         *
333         * @param permission the Permission
334         * @param group      the Group
335         * @return <code>true</code> if the user is assigned the Permission in the
336         *         Group.
337         */
338        public boolean hasPermission(String permission, String group) {
339                try 
340                {
341                        return hasPermission(permissionSet.getByName(permission), groupSet.getByName(group));
342                } 
343                catch (Exception e) 
344                {
345                        return false;
346                }
347        }
348
349        /**
350         * Checks if the user is assigned a specific Permission in the Group.
351         *
352         * @param permission the Permission
353         * @param group      the Group
354         * @return <code>true</code> if the user is assigned the Permission in the
355         *         Group.
356         */
357        public boolean hasPermission(String permission, Group group) {
358                try 
359                {
360                        return hasPermission(permissionSet.getByName(permission), group);
361                } 
362                catch (Exception e) 
363                {
364                        return false;
365                }
366        }
367
368        /**
369         * Checks if the user is assigned a specific Permission in any of the given
370         * Groups
371         *
372         * @param permissionName the name of the Permission
373         * @param groupset       a Groupset
374         * @return <code>true</code> if the user is assigned the Permission in any of
375         *         the given Groups.
376         */
377        public boolean hasPermission(String permissionName, GroupSet groupset) {
378                Permission permission;
379                try 
380                {
381                        permission = permissionSet.getByName(permissionName);
382                } catch (Exception e) {
383                        return false;
384                }
385                
386                if (permission == null) 
387                {
388                        return false;
389                }
390                
391                for (Group group : groupset) 
392                {
393                        PermissionSet permissions = getPermissions(group);
394                        if (permissions != null && permissions.contains(permission)) 
395                        {
396                                return true;
397                        }
398                }
399                return false;
400        }
401
402        /**
403         * Checks if the user is assigned a specific Permission.
404         *
405         * @param permission the Permission
406         * @return <code>true</code> if the user is assigned the Permission .
407         */
408        public boolean hasPermission(Permission permission) {
409                return permissionSet.contains(permission);
410        }
411
412        /**
413         * Checks if the user is assigned a specific Permission in the global Group.
414         *
415         * @param permission the Permission
416         * @return <code>true</code> if the user is assigned the Permission in the
417         *         global Group.
418         */
419        public boolean hasPermission(String permission) {
420                try 
421                {
422                        return permissionSet.containsName(permission);
423                } 
424                catch (Exception e) 
425                {
426                        return false;
427                }
428        }
429}