KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > jguard > ext > authorization > manager > AbstractAuthorizationManager


1 /*
2 jGuard is a security framework based on top of jaas (java authentication and authorization security).
3 it is written for web applications, to resolve simply, access control problems.
4
5 http://sourceforge.net/projects/jguard/
6
7 Copyright (C) 2004 Charles GAY
8
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
13
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public
20 License along with this library; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
23
24 jGuard project home page:
25 http://sourceforge.net/projects/jguard/
26
27 */

28 package net.sf.jguard.ext.authorization.manager;
29
30 import java.io.IOException JavaDoc;
31 import java.io.OutputStream JavaDoc;
32 import java.security.Permission JavaDoc;
33 import java.security.PermissionCollection JavaDoc;
34 import java.security.Principal JavaDoc;
35 import java.security.ProtectionDomain JavaDoc;
36 import java.util.Collection JavaDoc;
37 import java.util.Collections JavaDoc;
38 import java.util.HashMap JavaDoc;
39 import java.util.HashSet JavaDoc;
40 import java.util.Iterator JavaDoc;
41 import java.util.List JavaDoc;
42 import java.util.Map JavaDoc;
43 import java.util.Random JavaDoc;
44 import java.util.Set JavaDoc;
45 import java.util.Stack JavaDoc;
46 import java.util.TreeSet JavaDoc;
47 import java.util.logging.Level JavaDoc;
48 import java.util.logging.Logger JavaDoc;
49
50 import net.sf.jguard.core.authorization.permissions.Domain;
51 import net.sf.jguard.core.authorization.permissions.JGNegativePermissionCollection;
52 import net.sf.jguard.core.authorization.permissions.JGPermissionCollection;
53 import net.sf.jguard.core.authorization.permissions.JGPositivePermissionCollection;
54 import net.sf.jguard.core.authorization.permissions.NoSuchPermissionException;
55 import net.sf.jguard.core.authorization.permissions.PermissionUtils;
56 import net.sf.jguard.core.principals.RolePrincipal;
57 import net.sf.jguard.core.principals.UserPrincipal;
58 import net.sf.jguard.ext.SecurityConstants;
59 import net.sf.jguard.ext.authentication.manager.XmlAuthenticationManager;
60 import net.sf.jguard.ext.authorization.AuthorizationException;
61 import net.sf.jguard.ext.principals.PrincipalUtils;
62
63 /**
64  * Abstract class inherited by all the AuthorizationManager implementations.
65  * @author <a HREF="mailto:diabolo512@users.sourceforge.net">Charles Gay</a>
66  * @author <a HREF="mailto:tandilero@users.sourceforge.net">Maximiliano Batelli</a>
67  *
68  */

69 public abstract class AbstractAuthorizationManager implements AuthorizationManager {
70     /** Logger for this class */
71     private static final Logger JavaDoc logger = Logger.getLogger(AbstractAuthorizationManager.class.getName());
72
73    
74
75     protected String JavaDoc applicationName = null;
76     protected Map JavaDoc principals;
77     protected Set JavaDoc principalsSet;
78     protected Map JavaDoc domains;
79     //we add also this Set of domains to certify Domain unicity
80
protected static Set JavaDoc domainsSet;
81     protected JGPermissionCollection urlp;
82     //store all the permissions of all the domains
83
protected Map JavaDoc permissions ;
84     protected Set JavaDoc permissionsSet;
85     //store the permissions set associated with the domain ids
86
protected Map JavaDoc domainsPermissions;
87     // store the hierarcy while assembly the principals to after link
88
protected Map JavaDoc hierarchyMap;
89     protected Map JavaDoc options;
90     private boolean negativePermissions;
91
92     public AbstractAuthorizationManager(){
93         principals = new HashMap JavaDoc();
94         principalsSet = new TreeSet JavaDoc();
95         domains = new HashMap JavaDoc();
96         domainsSet = new TreeSet JavaDoc();
97         permissions = new HashMap JavaDoc();
98         permissionsSet = new HashSet JavaDoc();
99         domainsPermissions = new HashMap JavaDoc();
100         hierarchyMap = new HashMap JavaDoc();
101         urlp = null;
102     }
103
104     /**
105      * define the application's name, and propagate it into Principals.
106      * this mechanism is done because application's name can only be known when the
107      * first request is here (bad j2ee design....).
108      * @param applicationName
109      */

110     public void setApplicationName(String JavaDoc applicationName){
111
112         this.applicationName = applicationName;
113         Iterator JavaDoc itPrincipalsSet = principalsSet.iterator();
114         while(itPrincipalsSet.hasNext()){
115             RolePrincipal principalTemp = (RolePrincipal)itPrincipalsSet.next();
116             principalTemp.setApplicationName(applicationName);
117         }
118         Iterator JavaDoc itPrincipalsMap = principals.values().iterator();
119         while(itPrincipalsMap.hasNext()){
120             RolePrincipal principal = (RolePrincipal)itPrincipalsMap.next();
121             principal.setApplicationName(applicationName);
122         }
123
124     }
125     /**
126      * with a collection of domain names, provide the corresponding set of URLDomains.
127      * @param domainNames collection of domains.
128      * @return URLPermission's Set
129      */

130     public Set JavaDoc getDomains(Collection JavaDoc domainNames) {
131         Set JavaDoc doms = new HashSet JavaDoc();
132         Iterator JavaDoc itDomNames = domainNames.iterator();
133
134         while(itDomNames.hasNext()){
135             JGPermissionCollection dom = (JGPermissionCollection)domains.get(itDomNames.next());
136             doms.add(dom);
137         }
138
139         return doms;
140     }
141     /**
142      * with a collection of URLPermissions names, provide the corresponding
143      * set of URLPermissions.
144      * @param permissionNames collection of permission names to grab.
145      * @return URLPermission's Set
146      */

147     public Set JavaDoc getPermissions(Collection JavaDoc permissionNames) {
148         Set JavaDoc perms = new HashSet JavaDoc();
149         Iterator JavaDoc itPermNames = permissionNames.iterator();
150
151         while(itPermNames.hasNext()){
152             Permission JavaDoc perm;
153             String JavaDoc permissionName = (String JavaDoc)itPermNames.next();
154             try {
155                 perm = urlp.getPermission(permissionName);
156             perms.add(perm);
157             } catch (NoSuchPermissionException e) {
158                 logger.finest(" permission "+permissionName+" not found in JGPermissionCollection ");
159             }
160         }
161
162         return perms;
163     }
164     /**
165      * initialize AuthorizationManager implementation.
166      * @param options
167      */

168     public void init(Map JavaDoc options){
169         String JavaDoc negativePermission = (String JavaDoc)options.get(SecurityConstants.NEGATIVE_PERMISSIONS);
170         if(negativePermission!= null && negativePermission.equalsIgnoreCase("true")){
171             this.urlp = new JGNegativePermissionCollection();
172             this.negativePermissions = true;
173         }else{
174             this.urlp = new JGPositivePermissionCollection();
175             this.negativePermissions = false;
176         }
177     }
178
179     /**
180      * @see net.sf.jguard.ext.authorization.manager.AuthorizationManager#refresh()
181      */

182     public void refresh() {
183       init(options);
184     }
185     /**
186      * compare declared Principals in the application, with principals set of the user.
187      * for the principals of the user, we retrieve corresponding permissions declared in the application,
188      * and we regroup them in a PermissionCollection.
189      * @param principals
190      * @return PermissionCollection
191      * @see net.sf.jguard.ext.authorization.manager.AuthorizationManager#getPermissionCollection(java.util.Set)
192      * @see net.sf.jguard.core.authorization.manager.PermissionProvider
193      */

194     public PermissionCollection JavaDoc getPermissionCollection(Set JavaDoc principals,ProtectionDomain JavaDoc pDomain) {
195
196        if(logger.isLoggable(Level.FINEST)){
197            logger.finest(" user has got "+principals.size()+" principals "+principals.toString());
198        }
199         JGPermissionCollection urlpUser = null;
200         if(!negativePermissions){
201             urlpUser = new JGPositivePermissionCollection();
202         }else{
203             urlpUser = new JGNegativePermissionCollection();
204         }
205         
206         //TODO CGA add SSODPermissions (java.security.Permissions) decorator
207
//to support Static Separation Of Duty (an RBAC feature)
208
// it will handle SSOD purpose in a static way with
209
// any AuthorizationManager implementation
210

211         // Find the UserPrincipal to evaluate definitions
212
UserPrincipal userPrincipal = null;
213         Iterator JavaDoc userPrincipalsIt = principals.iterator();
214         while(userPrincipalsIt.hasNext()){
215             Principal JavaDoc ppal = (Principal JavaDoc)userPrincipalsIt.next();
216             if(ppal instanceof UserPrincipal) {
217                 userPrincipal = (UserPrincipal)ppal;
218                 break;
219             }
220         }
221         
222         RolePrincipal tempUserPrincipal;
223         RolePrincipal tempDefinedPrincipal;
224
225         Iterator JavaDoc definedPrincipalsIt;
226
227         userPrincipalsIt = principals.iterator();
228
229         //add all RolePrincipal permissions to JGPermissionCollection
230
while(userPrincipalsIt.hasNext()){
231             Principal JavaDoc ppal = (Principal JavaDoc)userPrincipalsIt.next();
232             if (!(ppal instanceof RolePrincipal)) {
233                 //we skip principal which are not RolePrincipal
234
//only jGuardPrincipals own permissions
235
continue;
236             }else{
237                 tempUserPrincipal = (RolePrincipal) ppal;
238             }
239             
240             //we don't add the RolePrincipal if its definition is false
241
if(!PermissionUtils.evaluatePrincipal(tempUserPrincipal, userPrincipal)) {
242                 continue;
243             }
244
245             if (logger.isLoggable(Level.FINEST)) {
246                 logger.finest("getPermissionCollection() - user's principal name="+ tempUserPrincipal.getLocalName());
247                 logger.finest("getPermissionCollection() - user's principal applicationName="
248                         + tempUserPrincipal.getApplicationName());
249             }
250             definedPrincipalsIt = principalsSet.iterator();
251             //we search the corresponding defined Principal
252
while(definedPrincipalsIt.hasNext()){
253                 tempDefinedPrincipal = (RolePrincipal)definedPrincipalsIt.next();
254                 if (logger.isLoggable(Level.FINEST)) {
255                     logger.finest("getPermissionCollection() - system's principal name="
256                             + tempDefinedPrincipal.getLocalName());
257                     logger.finest("getPermissionCollection() - system's principal applicationName="
258                             + applicationName);
259                 }
260                 
261                 //if RolePrincipal owned by the user(Authentication side) matches
262
//with the RolePrincipal owned by the application(Authorization side),
263
//we add all the related permissions in the PermissionCollection of the user
264
if(tempDefinedPrincipal.equals(tempUserPrincipal)){
265                     if (logger.isLoggable(Level.FINEST)) {
266                         logger.finest("getPermissionCollection() - principal name="
267                                 + tempUserPrincipal.getLocalName()
268                                 + " is declared in this application ");
269                     }
270                     urlpUser.addAll(tempDefinedPrincipal.getAllPermissions());
271                     Set JavaDoc tempset = tempDefinedPrincipal.getAllPermissions();
272
273                     if (logger.isLoggable(Level.FINEST)) {
274                         logger.finest("getPermissionCollection() - permissions granted are :"
275                                 + tempset.toString());
276                     }
277
278                     break;
279                 }
280             }
281         }
282
283         if(logger.isLoggable(Level.FINEST)){
284             logger.finest(" user has got "+urlpUser.size()+" permissions: \n"+urlpUser);
285         }
286         
287         //resolve regexp in permissions
288
JGPermissionCollection resolvedPermissions = (JGPermissionCollection)PermissionUtils.evaluatePermissionCollection(pDomain,(PermissionCollection JavaDoc)urlpUser);
289         //we remove unresolved permissions
290
//and replace them with the resolved one
291
//we do that to preserve the JGpermissionCollection subclass
292
//positive or negative
293
urlpUser.clear();
294         urlpUser.addAll(resolvedPermissions);
295         
296         //TODO CGA add Dynamic Separation Of Duty (DSOD) feature specified in RBAC
297
//(Role based Access Control)
298
//we will implement it as a Permissions subclass
299
//it will check permissions against DSO constraint in a static way
300
//in conjunction with the class WorkflowCheckerFactory
301

302         return urlpUser;
303     }
304
305     /**
306      * clone a RolePrincipal/Role and set its name with the name of the Principal to clone plus
307      * a random number.
308      * @param roleName RolePrincipal name to clone
309      * @return cloned RolePrincipal with a different name : original JguardPrincipal name + Random integer betweeen 0 and 99999
310      * @throws AuthorizationException
311      */

312     public Principal JavaDoc clonePrincipal(String JavaDoc roleName) throws AuthorizationException{
313         Random JavaDoc rnd = new Random JavaDoc();
314         String JavaDoc cloneName = roleName+rnd.nextInt(99999);
315
316         return clonePrincipal(roleName, cloneName);
317     }
318
319     /**
320      * clone a RolePrincipal/Role.
321      * @param roleName RolePrincipal name to clone
322      * @param cloneName RolePrincipal cloned name
323      * @return cloned RolePrincipal with a different name : original JguardPrincipal name + Random integer betweeen 0 and 99999
324      * @throws AuthorizationException
325      */

326     public Principal JavaDoc clonePrincipal(String JavaDoc roleName,String JavaDoc cloneName) throws AuthorizationException {
327         cloneName = RolePrincipal.getName(cloneName, applicationName);
328         Principal JavaDoc role = (Principal JavaDoc)principals.get(roleName);
329         Principal JavaDoc clone = null;
330         if(role instanceof RolePrincipal) {
331             clone = (RolePrincipal)((RolePrincipal)role).clone();
332             ((RolePrincipal)clone).setName(cloneName);
333         }
334         else
335             clone = PrincipalUtils.getPrincipal(role.getClass().getName(), cloneName);
336
337         //persist the newly created clone
338
createPrincipal(clone);
339
340     return clone;
341     }
342
343
344     /**
345      * return Set of domains.
346      * @return domains Set
347      * @see net.sf.jguard.ext.authorization.manager.AuthorizationManager#listDomains()
348      */

349     public Set JavaDoc listDomains() throws AuthorizationException {
350         return domainsSet;
351     }
352     /**
353      * read an URLPermission.
354      * @param permissionName
355      * @throws AuthorizationException
356      * @see net.sf.jguard.ext.authorization.manager.AuthorizationManager#readPermission(java.lang.String)
357      */

358     public Permission JavaDoc readPermission(String JavaDoc permissionName) throws AuthorizationException {
359         try {
360         return urlp.getPermission(permissionName);
361         } catch (NoSuchPermissionException e) {
362             throw new AuthorizationException(" permission "+permissionName+" not found ");
363         }
364     }
365     /**
366      * return an Domain with its associated URLPermission set.
367      * @param domainName
368      * @return Domain
369      * @throws AuthorizationException
370      * @see net.sf.jguard.ext.authorization.manager.AuthorizationManager#readDomain(java.lang.String)
371      */

372     public JGPermissionCollection readDomain(String JavaDoc domainName) throws AuthorizationException{
373         JGPermissionCollection domainFound = (JGPermissionCollection)domains.get(domainName);
374         if(domainFound==null){
375             throw new AuthorizationException(" domain with name="+domainName+" is not found");
376         }
377         return domainFound;
378     }
379     /**
380      * return the corresponding application role.
381      * @return role
382      * @see net.sf.jguard.ext.authorization.manager.AuthorizationManager#readPrincipal(java.lang.String)
383      * @throws AuthorizationException
384      */

385     public Principal JavaDoc readPrincipal(String JavaDoc roleName) throws AuthorizationException {
386         Principal JavaDoc principalFound = (Principal JavaDoc)principals.get(roleName);
387         if(principalFound==null){
388             throw new AuthorizationException(" principal with name="+roleName+" is not found");
389         }
390         return principalFound;
391     }
392
393     /**
394      * <p>Update the permissions from jGuardPrincipals that contains this domain.</p>
395      * <p><b>Note:</b> This method is need because, first, there are no warranty that the reference
396      * of domain in the RolePrincipal object are the same from domainsSet and map and, second, the
397      * getPermissions method from RolePrincipal don't load the permissions from domains objects
398      * (it use a internal set of permissions).</p>
399      * @param domain the domain that will be updated in the principals
400      */

401     protected void updatePrincipals(Domain JavaDoc domain) {
402         for (Iterator JavaDoc principalsIt = principalsSet.iterator(); principalsIt.hasNext(); ) {
403             RolePrincipal principal = (RolePrincipal) principalsIt.next();
404
405             //2005-06-01 vinipitta:
406
//if the principal contains the domain we remove the domain from it and replace by the
407
//current(updated) version of the domain. This forces the principal to update the
408
//permission list
409
if (principal.getDomains().contains(domain)) {
410                 principal.removeDomain(domain);
411                 //if we use the principal.getDomains().add method instead then this will not work!
412
principal.addDomain(domain);
413                 domainsSet.remove(domain);
414                 domainsSet.add(domain);
415                 domains.remove(domain.getName());
416                 domains.put(domain.getName(),domain);
417             }
418         }
419     }
420
421     /**
422      * <p>Update the permissions from jGuardPrincipals <b>and</b> the associated domain.</p>
423      * <p><b>Note:</b> This method is need because, first, there are no warranty that the reference
424      * of domain in the RolePrincipal object are the same from domainsSet and map and, second, the
425      * getPermissions method from RolePrincipal don't load the permissions from domains objects
426      * (it use a internal set of permissions).</p>
427      * @param permission whose domain will be updated in the principals
428      */

429     protected void updatePrincipals(Permission JavaDoc permission) {
430         for (Iterator JavaDoc principalsIt = principalsSet.iterator(); principalsIt.hasNext(); ) {
431             RolePrincipal principal = (RolePrincipal) principalsIt.next();
432             Domain JavaDoc domain = getDomain(permission);
433             //2005-06-01 vinipitta:
434
//if the principal contains the domain we remove the domain from it and replace by the
435
//current(updated) version of the domain. This forces the principal to update the
436
//permission list
437
if (principal.getDomains().contains(domain)) {
438                 principal.removeDomain(domain);
439                 //if we use the principal.getDomains().add method instead then this will not work!
440
principal.addDomain(domain);
441                 domainsSet.remove(domain);
442                 domainsSet.add(domain);
443                 domains.remove(domain.getName());
444                 domains.put(domain.getName(),domain);
445               //we handle the use case when the principal is ited directly
446
//to a permission and not indirectly through a domain
447
}else if(principal.getOrphanedPermissions().contains(permission)){
448                principal.getOrphanedPermissions().remove(permission);
449                principal.getOrphanedPermissions().add(permission);
450                principal.getPermissions().remove(permission);
451                principal.getPermissions().add(permission);
452
453             }
454         }
455     }
456
457     /**
458      * update the principals with this updated domain.
459      * it implies a suppress and an addition.
460      * @param newDomain
461      * @param oldDomainName
462      */

463     protected void updatePrincipals(JGPermissionCollection newDomain, String JavaDoc oldDomainName) {
464         JGPermissionCollection domain = new Domain JavaDoc(oldDomainName);
465
466         for (Iterator JavaDoc principalsIt = principalsSet.iterator(); principalsIt.hasNext(); ) {
467             RolePrincipal principal = (RolePrincipal) principalsIt.next();
468
469             //2005-06-01 vinipitta:
470
//if the principal contains the domain we remove the domain from it and replace by the
471
//current(updated) version of the domain. This forces the principal to update the
472
//permission list
473
if (principal.getDomains().contains(domain)) {
474                 principal.removeDomain(domain);
475                 //if we use the principal.getDomains().add method instead then this will not work!
476
principal.addDomain(newDomain);
477             }
478         }
479     }
480
481
482     /**
483      * Remove the domain from all principals that have relationship with this domain.
484      * @param domainName the name of the domain that will be removed
485      */

486     protected void removeDomainFromPrincipals(String JavaDoc domainName) {
487         JGPermissionCollection domain = new Domain JavaDoc(domainName);
488
489         for (Iterator JavaDoc principalsIt = principalsSet.iterator(); principalsIt.hasNext(); ) {
490             RolePrincipal principal = (RolePrincipal) principalsIt.next();
491             if (principal.getDomains().contains(domain)) {
492                 principal.removeDomain(domain);
493                 domains.remove(domain);
494                 domainsSet.remove(domain);
495             }
496         }
497     }
498
499     /**
500      * Remove the permission from all principals that have relationship with this permission like a
501      * orphaned permission (directly), or through a domain (indirectly).
502      * @param permissionName the name of the permission that will be removed
503      */

504     protected void removePermissionFromPrincipals(String JavaDoc permissionName) {
505         Permission JavaDoc permission = (Permission JavaDoc) permissions.get(permissionName);
506
507         for (Iterator JavaDoc principalsIt = principalsSet.iterator(); principalsIt.hasNext(); ) {
508             RolePrincipal principal = (RolePrincipal) principalsIt.next();
509             if (principal.getOrphanedPermissions().contains(permission)) {
510                 principal.getOrphanedPermissions().remove(permission);
511                 principal.getPermissions().remove(permission);
512                 logger.finest("removePermissionFromPrincipals: " + permission);
513             }else if(principal.getPermissionsFromDomains().contains(permission)){
514                 principal.getPermissionsFromDomains().remove(permission);
515                 principal.getPermissions().remove(permission);
516                 logger.finest("removePermissionFromPrincipals: " + permission);
517             }
518         }
519     }
520
521     /**
522      * return the domain which contains the permission.
523      * @param permission
524      * @return domain which owns the permission or null if no domain contains
525      * this permisison
526      */

527     protected Domain JavaDoc getDomain(Permission JavaDoc permission){
528         Iterator JavaDoc iterator = domainsSet.iterator();
529         while(iterator.hasNext()){
530             Domain JavaDoc temp = (Domain JavaDoc)iterator.next();
531             if(temp.containsPermission(permission)){
532                 return temp;
533             }
534         }
535         //no domains contains this permission
536
return null;
537     }
538
539     /**
540      * add the permission to the corresponding role.
541      * if the permission is not persisted, we persist it and create
542      * a corresponding Domain with the same name.
543      * @param roleName role updated
544      * @param perm permission to add
545      * @throws AuthorizationException
546      */

547     public void addToPrincipal(String JavaDoc roleName, Permission JavaDoc perm) throws AuthorizationException {
548         RolePrincipal role = (RolePrincipal) principals.get(roleName);
549         if(role == null){
550             throw new SecurityException JavaDoc(" Principal/role "+roleName+" does not exists ");
551         }
552         //if permission does not exists, we add it
553
// and create a corresponding domain with the same name
554
if(!permissionsSet.contains(perm)){
555             permissionsSet.add(perm);
556             permissions.put(perm.getName(),perm);
557             createDomain(perm.getName());
558             createPermission(perm,perm.getName());
559         }
560         role.addPermission(perm);
561     }
562
563     /**
564      * add the domain to the role, and
565      * persist the domain if it does not exists?
566      * @param roleName
567      * @param domain
568      * @throws AuthorizationException
569      */

570     public void addToPrincipal(String JavaDoc roleName,Domain JavaDoc domain) throws AuthorizationException{
571         RolePrincipal role = (RolePrincipal) principals.get(roleName);
572         if(role == null){
573             throw new SecurityException JavaDoc(" Principal/role "+roleName+" does not exists ");
574         }
575
576         if(domainsSet.contains(domain)){
577             domainsSet.add(domain);
578             domains.put(domain.getName(),domain);
579             createDomain(domain.getName());
580         }
581
582         role.addDomain(domain);
583     }
584
585     /**
586      * This commands establishes a new immediate inheritance relationship
587      * between the existing principals/principals roleAsc and the roleDesc.
588      * The command is valid if and only if the role roleAsc is not an immediate
589      * ascendant of roleDesc, and descendant does
590      * not properly inherit roleAsc principal/role (in order to avoid cycle creation).
591      *
592      * @param principalAscName the principal/role that will inherite.
593      * @param principalDescName the principal/role that will be inherited.
594      * @throws AuthorizationException if the inheritance already exists or create a cycle.
595      */

596     public void addInheritance(String JavaDoc principalAscName, String JavaDoc principalDescName) throws AuthorizationException {
597
598         //getting the principals
599
Principal JavaDoc principalAsc = (Principal JavaDoc) principals.get(principalAscName);
600         Principal JavaDoc principalDesc = (Principal JavaDoc) principals.get(principalDescName);
601
602         if (principalAscName.equals(principalDescName)){
603             logger.severe("ascendant and descendant cannot be the same principal ");
604             throw new AuthorizationException("ascendant and descendant cannot be the same principal ");
605         }
606
607         if (principalAsc == null) {
608             logger.severe("Role " + principalAscName + " not found!");
609             throw new AuthorizationException("Role " + principalAscName + " not found!");
610         }
611
612         if (principalDesc == null) {
613             logger.severe("Role " + principalDescName + " not found!");
614             throw new AuthorizationException("Role " + principalDescName + " not found!");
615         }
616
617         if(!RolePrincipal.class.isAssignableFrom(principalAsc.getClass())
618             ||!RolePrincipal.class.isAssignableFrom(principalDesc.getClass())){
619             throw new AuthorizationException(" role inheritance is only supported by RolePrincipal \n roleAsc class="+principalAsc.getClass().getName()+" \n roleDesc class="+principalDesc.getClass().getName());
620         }
621
622         //check if the roleAsc is immediate ascendant of roleDesc
623
for (Iterator JavaDoc it = ((RolePrincipal)principalAsc).getDescendants().iterator(); it.hasNext(); ) {
624             if (principalDesc.equals(it.next())) {
625                 logger.severe("Role " + principalAscName + " is immediate ascendant of role " + principalDescName + "!");
626                 throw new AuthorizationException("Role " + principalAscName + " is immediate ascendant of role " + principalDescName + "!");
627             }
628         }
629
630         //check if roleDesc inherit roleAsc
631
//use a stack instead of a recursive method
632
Stack JavaDoc rolesToCheck = new Stack JavaDoc();
633         //used to check first all principals from one level before check the next level
634
Stack JavaDoc rolesFromNextLevel = new Stack JavaDoc();
635         rolesToCheck.addAll(((RolePrincipal)principalDesc).getDescendants());
636
637         while (!rolesToCheck.isEmpty()) {
638             RolePrincipal role = (RolePrincipal) rolesToCheck.pop();
639             if (principalAsc.equals(role)) {
640                 logger.severe("Role " + principalAscName + " cannot inherit role "
641                         + principalDescName + " because " + principalDescName + " inherit "
642                         + principalAscName);
643                 throw new AuthorizationException("Role " + principalAscName + " cannot inherit role "
644                         + principalDescName + " because " + principalDescName + " inherit "
645                         + principalAscName);
646             }
647
648             rolesFromNextLevel.addAll(role.getDescendants());
649
650             //is time to go to next level
651
if (rolesToCheck.isEmpty()) {
652                 rolesToCheck.addAll(rolesFromNextLevel);
653
654                 //clear the second level stack
655
rolesFromNextLevel.clear();
656             }
657         }
658
659         //update in-memory role
660
((RolePrincipal)principalAsc).getDescendants().add(principalDesc);
661
662         //update xml
663
updatePrincipal((RolePrincipal)principalAsc);
664     }
665
666     /**
667      * @param roleAscName the role that inherit.
668      * @param roleDescName the role that is inherited.
669      * @throws AuthorizationException if the inheritance already exists or create a cycle.
670      */

671     public void deleteInheritance(String JavaDoc roleAscName, String JavaDoc roleDescName) throws AuthorizationException {
672         RolePrincipal roleAsc = (RolePrincipal) principals.get(roleAscName);
673         roleAsc.getDescendants().remove(principals.get(roleDescName));
674         updatePrincipal(roleAsc);
675     }
676
677     /**
678      * replace the inital principal with the new one.
679      * @param principal RolePrincipal updated
680      * @throws AuthorizationException
681      * @see net.sf.jguard.ext.authorization.manager.AuthorizationManager#updatePrincipal(net.sf.jguard.core.principals.RolePrincipal)
682      */

683     public void updatePrincipal(Principal JavaDoc principal) throws AuthorizationException {
684         deletePrincipal(principal);
685         createPrincipal(principal);
686         logger.finest(" updated principal="+principal);
687     }
688
689     /**
690      * assembly the hierarchy of jGuardPrincipals.
691      */

692     protected void assemblyHierarchy() {
693         //now that every principal is mapped, assembly the hierarchy.
694
for (Iterator JavaDoc it = hierarchyMap.keySet().iterator(); it.hasNext(); ) {
695             String JavaDoc ascendantName = (String JavaDoc) it.next();
696             RolePrincipal ascendant = (RolePrincipal) principals.get(ascendantName);
697
698             for (Iterator JavaDoc it2 = ((List JavaDoc) hierarchyMap.get(ascendantName)).iterator(); it2.hasNext(); ) {
699                 RolePrincipal descendant = (RolePrincipal) it2.next();
700                 ascendant.getDescendants().add(descendant);
701                 logger.finest("Role " + ascendantName + " inherits from role " + descendant.getLocalName());
702             }
703         }
704     }
705     /**
706      *
707      * @param principal
708      */

709     protected void deleteReferenceInHierarchy(RolePrincipal principal){
710           String JavaDoc principalName = principal.getLocalName();
711
712           //clean the hierarchy
713
for (Iterator JavaDoc it = hierarchyMap.keySet().iterator(); it.hasNext(); ) {
714               String JavaDoc ascendantName = (String JavaDoc) it.next();
715               if(principalName.equals(ascendantName)){
716                   //we remove in memory the deleted principal
717
hierarchyMap.remove(ascendantName);
718               }else{
719                   List JavaDoc descendants = (List JavaDoc) hierarchyMap.get(ascendantName);
720                   descendants.remove(principal);
721               }
722           }
723
724           //clean descendants references in the principal Map
725
Collection JavaDoc values = principals.values();
726           Iterator JavaDoc itValues = values.iterator();
727           while(itValues.hasNext()){
728               RolePrincipal ppalTemp = (RolePrincipal)itValues.next();
729               ppalTemp.getDescendants().remove(principal);
730           }
731
732           //clean descendants references in the principal Set
733
Iterator JavaDoc itPrincipalsSet = principalsSet.iterator();
734           while(itPrincipalsSet.hasNext()){
735                RolePrincipal ppalTemp = (RolePrincipal)itPrincipalsSet.next();
736                ppalTemp.getDescendants().remove(principal);
737           }
738
739     }
740
741     /**
742      * return the principal's Set.
743      * @return principal's Set
744      * @see net.sf.jguard.ext.authorization.manager.AuthorizationManager#listPrincipals()
745      */

746     public Set JavaDoc listPrincipals() {
747        return principalsSet;
748     }
749     /**
750      * return all the permissions.
751      * @return URLPermission container
752      * @see net.sf.jguard.ext.authorization.manager.AuthorizationManager#listPermissions()
753      */

754     public JGPermissionCollection listPermissions() {
755         return new JGPositivePermissionCollection(permissionsSet);
756     }
757
758
759     /**
760      * import data from the provided AbstractAuthorizationManager into
761      * our AuthorizationManager.
762      * @param authManager
763      * @throws AuthorizationException
764      */

765     public void importAuthorizationManager(AuthorizationManager authManager)throws AuthorizationException{
766         if(authManager.isEmpty()){
767             logger.warning(" authManager to import is empty ");
768             return;
769         }
770         //import domains set and associated permissions
771
Set JavaDoc domains = authManager.getDomainsSet();
772          Iterator JavaDoc itDomains = domains.iterator();
773          while(itDomains.hasNext()){
774              Domain JavaDoc domain = (Domain JavaDoc)itDomains.next();
775              createDomain(domain.getName());
776              Iterator JavaDoc itPermissions = domain.getPermissions().iterator();
777              while(itPermissions.hasNext()){
778                  Permission JavaDoc perm = (Permission JavaDoc)itPermissions.next();
779                  createPermission(perm,domain.getName());
780              }
781          }
782
783
784          //import principal set
785
Set JavaDoc Principals = authManager.getPrincipalsSet();
786          Iterator JavaDoc itPrincipals = Principals.iterator();
787          while(itPrincipals.hasNext()){
788              Principal JavaDoc principal = (Principal JavaDoc)itPrincipals.next();
789              createPrincipal(principal);
790          }
791
792
793          //import principal inheritance
794
Iterator JavaDoc itPrincipals2 = Principals.iterator();
795          while(itPrincipals2.hasNext()){
796              Principal JavaDoc principal = (Principal JavaDoc)itPrincipals2.next();
797              if(principal instanceof RolePrincipal){
798                  RolePrincipal ppal = (RolePrincipal)principal;
799                  Set JavaDoc descendants = ppal.getDescendants();
800                  Iterator JavaDoc itDescendants = descendants.iterator();
801                  while(itDescendants.hasNext()){
802                      RolePrincipal descPrincipal = (RolePrincipal)itDescendants.next();
803                      addInheritance(getLocalName(principal),getLocalName(descPrincipal));
804                  }
805              }
806          }
807
808
809     }
810
811     public final Set JavaDoc getDomainsSet() {
812         return Collections.unmodifiableSet(domainsSet);
813     }
814
815     public final Map JavaDoc getDomains() {
816         return Collections.unmodifiableMap(domains);
817     }
818
819     public final Map JavaDoc getDomainsPermissions() {
820         return Collections.unmodifiableMap(domainsPermissions);
821     }
822
823     public final Map JavaDoc getHierarchyMap() {
824         return Collections.unmodifiableMap(hierarchyMap);
825     }
826
827     public final Map JavaDoc getPermissions() {
828         return Collections.unmodifiableMap(permissions);
829     }
830
831
832     public final Set JavaDoc getPermissionsSet() {
833         return Collections.unmodifiableSet(permissionsSet);
834     }
835
836     public final Map JavaDoc getPrincipals() {
837         return Collections.unmodifiableMap(principals);
838     }
839
840
841     public final Set JavaDoc getPrincipalsSet() {
842         return Collections.unmodifiableSet(principalsSet);
843     }
844      protected static String JavaDoc getLocalName(Principal JavaDoc principal) {
845             
846             String JavaDoc name = null;
847             if (principal instanceof RolePrincipal) {
848                 RolePrincipal rolePrincipal = (RolePrincipal) principal;
849                 name = rolePrincipal.getLocalName();
850             }else{
851                 name = principal.getName();
852             }
853             return name;
854         }
855
856 }
857
858
Popular Tags