1 package org.apache.archiva.redback.rbac.cached;
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
22 import org.apache.archiva.redback.components.cache.Cache;
23 import org.apache.archiva.redback.rbac.Operation;
24 import org.apache.archiva.redback.rbac.Permission;
25 import org.apache.archiva.redback.rbac.RBACManager;
26 import org.apache.archiva.redback.rbac.RBACManagerListener;
27 import org.apache.archiva.redback.rbac.RbacManagerException;
28 import org.apache.archiva.redback.rbac.RbacObjectInvalidException;
29 import org.apache.archiva.redback.rbac.RbacObjectNotFoundException;
30 import org.apache.archiva.redback.rbac.Resource;
31 import org.apache.archiva.redback.rbac.Role;
32 import org.apache.archiva.redback.rbac.UserAssignment;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35 import org.springframework.stereotype.Service;
37 import javax.inject.Inject;
38 import javax.inject.Named;
39 import java.util.Collection;
40 import java.util.List;
45 * CachedRbacManager is a wrapped RBACManager with caching.
47 * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
49 @Service("rbacManager#cached")
50 public class CachedRbacManager
51 implements RBACManager, RBACManagerListener
54 private Logger log = LoggerFactory.getLogger( getClass() );
57 @Named(value = "rbacManager#jdo")
58 private RBACManager rbacImpl;
61 @Named(value = "cache#operations")
62 private Cache operationsCache;
65 @Named(value = "cache#permissions")
66 private Cache permissionsCache;
69 @Named(value = "cache#resources")
70 private Cache resourcesCache;
73 @Named(value = "cache#roles")
74 private Cache rolesCache;
77 @Named(value = "cache#userAssignments")
78 private Cache userAssignmentsCache;
81 @Named(value = "cache#userPermissions")
82 private Cache userPermissionsCache;
85 @Named(value = "cache#effectiveRoleSet")
86 private Cache effectiveRoleSetCache;
88 public void addChildRole( Role role, Role childRole )
89 throws RbacObjectInvalidException, RbacManagerException
93 this.rbacImpl.addChildRole( role, childRole );
97 invalidateCachedRole( role );
98 invalidateCachedRole( childRole );
102 public void addListener( RBACManagerListener listener )
104 this.rbacImpl.addListener( listener );
107 public Operation createOperation( String name )
108 throws RbacManagerException
110 operationsCache.remove( name );
111 return this.rbacImpl.createOperation( name );
114 public Permission createPermission( String name )
115 throws RbacManagerException
117 permissionsCache.remove( name );
118 return this.rbacImpl.createPermission( name );
121 public Permission createPermission( String name, String operationName, String resourceIdentifier )
122 throws RbacManagerException
124 permissionsCache.remove( name );
125 return this.rbacImpl.createPermission( name, operationName, resourceIdentifier );
128 public Resource createResource( String identifier )
129 throws RbacManagerException
131 resourcesCache.remove( identifier );
132 return this.rbacImpl.createResource( identifier );
135 public Role createRole( String name )
137 rolesCache.remove( name );
138 return this.rbacImpl.createRole( name );
141 public UserAssignment createUserAssignment( String principal )
142 throws RbacManagerException
144 invalidateCachedUserAssignment( principal );
145 return this.rbacImpl.createUserAssignment( principal );
148 public void eraseDatabase()
152 this.rbacImpl.eraseDatabase();
157 //EhcacheUtils.clearAllCaches( log() );
162 * @see org.apache.archiva.redback.rbac.RBACManager#getAllAssignableRoles()
164 public List<Role> getAllAssignableRoles()
165 throws RbacManagerException, RbacObjectNotFoundException
167 log.debug( "NOT CACHED - .getAllAssignableRoles()" );
168 return this.rbacImpl.getAllAssignableRoles();
171 public List<Operation> getAllOperations()
172 throws RbacManagerException
174 log.debug( "NOT CACHED - .getAllOperations()" );
175 return this.rbacImpl.getAllOperations();
178 public List<Permission> getAllPermissions()
179 throws RbacManagerException
181 log.debug( "NOT CACHED - .getAllPermissions()" );
182 return this.rbacImpl.getAllPermissions();
185 public List<Resource> getAllResources()
186 throws RbacManagerException
188 log.debug( "NOT CACHED - .getAllResources()" );
189 return this.rbacImpl.getAllResources();
192 public List<Role> getAllRoles()
193 throws RbacManagerException
195 log.debug( "NOT CACHED - .getAllRoles()" );
196 return this.rbacImpl.getAllRoles();
199 public List<UserAssignment> getAllUserAssignments()
200 throws RbacManagerException
202 log.debug( "NOT CACHED - .getAllUserAssignments()" );
203 return this.rbacImpl.getAllUserAssignments();
207 * @see org.apache.archiva.redback.rbac.RBACManager#getAssignedPermissionMap(java.lang.String)
209 @SuppressWarnings("unchecked")
210 public Map<String, List<Permission>> getAssignedPermissionMap( String principal )
211 throws RbacObjectNotFoundException, RbacManagerException
213 Map<String, List<Permission>> el = (Map<String, List<Permission>>) userPermissionsCache.get( principal );
217 log.debug( "using cached user permission map" );
221 log.debug( "building user permission map" );
222 Map<String, List<Permission>> userPermMap = this.rbacImpl.getAssignedPermissionMap( principal );
223 userPermissionsCache.put( principal, userPermMap );
228 public Set<Permission> getAssignedPermissions( String principal )
229 throws RbacObjectNotFoundException, RbacManagerException
231 log.debug( "NOT CACHED - .getAssignedPermissions(String)" );
232 return this.rbacImpl.getAssignedPermissions( principal );
235 public Collection<Role> getAssignedRoles( String principal )
236 throws RbacObjectNotFoundException, RbacManagerException
238 log.debug( "NOT CACHED - .getAssignedRoles(String)" );
239 return this.rbacImpl.getAssignedRoles( principal );
242 public Collection<Role> getAssignedRoles( UserAssignment userAssignment )
243 throws RbacObjectNotFoundException, RbacManagerException
245 log.debug( "NOT CACHED - .getAssignedRoles(UserAssignment)" );
246 return this.rbacImpl.getAssignedRoles( userAssignment );
249 public Map<String, Role> getChildRoles( Role role )
250 throws RbacManagerException
252 log.debug( "NOT CACHED - .getChildRoles(Role)" );
253 return this.rbacImpl.getChildRoles( role );
256 public Map<String, Role> getParentRoles( Role role )
257 throws RbacManagerException
259 log.debug( "NOT CACHED - .getParentRoles(Role)" );
260 return this.rbacImpl.getParentRoles( role );
263 public Collection<Role> getEffectivelyAssignedRoles( String principal )
264 throws RbacObjectNotFoundException, RbacManagerException
266 log.debug( "NOT CACHED - .getEffectivelyAssignedRoles(String)" );
267 return this.rbacImpl.getEffectivelyAssignedRoles( principal );
270 public Collection<Role> getEffectivelyUnassignedRoles( String principal )
271 throws RbacManagerException, RbacObjectNotFoundException
273 log.debug( "NOT CACHED - .getEffectivelyUnassignedRoles(String)" );
274 return this.rbacImpl.getEffectivelyUnassignedRoles( principal );
277 @SuppressWarnings("unchecked")
278 public Set<Role> getEffectiveRoles( Role role )
279 throws RbacObjectNotFoundException, RbacManagerException
281 Set<Role> el = (Set<Role>) effectiveRoleSetCache.get( role.getName() );
285 log.debug( "using cached effective role set" );
290 log.debug( "building effective role set" );
291 Set<Role> effectiveRoleSet = this.rbacImpl.getEffectiveRoles( role );
292 effectiveRoleSetCache.put( role.getName(), effectiveRoleSet );
293 return effectiveRoleSet;
297 public Resource getGlobalResource()
298 throws RbacManagerException
300 /* this is very light */
301 log.debug( "NOT CACHED - .getGlobalResource()" );
302 return this.rbacImpl.getGlobalResource();
305 public Operation getOperation( String operationName )
306 throws RbacObjectNotFoundException, RbacManagerException
308 Object el = operationsCache.get( operationName );
311 return (Operation) el;
315 Operation operation = this.rbacImpl.getOperation( operationName );
316 operationsCache.put( operationName, operation );
321 public Permission getPermission( String permissionName )
322 throws RbacObjectNotFoundException, RbacManagerException
324 Object el = permissionsCache.get( permissionName );
327 return (Permission) el;
331 Permission permission = this.rbacImpl.getPermission( permissionName );
332 permissionsCache.put( permissionName, permission );
337 public Resource getResource( String resourceIdentifier )
338 throws RbacObjectNotFoundException, RbacManagerException
340 Object el = resourcesCache.get( resourceIdentifier );
343 return (Resource) el;
347 Resource resource = this.rbacImpl.getResource( resourceIdentifier );
348 resourcesCache.put( resourceIdentifier, resource );
353 public Role getRole( String roleName )
354 throws RbacObjectNotFoundException, RbacManagerException
356 Object el = rolesCache.get( roleName );
363 Role role = this.rbacImpl.getRole( roleName );
364 rolesCache.put( roleName, role );
369 public Map<String, Role> getRoles( Collection<String> roleNames )
370 throws RbacObjectNotFoundException, RbacManagerException
372 log.debug( "NOT CACHED - .getRoles(Collection)" );
373 return this.rbacImpl.getRoles( roleNames );
376 public Collection<Role> getUnassignedRoles( String principal )
377 throws RbacManagerException, RbacObjectNotFoundException
379 log.debug( "NOT CACHED - .getUnassignedRoles(String)" );
380 return this.rbacImpl.getUnassignedRoles( principal );
383 public UserAssignment getUserAssignment( String principal )
384 throws RbacObjectNotFoundException, RbacManagerException
386 Object el = userAssignmentsCache.get( principal );
389 return (UserAssignment) el;
393 UserAssignment userAssignment = this.rbacImpl.getUserAssignment( principal );
394 userAssignmentsCache.put( principal, userAssignment );
395 return userAssignment;
399 public List<UserAssignment> getUserAssignmentsForRoles( Collection<String> roleNames )
400 throws RbacManagerException
402 log.debug( "NOT CACHED - .getUserAssignmentsForRoles(Collection)" );
403 return this.rbacImpl.getUserAssignmentsForRoles( roleNames );
406 public boolean operationExists( Operation operation )
408 if ( operation == null )
413 if ( operationsCache.hasKey( operation.getName() ) )
418 return this.rbacImpl.operationExists( operation );
421 public boolean operationExists( String name )
423 if ( operationsCache.hasKey( name ) )
428 return this.rbacImpl.operationExists( name );
431 public boolean permissionExists( Permission permission )
433 if ( permission == null )
438 if ( permissionsCache.hasKey( permission.getName() ) )
443 return this.rbacImpl.permissionExists( permission );
446 public boolean permissionExists( String name )
448 if ( permissionsCache.hasKey( name ) )
453 return this.rbacImpl.permissionExists( name );
456 public void rbacInit( boolean freshdb )
458 if ( rbacImpl instanceof RBACManagerListener )
460 ( (RBACManagerListener) this.rbacImpl ).rbacInit( freshdb );
462 // lookup all Cache and clear all ?
463 this.resourcesCache.clear();
464 this.operationsCache.clear();
465 this.permissionsCache.clear();
466 this.rolesCache.clear();
467 this.userAssignmentsCache.clear();
468 this.userPermissionsCache.clear();
471 public void rbacPermissionRemoved( Permission permission )
473 if ( rbacImpl instanceof RBACManagerListener )
475 ( (RBACManagerListener) this.rbacImpl ).rbacPermissionRemoved( permission );
478 invalidateCachedPermission( permission );
481 public void rbacPermissionSaved( Permission permission )
483 if ( rbacImpl instanceof RBACManagerListener )
485 ( (RBACManagerListener) this.rbacImpl ).rbacPermissionSaved( permission );
488 invalidateCachedPermission( permission );
491 public void rbacRoleRemoved( Role role )
493 if ( rbacImpl instanceof RBACManagerListener )
495 ( (RBACManagerListener) this.rbacImpl ).rbacRoleRemoved( role );
498 invalidateCachedRole( role );
501 public void rbacRoleSaved( Role role )
503 if ( rbacImpl instanceof RBACManagerListener )
505 ( (RBACManagerListener) this.rbacImpl ).rbacRoleSaved( role );
508 invalidateCachedRole( role );
511 public void rbacUserAssignmentRemoved( UserAssignment userAssignment )
513 if ( rbacImpl instanceof RBACManagerListener )
515 ( (RBACManagerListener) this.rbacImpl ).rbacUserAssignmentRemoved( userAssignment );
518 invalidateCachedUserAssignment( userAssignment );
521 public void rbacUserAssignmentSaved( UserAssignment userAssignment )
523 if ( rbacImpl instanceof RBACManagerListener )
525 ( (RBACManagerListener) this.rbacImpl ).rbacUserAssignmentSaved( userAssignment );
528 invalidateCachedUserAssignment( userAssignment );
531 public void removeListener( RBACManagerListener listener )
533 this.rbacImpl.removeListener( listener );
536 public void removeOperation( Operation operation )
537 throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
539 invalidateCachedOperation( operation );
540 this.rbacImpl.removeOperation( operation );
543 public void removeOperation( String operationName )
544 throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
546 operationsCache.remove( operationName );
547 this.rbacImpl.removeOperation( operationName );
550 public void removePermission( Permission permission )
551 throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
553 invalidateCachedPermission( permission );
554 this.rbacImpl.removePermission( permission );
557 public void removePermission( String permissionName )
558 throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
560 permissionsCache.remove( permissionName );
561 this.rbacImpl.removePermission( permissionName );
564 public void removeResource( Resource resource )
565 throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
567 invalidateCachedResource( resource );
568 this.rbacImpl.removeResource( resource );
571 public void removeResource( String resourceIdentifier )
572 throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
574 resourcesCache.remove( resourceIdentifier );
575 this.rbacImpl.removeResource( resourceIdentifier );
578 public void removeRole( Role role )
579 throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
581 invalidateCachedRole( role );
582 this.rbacImpl.removeRole( role );
585 public void removeRole( String roleName )
586 throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
588 rolesCache.remove( roleName );
589 this.rbacImpl.removeRole( roleName );
592 public void removeUserAssignment( String principal )
593 throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
595 invalidateCachedUserAssignment( principal );
596 this.rbacImpl.removeUserAssignment( principal );
599 public void removeUserAssignment( UserAssignment userAssignment )
600 throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
602 invalidateCachedUserAssignment( userAssignment );
603 this.rbacImpl.removeUserAssignment( userAssignment );
606 public boolean resourceExists( Resource resource )
608 if ( resourcesCache.hasKey( resource.getIdentifier() ) )
613 return this.rbacImpl.resourceExists( resource );
616 public boolean resourceExists( String identifier )
618 if ( resourcesCache.hasKey( identifier ) )
623 return this.rbacImpl.resourceExists( identifier );
626 public boolean roleExists( Role role )
628 if ( rolesCache.hasKey( role.getName() ) )
633 return this.rbacImpl.roleExists( role );
636 public boolean roleExists( String name )
638 if ( rolesCache.hasKey( name ) )
643 return this.rbacImpl.roleExists( name );
646 public Operation saveOperation( Operation operation )
647 throws RbacObjectInvalidException, RbacManagerException
649 invalidateCachedOperation( operation );
650 return this.rbacImpl.saveOperation( operation );
653 public Permission savePermission( Permission permission )
654 throws RbacObjectInvalidException, RbacManagerException
656 invalidateCachedPermission( permission );
657 return this.rbacImpl.savePermission( permission );
660 public Resource saveResource( Resource resource )
661 throws RbacObjectInvalidException, RbacManagerException
663 invalidateCachedResource( resource );
664 return this.rbacImpl.saveResource( resource );
667 public synchronized Role saveRole( Role role )
668 throws RbacObjectInvalidException, RbacManagerException
671 List assignments = this.rbacImpl.getUserAssignmentsForRoles( Collections.singletonList( role.getName() ) );
673 for ( Iterator i = assignments.iterator(); i.hasNext(); )
675 log.debug( "invalidating user assignment with role " + role.getName() );
676 invalidateCachedUserAssignment( (UserAssignment)i.next() );
681 the above commented out section would try and invalidate just that user caches that are effected by
682 changes in the users permissions map due to role changes.
684 however the implementations of those do not take into account child role hierarchies so wipe all
685 user caches on role saving...which is a heavy handed way to solve the problem, but not going to
686 happen frequently for current applications so not a huge deal.
688 invalidateAllCachedUserAssignments();
689 invalidateCachedRole( role );
690 return this.rbacImpl.saveRole( role );
693 public synchronized void saveRoles( Collection<Role> roles )
694 throws RbacObjectInvalidException, RbacManagerException
697 for ( Role role : roles )
699 invalidateCachedRole( role );
703 List assignments = this.rbacImpl.getUserAssignmentsForRoles( roles );
705 for ( Iterator i = assignments.iterator(); i.hasNext(); )
707 log.debug( "invalidating user assignment with roles" );
708 invalidateCachedUserAssignment( (UserAssignment)i.next() );
711 invalidateAllCachedUserAssignments();
712 this.rbacImpl.saveRoles( roles );
715 public UserAssignment saveUserAssignment( UserAssignment userAssignment )
716 throws RbacObjectInvalidException, RbacManagerException
718 invalidateCachedUserAssignment( userAssignment );
719 return this.rbacImpl.saveUserAssignment( userAssignment );
722 public boolean userAssignmentExists( String principal )
724 if ( userAssignmentsCache.hasKey( principal ) )
729 return this.rbacImpl.userAssignmentExists( principal );
732 public boolean userAssignmentExists( UserAssignment assignment )
734 if ( userAssignmentsCache.hasKey( assignment.getPrincipal() ) )
739 return this.rbacImpl.userAssignmentExists( assignment );
742 private void invalidateCachedRole( Role role )
746 rolesCache.remove( role.getName() );
747 // if a role changes we need to invalidate the entire effective role set cache
748 // since we have no concept of the heirarchy involved in the role sets
749 effectiveRoleSetCache.clear();
754 private void invalidateCachedOperation( Operation operation )
756 if ( operation != null )
758 operationsCache.remove( operation.getName() );
762 private void invalidateCachedPermission( Permission permission )
764 if ( permission != null )
766 permissionsCache.remove( permission.getName() );
770 private void invalidateCachedResource( Resource resource )
772 if ( resource != null )
774 resourcesCache.remove( resource.getIdentifier() );
778 private void invalidateCachedUserAssignment( UserAssignment userAssignment )
780 if ( userAssignment != null )
782 userAssignmentsCache.remove( userAssignment.getPrincipal() );
783 userPermissionsCache.remove( userAssignment.getPrincipal() );
787 private void invalidateCachedUserAssignment( String principal )
789 userAssignmentsCache.remove( principal );
790 userPermissionsCache.remove( principal );
793 private void invalidateAllCachedUserAssignments()
795 userAssignmentsCache.clear();
796 userPermissionsCache.clear();
799 public Cache getOperationsCache()
801 return operationsCache;
804 public void setOperationsCache( Cache operationsCache )
806 this.operationsCache = operationsCache;
809 public Cache getPermissionsCache()
811 return permissionsCache;
814 public void setPermissionsCache( Cache permissionsCache )
816 this.permissionsCache = permissionsCache;
819 public Cache getResourcesCache()
821 return resourcesCache;
824 public void setResourcesCache( Cache resourcesCache )
826 this.resourcesCache = resourcesCache;
829 public Cache getRolesCache()
834 public void setRolesCache( Cache rolesCache )
836 this.rolesCache = rolesCache;
839 public Cache getUserAssignmentsCache()
841 return userAssignmentsCache;
844 public void setUserAssignmentsCache( Cache userAssignmentsCache )
846 this.userAssignmentsCache = userAssignmentsCache;
849 public Cache getUserPermissionsCache()
851 return userPermissionsCache;
854 public void setUserPermissionsCache( Cache userPermissionsCache )
856 this.userPermissionsCache = userPermissionsCache;
859 public Cache getEffectiveRoleSetCache()
861 return effectiveRoleSetCache;
864 public void setEffectiveRoleSetCache( Cache effectiveRoleSetCache )
866 this.effectiveRoleSetCache = effectiveRoleSetCache;
869 public RBACManager getRbacImpl()
874 public void setRbacImpl( RBACManager rbacImpl )
876 this.rbacImpl = rbacImpl;