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