1 package org.apache.archiva.redback.rbac;
4 * Copyright 2001-2006 The Apache Software Foundation.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 import org.codehaus.plexus.util.CollectionUtils;
20 import org.codehaus.plexus.util.StringUtils;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
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;
37 * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
40 public abstract class AbstractRBACManager
41 implements RBACManager
43 protected Logger log = LoggerFactory.getLogger( getClass() );
45 private List<RBACManagerListener> listeners = new ArrayList<RBACManagerListener>( 0 );
47 private Resource globalResource;
50 public void initialize()
55 public void addListener( RBACManagerListener listener )
57 if ( !listeners.contains( listener ) )
59 listeners.add( listener );
63 public void removeListener( RBACManagerListener listener )
65 listeners.remove( listener );
68 public void fireRbacInit( boolean freshdb )
70 Iterator<RBACManagerListener> it = listeners.iterator();
71 while ( it.hasNext() )
73 RBACManagerListener listener = it.next();
76 listener.rbacInit( freshdb );
80 log.warn( "Unable to trigger .rbacInit( boolean ) to " + listener.getClass().getName(), e );
85 public void fireRbacRoleSaved( Role role )
87 Iterator<RBACManagerListener> it = listeners.iterator();
88 while ( it.hasNext() )
90 RBACManagerListener listener = it.next();
93 listener.rbacRoleSaved( role );
97 log.warn( "Unable to trigger .rbacRoleSaved( Role ) to " + listener.getClass().getName(), e );
102 public void fireRbacRoleRemoved( Role role )
104 Iterator<RBACManagerListener> it = listeners.iterator();
105 while ( it.hasNext() )
107 RBACManagerListener listener = it.next();
110 listener.rbacRoleRemoved( role );
112 catch ( Exception e )
114 log.warn( "Unable to trigger .rbacRoleRemoved( Role ) to " + listener.getClass().getName(), e );
119 public void fireRbacPermissionSaved( Permission permission )
121 Iterator<RBACManagerListener> it = listeners.iterator();
122 while ( it.hasNext() )
124 RBACManagerListener listener = it.next();
127 listener.rbacPermissionSaved( permission );
129 catch ( Exception e )
131 log.warn( "Unable to trigger .rbacPermissionSaved( Permission ) to " + listener.getClass().getName(),
137 public void fireRbacPermissionRemoved( Permission permission )
139 Iterator<RBACManagerListener> it = listeners.iterator();
140 while ( it.hasNext() )
142 RBACManagerListener listener = it.next();
145 listener.rbacPermissionRemoved( permission );
147 catch ( Exception e )
149 log.warn( "Unable to trigger .rbacPermissionRemoved( Permission ) to " + listener.getClass().getName(),
155 public void fireRbacUserAssignmentSaved( UserAssignment userAssignment )
157 Iterator<RBACManagerListener> it = listeners.iterator();
158 while ( it.hasNext() )
160 RBACManagerListener listener = it.next();
163 listener.rbacUserAssignmentSaved( userAssignment );
165 catch ( Exception e )
168 "Unable to trigger .rbacUserAssignmentSaved( UserAssignment ) to " + listener.getClass().getName(),
174 public void fireRbacUserAssignmentRemoved( UserAssignment userAssignment )
176 Iterator<RBACManagerListener> it = listeners.iterator();
177 while ( it.hasNext() )
179 RBACManagerListener listener = it.next();
182 listener.rbacUserAssignmentRemoved( userAssignment );
184 catch ( Exception e )
186 log.warn( "Unable to trigger .rbacUserAssignmentRemoved( UserAssignment ) to "
187 + listener.getClass().getName(), e );
192 public void removeRole( String roleName )
193 throws RbacObjectNotFoundException, RbacManagerException
195 removeRole( getRole( roleName ) );
198 public void removePermission( String permissionName )
199 throws RbacObjectNotFoundException, RbacManagerException
201 removePermission( getPermission( permissionName ) );
204 public void removeOperation( String operationName )
205 throws RbacObjectNotFoundException, RbacManagerException
207 removeOperation( getOperation( operationName ) );
210 public void removeResource( String resourceIdentifier )
211 throws RbacObjectNotFoundException, RbacManagerException
213 removeResource( getResource( resourceIdentifier ) );
216 public void removeUserAssignment( String principal )
217 throws RbacObjectNotFoundException, RbacManagerException
219 removeUserAssignment( getUserAssignment( principal ) );
222 public boolean resourceExists( Resource resource )
226 return getAllResources().contains( resource );
228 catch ( RbacManagerException e )
234 public boolean resourceExists( String identifier )
238 for ( Resource resource : getAllResources() )
240 if ( StringUtils.equals( resource.getIdentifier(), identifier ) )
246 catch ( RbacManagerException e )
254 public boolean operationExists( Operation operation )
258 return getAllOperations().contains( operation );
260 catch ( RbacManagerException e )
266 public boolean operationExists( String name )
270 for ( Operation operation : getAllOperations() )
272 if ( StringUtils.equals( operation.getName(), name ) )
278 catch ( RbacManagerException e )
286 public boolean permissionExists( Permission permission )
290 return getAllPermissions().contains( permission );
292 catch ( RbacManagerException e )
298 public boolean permissionExists( String name )
302 for ( Permission permission : getAllPermissions() )
304 if ( StringUtils.equals( permission.getName(), name ) )
310 catch ( RbacManagerException e )
318 public boolean roleExists( Role role )
322 return getAllRoles().contains( role );
324 catch ( RbacManagerException e )
330 public boolean roleExists( String name )
334 for ( Role role : getAllRoles() )
336 if ( StringUtils.equals( role.getName(), name ) )
342 catch ( RbacManagerException e )
350 public boolean userAssignmentExists( String principal )
354 for ( UserAssignment assignment : getAllUserAssignments() )
356 if ( StringUtils.equals( assignment.getPrincipal(), principal ) )
362 catch ( RbacManagerException e )
370 public boolean userAssignmentExists( UserAssignment assignment )
374 return getAllUserAssignments().contains( assignment );
376 catch ( RbacManagerException e )
383 * returns a set of all permissions that are in all active roles for a given
388 * @throws RbacObjectNotFoundException
389 * @throws RbacManagerException
391 public Set<Permission> getAssignedPermissions( String principal )
392 throws RbacObjectNotFoundException, RbacManagerException
395 UserAssignment ua = getUserAssignment( principal );
397 Set<Permission> permissionSet = new HashSet<Permission>();
399 if ( ua.getRoleNames() != null )
401 boolean childRoleNamesUpdated = false;
403 Iterator<String> it = ua.getRoleNames().listIterator();
404 while ( it.hasNext() )
406 String roleName = it.next();
409 Role role = getRole( roleName );
410 gatherUniquePermissions( role, permissionSet );
412 catch ( RbacObjectNotFoundException e )
414 // Found a bad role name. remove it!
416 childRoleNamesUpdated = true;
420 if ( childRoleNamesUpdated )
422 saveUserAssignment( ua );
426 return permissionSet;
430 * returns a map of assigned permissions keyed off of operations
434 * @throws RbacObjectNotFoundException
435 * @throws RbacManagerException
437 public Map<String, List<Permission>> getAssignedPermissionMap( String principal )
438 throws RbacObjectNotFoundException, RbacManagerException
440 return getPermissionMapByOperation( getAssignedPermissions( principal ) );
443 private Map<String, List<Permission>> getPermissionMapByOperation( Collection<Permission> permissions )
445 Map<String, List<Permission>> userPermMap = new HashMap<String, List<Permission>>();
447 for ( Permission permission : permissions )
449 List<Permission> permList = userPermMap.get( permission.getOperation().getName() );
451 if ( permList != null )
453 permList.add( permission );
457 List<Permission> newPermList = new ArrayList<Permission>( permissions.size() );
458 newPermList.add( permission );
459 userPermMap.put( permission.getOperation().getName(), newPermList );
466 private void gatherUniquePermissions( Role role, Collection<Permission> coll )
467 throws RbacManagerException
469 if ( role.getPermissions() != null )
471 for ( Permission permission : role.getPermissions() )
473 if ( !coll.contains( permission ) )
475 coll.add( permission );
480 if ( role.hasChildRoles() )
482 Map<String, Role> childRoles = getChildRoles( role );
483 Iterator<Role> it = childRoles.values().iterator();
484 while ( it.hasNext() )
486 Role child = it.next();
487 gatherUniquePermissions( child, coll );
492 public List<Role> getAllAssignableRoles()
493 throws RbacManagerException, RbacObjectNotFoundException
495 List<Role> assignableRoles = new ArrayList<Role>();
497 for ( Role r : getAllRoles() )
499 Role role = getRole( r.getName() );
500 if ( role.isAssignable() )
502 assignableRoles.add( role );
506 return assignableRoles;
510 * returns the active roles for a given principal
512 * NOTE: roles that are returned might have have roles themselves, if
513 * you just want all permissions then use {@link #getAssignedPermissions(String principal)}
517 * @throws RbacObjectNotFoundException
518 * @throws RbacManagerException
520 public Collection<Role> getAssignedRoles( String principal )
521 throws RbacObjectNotFoundException, RbacManagerException
523 UserAssignment ua = getUserAssignment( principal );
525 return getAssignedRoles( ua );
529 * returns only the roles that are assigned, not the roles that might be child roles of the
534 * @throws RbacObjectNotFoundException
535 * @throws RbacManagerException
537 public Collection<Role> getAssignedRoles( UserAssignment ua )
538 throws RbacObjectNotFoundException, RbacManagerException
540 Set<Role> roleSet = new HashSet<Role>();
542 if ( ua.getRoleNames() != null )
544 boolean childRoleNamesUpdated = false;
546 Iterator<String> it = ua.getRoleNames().listIterator();
547 while ( it.hasNext() )
549 String roleName = it.next();
552 Role role = getRole( roleName );
554 if ( !roleSet.contains( role ) )
559 catch ( RbacObjectNotFoundException e )
561 // Found a bad role name. remove it!
563 childRoleNamesUpdated = true;
567 if ( childRoleNamesUpdated )
569 saveUserAssignment( ua );
577 * get all of the roles that the give role has as a child into a set
581 * @throws RbacObjectNotFoundException
582 * @throws RbacManagerException
584 private void gatherEffectiveRoles( Role role, Set<Role> roleSet )
585 throws RbacObjectNotFoundException, RbacManagerException
587 if ( role.hasChildRoles() )
589 for ( String roleName : role.getChildRoleNames() )
593 Role crole = getRole( roleName );
595 if ( !roleSet.contains( crole ) )
597 gatherEffectiveRoles( crole, roleSet );
600 catch ( RbacObjectNotFoundException e )
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() );
609 if ( !roleSet.contains( role ) )
615 public Collection<Role> getEffectivelyAssignedRoles( String principal )
616 throws RbacObjectNotFoundException, RbacManagerException
618 UserAssignment ua = getUserAssignment( principal );
620 return getEffectivelyAssignedRoles( ua );
623 public Collection<Role> getEffectivelyAssignedRoles( UserAssignment ua )
624 throws RbacObjectNotFoundException, RbacManagerException
626 Set<Role> roleSet = new HashSet<Role>();
628 if ( ua != null && ua.getRoleNames() != null )
630 boolean childRoleNamesUpdated = false;
632 Iterator<String> it = ua.getRoleNames().listIterator();
633 while ( it.hasNext() )
635 String roleName = it.next();
638 Role role = getRole( roleName );
640 gatherEffectiveRoles( role, roleSet );
642 catch ( RbacObjectNotFoundException e )
644 // Found a bad role name. remove it!
646 childRoleNamesUpdated = true;
650 if ( childRoleNamesUpdated )
652 saveUserAssignment( ua );
661 * @throws RbacManagerException
662 * @throws RbacObjectNotFoundException
664 @SuppressWarnings( "unchecked" )
665 public Collection<Role> getEffectivelyUnassignedRoles( String principal )
666 throws RbacManagerException, RbacObjectNotFoundException
668 Collection<Role> assignedRoles = getEffectivelyAssignedRoles( principal );
669 List<Role> allRoles = getAllAssignableRoles();
671 log.debug( "UR: assigned {}", assignedRoles.size() );
672 log.debug( "UR: available {}", allRoles.size() );
674 return CollectionUtils.subtract( allRoles, assignedRoles );
681 * @throws RbacManagerException
682 * @throws RbacObjectNotFoundException
684 @SuppressWarnings( "unchecked" )
685 public Collection<Role> getUnassignedRoles( String principal )
686 throws RbacManagerException, RbacObjectNotFoundException
688 Collection<Role> assignedRoles = getAssignedRoles( principal );
689 List<Role> allRoles = getAllAssignableRoles();
691 log.debug( "UR: assigned {}", assignedRoles.size() );
692 log.debug( "UR: available {}", allRoles.size() );
694 return CollectionUtils.subtract( allRoles, assignedRoles );
697 public Resource getGlobalResource()
698 throws RbacManagerException
700 if ( globalResource == null )
702 globalResource = createResource( Resource.GLOBAL );
703 globalResource.setPermanent( true );
704 globalResource = saveResource( globalResource );
706 return globalResource;
709 public void addChildRole( Role role, Role childRole )
710 throws RbacObjectInvalidException, RbacManagerException
712 saveRole( childRole );
713 role.addChildRoleName( childRole.getName() );
716 public Map<String, Role> getChildRoles( Role role )
717 throws RbacManagerException
719 Map<String, Role> childRoles = new HashMap<String, Role>();
721 boolean childRoleNamesUpdated = false;
723 Iterator<String> it = role.getChildRoleNames().listIterator();
724 while ( it.hasNext() )
726 String roleName = (String) it.next();
729 Role child = getRole( roleName );
730 childRoles.put( child.getName(), child );
732 catch ( RbacObjectNotFoundException e )
734 // Found a bad roleName! - remove it.
736 childRoleNamesUpdated = true;
740 if ( childRoleNamesUpdated )
748 public Map<String, Role> getParentRoles( Role role )
749 throws RbacManagerException
751 Map<String, Role> parentRoles = new HashMap<String, Role>();
753 for ( Role r : getAllRoles() )
755 if ( !r.getName().equals( role.getName() ) )
757 Set<Role> effectiveRoles = getEffectiveRoles( r );
758 for ( Role currentRole : effectiveRoles )
760 if ( currentRole.getName().equals( role.getName() ) )
762 if ( !parentRoles.containsKey( r.getName() ) )
764 parentRoles.put( r.getName(), r );
773 public Set<Role> getEffectiveRoles( Role role )
774 throws RbacObjectNotFoundException, RbacManagerException
776 Set<Role> roleSet = new HashSet<Role>();
777 gatherEffectiveRoles( role, roleSet );
782 public Map<String, Role> getRoles( Collection<String> roleNames )
783 throws RbacObjectNotFoundException, RbacManagerException
785 Map<String, Role> roleMap = new HashMap<String, Role>();
787 for ( String roleName : roleNames )
789 Role child = getRole( roleName );
790 roleMap.put( child.getName(), child );