This project has retired. For details please refer to its Attic page.
AbstractRBACManager xref
View Javadoc

1   package org.apache.archiva.redback.rbac;
2   
3   /*
4    * Copyright 2001-2006 The Apache Software Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  import org.apache.commons.collections.CollectionUtils;
20  import org.apache.commons.lang.StringUtils;
21  import org.slf4j.Logger;
22  import org.slf4j.LoggerFactory;
23  
24  import javax.annotation.PostConstruct;
25  import java.util.ArrayList;
26  import java.util.Collection;
27  import java.util.HashMap;
28  import java.util.HashSet;
29  import java.util.Iterator;
30  import java.util.List;
31  import java.util.Map;
32  import java.util.Set;
33  
34  /**
35   * AbstractRBACManager
36   *
37   * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
38   */
39  public abstract class AbstractRBACManager
40      implements RBACManager
41  {
42      protected Logger log = LoggerFactory.getLogger( getClass() );
43  
44      private List<RBACManagerListener> listeners = new ArrayList<RBACManagerListener>( 0 );
45  
46      private Resource globalResource;
47  
48      @PostConstruct
49      public void initialize()
50      {
51          //no op
52      }
53  
54      public boolean isFinalImplementation()
55      {
56          return false;
57      }
58  
59  
60      public void addListener( RBACManagerListener listener )
61      {
62          if ( !listeners.contains( listener ) )
63          {
64              listeners.add( listener );
65          }
66      }
67  
68      public void removeListener( RBACManagerListener listener )
69      {
70          listeners.remove( listener );
71      }
72  
73      public void fireRbacInit( boolean freshdb )
74      {
75          for ( RBACManagerListener listener : listeners )
76          {
77              try
78              {
79                  listener.rbacInit( freshdb );
80              }
81              catch ( Exception e )
82              {
83                  log.warn( "Unable to trigger .rbacInit( boolean ) to " + listener.getClass().getName(), e );
84              }
85          }
86      }
87  
88      public void fireRbacRoleSaved( Role role )
89      {
90          for ( RBACManagerListener listener : listeners )
91          {
92              try
93              {
94                  listener.rbacRoleSaved( role );
95              }
96              catch ( Exception e )
97              {
98                  log.warn( "Unable to trigger .rbacRoleSaved( Role ) to " + listener.getClass().getName(), e );
99              }
100         }
101     }
102 
103     public void fireRbacRoleRemoved( Role role )
104     {
105         for ( RBACManagerListener listener : listeners )
106         {
107             try
108             {
109                 listener.rbacRoleRemoved( role );
110             }
111             catch ( Exception e )
112             {
113                 log.warn( "Unable to trigger .rbacRoleRemoved( Role ) to " + listener.getClass().getName(), e );
114             }
115         }
116     }
117 
118     public void fireRbacPermissionSaved( Permission permission )
119     {
120         for ( RBACManagerListener listener : listeners )
121         {
122             try
123             {
124                 listener.rbacPermissionSaved( permission );
125             }
126             catch ( Exception e )
127             {
128                 log.warn( "Unable to trigger .rbacPermissionSaved( Permission ) to " + listener.getClass().getName(),
129                           e );
130             }
131         }
132     }
133 
134     public void fireRbacPermissionRemoved( Permission permission )
135     {
136         for ( RBACManagerListener listener : listeners )
137         {
138             try
139             {
140                 listener.rbacPermissionRemoved( permission );
141             }
142             catch ( Exception e )
143             {
144                 log.warn( "Unable to trigger .rbacPermissionRemoved( Permission ) to " + listener.getClass().getName(),
145                           e );
146             }
147         }
148     }
149 
150     public void fireRbacUserAssignmentSaved( UserAssignment userAssignment )
151     {
152         for ( RBACManagerListener listener : listeners )
153         {
154             try
155             {
156                 listener.rbacUserAssignmentSaved( userAssignment );
157             }
158             catch ( Exception e )
159             {
160                 log.warn(
161                     "Unable to trigger .rbacUserAssignmentSaved( UserAssignment ) to " + listener.getClass().getName(),
162                     e );
163             }
164         }
165     }
166 
167     public void fireRbacUserAssignmentRemoved( UserAssignment userAssignment )
168     {
169         for ( RBACManagerListener listener : listeners )
170         {
171             try
172             {
173                 listener.rbacUserAssignmentRemoved( userAssignment );
174             }
175             catch ( Exception e )
176             {
177                 log.warn( "Unable to trigger .rbacUserAssignmentRemoved( UserAssignment ) to "
178                               + listener.getClass().getName(), e );
179             }
180         }
181     }
182 
183     public void removeRole( String roleName )
184         throws RbacObjectNotFoundException, RbacManagerException
185     {
186         removeRole( getRole( roleName ) );
187     }
188 
189     public void removePermission( String permissionName )
190         throws RbacObjectNotFoundException, RbacManagerException
191     {
192         removePermission( getPermission( permissionName ) );
193     }
194 
195     public void removeOperation( String operationName )
196         throws RbacObjectNotFoundException, RbacManagerException
197     {
198         removeOperation( getOperation( operationName ) );
199     }
200 
201     public void removeResource( String resourceIdentifier )
202         throws RbacObjectNotFoundException, RbacManagerException
203     {
204         removeResource( getResource( resourceIdentifier ) );
205     }
206 
207     public void removeUserAssignment( String principal )
208         throws RbacObjectNotFoundException, RbacManagerException
209     {
210         removeUserAssignment( getUserAssignment( principal ) );
211     }
212 
213     public boolean resourceExists( Resource resource )
214     {
215         try
216         {
217             return getAllResources().contains( resource );
218         }
219         catch ( RbacManagerException e )
220         {
221             return false;
222         }
223     }
224 
225     public boolean resourceExists( String identifier )
226     {
227         try
228         {
229             for ( Resource resource : getAllResources() )
230             {
231                 if ( StringUtils.equals( resource.getIdentifier(), identifier ) )
232                 {
233                     return true;
234                 }
235             }
236         }
237         catch ( RbacManagerException e )
238         {
239             return false;
240         }
241 
242         return false;
243     }
244 
245     public boolean operationExists( Operation operation )
246     {
247         try
248         {
249             return getAllOperations().contains( operation );
250         }
251         catch ( RbacManagerException e )
252         {
253             return false;
254         }
255     }
256 
257     public boolean operationExists( String name )
258     {
259         try
260         {
261             for ( Operation operation : getAllOperations() )
262             {
263                 if ( StringUtils.equals( operation.getName(), name ) )
264                 {
265                     return true;
266                 }
267             }
268         }
269         catch ( RbacManagerException e )
270         {
271             return false;
272         }
273 
274         return false;
275     }
276 
277     public boolean permissionExists( Permission permission )
278     {
279         try
280         {
281             return getAllPermissions().contains( permission );
282         }
283         catch ( RbacManagerException e )
284         {
285             return false;
286         }
287     }
288 
289     public boolean permissionExists( String name )
290     {
291         try
292         {
293             for ( Permission permission : getAllPermissions() )
294             {
295                 if ( StringUtils.equals( permission.getName(), name ) )
296                 {
297                     return true;
298                 }
299             }
300         }
301         catch ( RbacManagerException e )
302         {
303             return false;
304         }
305 
306         return false;
307     }
308 
309     public boolean roleExists( Role role )
310         throws RbacManagerException
311     {
312         try
313         {
314             return getAllRoles().contains( role );
315         }
316         catch ( RbacManagerException e )
317         {
318             return false;
319         }
320     }
321 
322     public boolean roleExists( String name )
323         throws RbacManagerException
324     {
325         try
326         {
327             for ( Role role : getAllRoles() )
328             {
329                 if ( StringUtils.equals( role.getName(), name ) )
330                 {
331                     return true;
332                 }
333             }
334         }
335         catch ( RbacManagerException e )
336         {
337             return false;
338         }
339 
340         return false;
341     }
342 
343     public boolean userAssignmentExists( String principal )
344     {
345         try
346         {
347             for ( UserAssignment assignment : getAllUserAssignments() )
348             {
349                 if ( StringUtils.equals( assignment.getPrincipal(), principal ) )
350                 {
351                     return true;
352                 }
353             }
354         }
355         catch ( RbacManagerException e )
356         {
357             return false;
358         }
359 
360         return false;
361     }
362 
363     public boolean userAssignmentExists( UserAssignment assignment )
364     {
365         try
366         {
367             return getAllUserAssignments().contains( assignment );
368         }
369         catch ( RbacManagerException e )
370         {
371             return false;
372         }
373     }
374 
375     /**
376      * returns a set of all permissions that are in all active roles for a given
377      * principal
378      *
379      * @param principal
380      * @return
381      * @throws RbacObjectNotFoundException
382      * @throws RbacManagerException
383      */
384     public Set<Permission> getAssignedPermissions( String principal )
385         throws RbacObjectNotFoundException, RbacManagerException
386     {
387 
388         UserAssignment ua = getUserAssignment( principal );
389 
390         Set<Permission> permissionSet = new HashSet<Permission>();
391 
392         if ( ua.getRoleNames() != null )
393         {
394             boolean childRoleNamesUpdated = false;
395 
396             Iterator<String> it = ua.getRoleNames().listIterator();
397             while ( it.hasNext() )
398             {
399                 String roleName = it.next();
400                 try
401                 {
402                     Role role = getRole( roleName );
403                     gatherUniquePermissions( role, permissionSet );
404                 }
405                 catch ( RbacObjectNotFoundException e )
406                 {
407                     // Found a bad role name. remove it!
408                     it.remove();
409                     childRoleNamesUpdated = true;
410                 }
411             }
412 
413             if ( childRoleNamesUpdated )
414             {
415                 saveUserAssignment( ua );
416             }
417         }
418 
419         return permissionSet;
420     }
421 
422     /**
423      * returns a map of assigned permissions keyed off of operations
424      *
425      * @param principal
426      * @return
427      * @throws RbacObjectNotFoundException
428      * @throws RbacManagerException
429      */
430     public Map<String, List<Permission>> getAssignedPermissionMap( String principal )
431         throws RbacObjectNotFoundException, RbacManagerException
432     {
433         return getPermissionMapByOperation( getAssignedPermissions( principal ) );
434     }
435 
436     private Map<String, List<Permission>> getPermissionMapByOperation( Collection<Permission> permissions )
437     {
438         Map<String, List<Permission>> userPermMap = new HashMap<String, List<Permission>>();
439 
440         for ( Permission permission : permissions )
441         {
442             List<Permission> permList = userPermMap.get( permission.getOperation().getName() );
443 
444             if ( permList != null )
445             {
446                 permList.add( permission );
447             }
448             else
449             {
450                 List<Permission> newPermList = new ArrayList<Permission>( permissions.size() );
451                 newPermList.add( permission );
452                 userPermMap.put( permission.getOperation().getName(), newPermList );
453             }
454         }
455 
456         return userPermMap;
457     }
458 
459     private void gatherUniquePermissions( Role role, Collection<Permission> coll )
460         throws RbacManagerException
461     {
462         if ( role.getPermissions() != null )
463         {
464             for ( Permission permission : role.getPermissions() )
465             {
466                 if ( !coll.contains( permission ) )
467                 {
468                     coll.add( permission );
469                 }
470             }
471         }
472 
473         if ( role.hasChildRoles() )
474         {
475             Map<String, Role> childRoles = getChildRoles( role );
476             Iterator<Role> it = childRoles.values().iterator();
477             while ( it.hasNext() )
478             {
479                 Role child = it.next();
480                 gatherUniquePermissions( child, coll );
481             }
482         }
483     }
484 
485     public List<Role> getAllAssignableRoles()
486         throws RbacManagerException, RbacObjectNotFoundException
487     {
488         List<Role> assignableRoles = new ArrayList<Role>();
489 
490         for ( Role r : getAllRoles() )
491         {
492             Role role = getRole( r.getName() );
493             if ( role.isAssignable() )
494             {
495                 assignableRoles.add( role );
496             }
497         }
498 
499         return assignableRoles;
500     }
501 
502     /**
503      * returns the active roles for a given principal
504      * <p/>
505      * NOTE: roles that are returned might have have roles themselves, if
506      * you just want all permissions then use {@link #getAssignedPermissions(String principal)}
507      *
508      * @param principal
509      * @return
510      * @throws RbacObjectNotFoundException
511      * @throws RbacManagerException
512      */
513     public Collection<Role> getAssignedRoles( String principal )
514         throws RbacObjectNotFoundException, RbacManagerException
515     {
516         UserAssignment ua = getUserAssignment( principal );
517 
518         return getAssignedRoles( ua );
519     }
520 
521     /**
522      * returns only the roles that are assigned, not the roles that might be child roles of the
523      * assigned roles.
524      *
525      * @param ua
526      * @return
527      * @throws RbacObjectNotFoundException
528      * @throws RbacManagerException
529      */
530     public Collection<Role> getAssignedRoles( UserAssignment ua )
531         throws RbacObjectNotFoundException, RbacManagerException
532     {
533         Set<Role> roleSet = new HashSet<Role>();
534 
535         if ( ua.getRoleNames() != null )
536         {
537             boolean childRoleNamesUpdated = false;
538 
539             Iterator<String> it = ua.getRoleNames().listIterator();
540             while ( it.hasNext() )
541             {
542                 String roleName = it.next();
543                 try
544                 {
545                     Role role = getRole( roleName );
546 
547                     if ( !roleSet.contains( role ) )
548                     {
549                         roleSet.add( role );
550                     }
551                 }
552                 catch ( RbacObjectNotFoundException e )
553                 {
554                     // Found a bad role name. remove it!
555                     it.remove();
556                     childRoleNamesUpdated = true;
557                 }
558             }
559 
560             if ( childRoleNamesUpdated )
561             {
562                 saveUserAssignment( ua );
563             }
564         }
565 
566         return roleSet;
567     }
568 
569     /**
570      * get all of the roles that the give role has as a child into a set
571      *
572      * @param role
573      * @param roleSet
574      * @throws RbacObjectNotFoundException
575      * @throws RbacManagerException
576      */
577     private void gatherEffectiveRoles( Role role, Set<Role> roleSet )
578         throws RbacObjectNotFoundException, RbacManagerException
579     {
580         if ( role.hasChildRoles() )
581         {
582             for ( String roleName : role.getChildRoleNames() )
583             {
584                 try
585                 {
586                     Role crole = getRole( roleName );
587 
588                     if ( !roleSet.contains( crole ) )
589                     {
590                         gatherEffectiveRoles( crole, roleSet );
591                     }
592                 }
593                 catch ( RbacObjectNotFoundException e )
594                 {
595                     // the client application might not manage role clean up totally correctly so we want to notify
596                     // of a child role issue and offer a clean up process at some point
597                     log.warn( "dangling child role: " + roleName + " on " + role.getName() );
598                 }
599             }
600         }
601 
602         if ( !roleSet.contains( role ) )
603         {
604             roleSet.add( role );
605         }
606     }
607 
608     public Collection<Role> getEffectivelyAssignedRoles( String principal )
609         throws RbacObjectNotFoundException, RbacManagerException
610     {
611         UserAssignment ua = getUserAssignment( principal );
612 
613         return getEffectivelyAssignedRoles( ua );
614     }
615 
616     public Collection<Role> getEffectivelyAssignedRoles( UserAssignment ua )
617         throws RbacObjectNotFoundException, RbacManagerException
618     {
619         Set<Role> roleSet = new HashSet<Role>();
620 
621         if ( ua != null && ua.getRoleNames() != null )
622         {
623             boolean childRoleNamesUpdated = false;
624 
625             Iterator<String> it = ua.getRoleNames().listIterator();
626             while ( it.hasNext() )
627             {
628                 String roleName = it.next();
629                 try
630                 {
631                     Role role = getRole( roleName );
632 
633                     gatherEffectiveRoles( role, roleSet );
634                 }
635                 catch ( RbacObjectNotFoundException e )
636                 {
637                     // Found a bad role name. remove it!
638                     it.remove();
639                     childRoleNamesUpdated = true;
640                 }
641             }
642 
643             if ( childRoleNamesUpdated )
644             {
645                 saveUserAssignment( ua );
646             }
647         }
648         return roleSet;
649     }
650 
651     /**
652      * @param principal
653      * @return
654      * @throws RbacManagerException
655      * @throws RbacObjectNotFoundException
656      */
657     public Collection<Role> getEffectivelyUnassignedRoles( String principal )
658         throws RbacManagerException, RbacObjectNotFoundException
659     {
660         Collection<Role> assignedRoles = getEffectivelyAssignedRoles( principal );
661         List<Role> allRoles = getAllAssignableRoles();
662 
663         log.debug( "UR: assigned {}", assignedRoles.size() );
664         log.debug( "UR: available {}", allRoles.size() );
665 
666         return CollectionUtils.subtract( allRoles, assignedRoles );
667     }
668 
669 
670     /**
671      * @param principal
672      * @return
673      * @throws RbacManagerException
674      * @throws RbacObjectNotFoundException
675      */
676     public Collection<Role> getUnassignedRoles( String principal )
677         throws RbacManagerException, RbacObjectNotFoundException
678     {
679         Collection<Role> assignedRoles = getAssignedRoles( principal );
680         List<Role> allRoles = getAllAssignableRoles();
681 
682         log.debug( "UR: assigned {}", assignedRoles.size() );
683         log.debug( "UR: available {}", allRoles.size() );
684 
685         return CollectionUtils.subtract( allRoles, assignedRoles );
686     }
687 
688     public Resource getGlobalResource()
689         throws RbacManagerException
690     {
691         if ( globalResource == null )
692         {
693             globalResource = createResource( Resource.GLOBAL );
694             globalResource.setPermanent( true );
695             globalResource = saveResource( globalResource );
696         }
697         return globalResource;
698     }
699 
700     public void addChildRole( Role role, Role childRole )
701         throws RbacObjectInvalidException, RbacManagerException
702     {
703         saveRole( childRole );
704         role.addChildRoleName( childRole.getName() );
705     }
706 
707     public Map<String, Role> getChildRoles( Role role )
708         throws RbacManagerException
709     {
710         Map<String, Role> childRoles = new HashMap<String, Role>();
711 
712         boolean childRoleNamesUpdated = false;
713 
714         Iterator<String> it = role.getChildRoleNames().listIterator();
715 
716         List<String> updatedChildRoleList = new ArrayList<String>( role.getChildRoleNames().size() );
717 
718         while ( it.hasNext() )
719         {
720             String roleName = it.next();
721             try
722             {
723                 Role child = getRole( roleName );
724                 // archiva can change role manager but LDAP can be non writable so in such case
725                 // some roles doesn't exists !!
726                 if ( child != null )
727                 {
728                     childRoles.put( child.getName(), child );
729                     updatedChildRoleList.add( roleName );
730                 }
731                 else
732                 {
733                     log.warn(
734                         "error searching role with name '{}' probably some issues when migrating your role manager",
735                         roleName );
736                 }
737             }
738             catch ( RbacObjectNotFoundException e )
739             {
740                 // Found a bad roleName! - trigger new List save
741                 //it.remove();
742                 childRoleNamesUpdated = true;
743             }
744         }
745 
746         if ( childRoleNamesUpdated )
747         {
748             role.setChildRoleNames( updatedChildRoleList );
749             saveRole( role );
750         }
751 
752         return childRoles;
753     }
754 
755     public Map<String, Role> getParentRoles( Role role )
756         throws RbacManagerException
757     {
758         Map<String, Role> parentRoles = new HashMap<String, Role>();
759 
760         for ( Role r : getAllRoles() )
761         {
762             if ( !r.getName().equals( role.getName() ) )
763             {
764                 Set<Role> effectiveRoles = getEffectiveRoles( r );
765                 for ( Role currentRole : effectiveRoles )
766                 {
767                     if ( currentRole.getName().equals( role.getName() ) )
768                     {
769                         if ( !parentRoles.containsKey( r.getName() ) )
770                         {
771                             parentRoles.put( r.getName(), r );
772                         }
773                     }
774                 }
775             }
776         }
777         return parentRoles;
778     }
779 
780     public Set<Role> getEffectiveRoles( Role role )
781         throws RbacObjectNotFoundException, RbacManagerException
782     {
783         Set<Role> roleSet = new HashSet<Role>();
784         gatherEffectiveRoles( role, roleSet );
785 
786         return roleSet;
787     }
788 
789     public Map<String, Role> getRoles( Collection<String> roleNames )
790         throws RbacObjectNotFoundException, RbacManagerException
791     {
792         Map<String, Role> roleMap = new HashMap<String, Role>();
793 
794         for ( String roleName : roleNames )
795         {
796             Role child = getRole( roleName );
797             roleMap.put( child.getName(), child );
798         }
799 
800         return roleMap;
801     }
802 }