1 package org.apache.archiva.web.security;
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
21 import org.apache.archiva.admin.model.RepositoryAdminException;
22 import org.apache.archiva.admin.model.runtime.RedbackRuntimeConfigurationAdmin;
23 import org.apache.archiva.components.cache.Cache;
24 import org.apache.archiva.redback.rbac.AbstractRBACManager;
25 import org.apache.archiva.redback.rbac.Operation;
26 import org.apache.archiva.redback.rbac.Permission;
27 import org.apache.archiva.redback.rbac.RBACManager;
28 import org.apache.archiva.redback.rbac.RbacManagerException;
29 import org.apache.archiva.redback.rbac.RbacObjectInvalidException;
30 import org.apache.archiva.redback.rbac.RbacObjectNotFoundException;
31 import org.apache.archiva.redback.rbac.Resource;
32 import org.apache.archiva.redback.rbac.Role;
33 import org.apache.archiva.redback.rbac.UserAssignment;
34 import org.apache.commons.lang3.StringUtils;
35 import org.springframework.context.ApplicationContext;
36 import org.springframework.stereotype.Service;
38 import javax.inject.Inject;
39 import javax.inject.Named;
40 import java.util.ArrayList;
41 import java.util.Collection;
42 import java.util.HashMap;
43 import java.util.LinkedHashMap;
44 import java.util.List;
49 * @author Olivier Lamy
52 @Service( "rbacManager#archiva" )
53 public class ArchivaRbacManager
54 extends AbstractRBACManager
55 implements RBACManager
58 private Map<String, RBACManager> rbacManagersPerId;
61 private ApplicationContext applicationContext;
64 private RedbackRuntimeConfigurationAdmin redbackRuntimeConfigurationAdmin;
67 @Named( value = "cache#operations" )
68 private Cache<String, Operation> operationsCache;
71 @Named( value = "cache#permissions" )
72 private Cache<String, Permission> permissionsCache;
75 @Named( value = "cache#resources" )
76 private Cache<String, Resource> resourcesCache;
79 @Named( value = "cache#roles" )
80 private Cache<String, Role> rolesCache;
83 @Named( value = "cache#rolesById" )
84 private Cache<String, Role> rolesByIdCache;
87 @Named( value = "cache#userAssignments" )
88 private Cache<String, UserAssignment> userAssignmentsCache;
91 @Named( value = "cache#userPermissions" )
92 private Cache<String, Map<String, List<Permission>>> userPermissionsCache;
95 @Named( value = "cache#effectiveRoleSet" )
96 private Cache<String, Set<Role>> effectiveRoleSetCache;
99 public void initialize()
103 List<String> rbacManagerIds =
104 redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration().getRbacManagerImpls();
108 if ( rbacManagerIds.isEmpty() )
110 rbacManagerIds.add( RedbackRuntimeConfigurationAdmin.DEFAULT_RBAC_MANAGER_IMPL );
113 log.info( "use rbacManagerIds: '{}'", rbacManagerIds );
115 this.rbacManagersPerId = new LinkedHashMap<>( rbacManagerIds.size() );
117 for ( String id : rbacManagerIds )
119 if ( StringUtils.equalsIgnoreCase( "jdo", id ))
121 id = RedbackRuntimeConfigurationAdmin.DEFAULT_RBAC_MANAGER_IMPL;
123 RBACManager rbacManager = applicationContext.getBean( "rbacManager#" + id, RBACManager.class );
124 rbacManagersPerId.put( id, rbacManager );
128 catch ( RepositoryAdminException e )
131 log.error( e.getMessage(), e );
132 throw new RuntimeException( e.getMessage(), e );
136 private void clearCaches() {
137 resourcesCache.clear();
138 operationsCache.clear();
139 permissionsCache.clear();
141 rolesByIdCache.clear();
142 userAssignmentsCache.clear();
143 userPermissionsCache.clear();
144 effectiveRoleSetCache.clear();
147 protected RBACManager getRbacManagerForWrite()
149 for ( RBACManager rbacManager : this.rbacManagersPerId.values() )
151 if ( !rbacManager.isReadOnly() )
153 log.debug("Writable Rbac manager {}", rbacManager.getDescriptionKey());
157 return this.rbacManagersPerId.isEmpty() ? applicationContext.getBean(
158 "rbacManager#" + RedbackRuntimeConfigurationAdmin.DEFAULT_RBAC_MANAGER_IMPL, RBACManager.class ) //
159 : this.rbacManagersPerId.values().iterator().next();
163 public Role createRole( String name )
165 return getRbacManagerForWrite().createRole( name );
169 public Role createRole( String id, String name )
171 return getRbacManagerForWrite( ).createRole( id, name );
175 public Role saveRole( Role role )
176 throws RbacObjectInvalidException, RbacManagerException
178 Exception lastException = null;
179 boolean allFailed = true;
180 for ( RBACManager rbacManager : rbacManagersPerId.values() )
184 if ( !rbacManager.isReadOnly() )
186 role = rbacManager.saveRole( role );
190 catch ( Exception e )
195 if ( lastException != null && allFailed )
197 throw new RbacManagerException( lastException.getMessage(), lastException );
203 public void saveRoles( Collection<Role> roles )
204 throws RbacObjectInvalidException, RbacManagerException
206 Exception lastException = null;
207 boolean allFailed = true;
208 for ( RBACManager rbacManager : rbacManagersPerId.values() )
212 if ( !rbacManager.isReadOnly() )
214 rbacManager.saveRoles( roles );
218 catch ( Exception e )
223 if ( lastException != null && allFailed )
225 throw new RbacManagerException( lastException.getMessage(), lastException );
230 public Role getRole( String roleName )
231 throws RbacObjectNotFoundException, RbacManagerException
234 Role el = rolesCache.get( roleName );
240 Exception lastException = null;
241 for ( RBACManager rbacManager : rbacManagersPerId.values() )
245 Role role = rbacManager.getRole( roleName );
248 rolesCache.put( role.getName(), role );
249 rolesByIdCache.put( role.getId( ), role );
253 catch ( Exception e )
258 log.debug( "cannot find role for name: ‘{}", roleName );
259 if ( lastException != null )
261 throw new RbacManagerException( lastException.getMessage(), lastException );
263 throw new RbacObjectNotFoundException( "Role not found " + roleName );
267 public Role getRoleById( String id ) throws RbacObjectNotFoundException, RbacManagerException
269 Role el = rolesByIdCache.get( id );
275 Exception lastException = null;
276 for ( RBACManager rbacManager : rbacManagersPerId.values() )
280 Role role = rbacManager.getRoleById( id );
283 rolesCache.put( role.getName(), role );
284 rolesByIdCache.put( role.getId( ), role );
288 catch ( Exception e )
293 log.debug( "cannot find role for id: ‘{}", id );
294 if ( lastException != null )
296 throw new RbacManagerException( lastException.getMessage(), lastException );
298 throw new RbacObjectNotFoundException( "Role not found " + id );
302 public List<Role> getAllRoles()
303 throws RbacManagerException
305 Map<String, Role> allRoles = new HashMap<>();
306 boolean allFailed = true;
307 Exception lastException = null;
308 for ( RBACManager rbacManager : rbacManagersPerId.values() )
312 List<? extends Role> roles = rbacManager.getAllRoles();
313 for ( Role role : roles )
315 allRoles.put( role.getName(), role );
319 catch ( Exception e )
325 if ( lastException != null && allFailed )
327 throw new RbacManagerException( lastException.getMessage(), lastException );
330 return new ArrayList<>( allRoles.values() );
334 public void removeRole( Role role )
335 throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
337 boolean allFailed = true;
338 Exception lastException = null;
339 for ( RBACManager rbacManager : rbacManagersPerId.values() )
343 rbacManager.removeRole( role );
344 rolesCache.remove( role.getName() );
345 rolesByIdCache.remove( role.getId( ) );
348 catch ( Exception e )
354 if ( lastException != null && allFailed )
356 throw new RbacManagerException( lastException.getMessage(), lastException );
361 public Permission createPermission( String name )
362 throws RbacManagerException
364 return getRbacManagerForWrite().createPermission( name );
368 public Permission createPermission( String name, String operationName, String resourceIdentifier )
369 throws RbacManagerException
371 return getRbacManagerForWrite().createPermission( name, operationName, resourceIdentifier );
375 public Permission savePermission( Permission permission )
376 throws RbacObjectInvalidException, RbacManagerException
378 boolean allFailed = true;
379 Exception lastException = null;
380 for ( RBACManager rbacManager : rbacManagersPerId.values() )
384 if ( rbacManager.isReadOnly() )
386 permission = rbacManager.savePermission( permission );
390 catch ( Exception e )
396 if ( lastException != null && allFailed )
398 throw new RbacManagerException( lastException.getMessage(), lastException );
405 public Permission getPermission( String permissionName )
406 throws RbacObjectNotFoundException, RbacManagerException
409 Permission el = permissionsCache.get( permissionName );
415 Exception lastException = null;
416 for ( RBACManager rbacManager : rbacManagersPerId.values() )
420 Permission p = rbacManager.getPermission( permissionName );
423 permissionsCache.put( permissionName, p );
427 catch ( Exception e )
433 if ( lastException != null )
435 throw new RbacManagerException( lastException.getMessage(), lastException );
441 public List<Permission> getAllPermissions()
442 throws RbacManagerException
444 Map<String, Permission> allPermissions = new HashMap<>();
445 boolean allFailed = true;
446 Exception lastException = null;
447 for ( RBACManager rbacManager : rbacManagersPerId.values() )
451 List<? extends Permission> permissions = rbacManager.getAllPermissions();
452 for ( Permission p : permissions )
454 allPermissions.put( p.getName(), p );
458 catch ( Exception e )
464 if ( lastException != null && allFailed )
466 throw new RbacManagerException( lastException.getMessage(), lastException );
468 return new ArrayList<>( allPermissions.values() );
472 public void removePermission( Permission permission )
473 throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
475 boolean allFailed = true;
476 Exception lastException = null;
477 for ( RBACManager rbacManager : rbacManagersPerId.values() )
481 rbacManager.removePermission( permission );
482 permissionsCache.remove( permission.getName() );
485 catch ( Exception e )
491 if ( lastException != null && allFailed )
493 throw new RbacManagerException( lastException.getMessage(), lastException );
498 public Operation createOperation( String name )
499 throws RbacManagerException
501 return getRbacManagerForWrite().createOperation( name );
505 public Operation saveOperation( Operation operation )
506 throws RbacObjectInvalidException, RbacManagerException
508 boolean allFailed = true;
509 Exception lastException = null;
510 for ( RBACManager rbacManager : rbacManagersPerId.values() )
514 if ( !rbacManager.isReadOnly() )
516 operation = rbacManager.saveOperation( operation );
520 catch ( Exception e )
526 if ( lastException != null && allFailed )
528 throw new RbacManagerException( lastException.getMessage(), lastException );
534 public Operation getOperation( String operationName )
535 throws RbacObjectNotFoundException, RbacManagerException
538 Operation el = operationsCache.get( operationName );
544 Exception lastException = null;
545 for ( RBACManager rbacManager : rbacManagersPerId.values() )
549 Operation o = rbacManager.getOperation( operationName );
552 operationsCache.put( operationName, o );
556 catch ( Exception e )
562 if ( lastException != null )
564 throw new RbacManagerException( lastException.getMessage(), lastException );
570 public List<Operation> getAllOperations()
571 throws RbacManagerException
573 Map<String, Operation> allOperations = new HashMap<>();
574 boolean allFailed = true;
575 Exception lastException = null;
576 for ( RBACManager rbacManager : rbacManagersPerId.values() )
580 List<? extends Operation> operations = rbacManager.getAllOperations();
581 for ( Operation o : operations )
583 allOperations.put( o.getName(), o );
587 catch ( Exception e )
593 if ( lastException != null && allFailed )
595 throw new RbacManagerException( lastException.getMessage(), lastException );
597 return new ArrayList<>( allOperations.values() );
601 public void removeOperation( Operation operation )
602 throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
604 boolean allFailed = true;
605 Exception lastException = null;
606 for ( RBACManager rbacManager : rbacManagersPerId.values() )
610 rbacManager.removeOperation( operation );
611 operationsCache.remove( operation.getName() );
614 catch ( Exception e )
620 if ( lastException != null && allFailed )
622 throw new RbacManagerException( lastException.getMessage(), lastException );
627 public Resource createResource( String identifier )
628 throws RbacManagerException
630 return getRbacManagerForWrite().createResource( identifier );
634 public Resource saveResource( Resource resource )
635 throws RbacObjectInvalidException, RbacManagerException
637 boolean allFailed = true;
638 Exception lastException = null;
639 for ( RBACManager rbacManager : rbacManagersPerId.values() )
643 if ( !rbacManager.isReadOnly() )
645 resource = rbacManager.saveResource( resource );
649 catch ( Exception e )
655 if ( lastException != null && allFailed )
657 throw new RbacManagerException( lastException.getMessage(), lastException );
663 public Resource getResource( String resourceIdentifier )
664 throws RbacObjectNotFoundException, RbacManagerException
667 Resource el = resourcesCache.get( resourceIdentifier );
673 Exception lastException = null;
674 for ( RBACManager rbacManager : rbacManagersPerId.values() )
678 Resource r = rbacManager.getResource( resourceIdentifier );
681 resourcesCache.put( resourceIdentifier, r );
685 catch ( Exception e )
691 if ( lastException != null )
693 throw new RbacManagerException( lastException.getMessage(), lastException );
699 public List<Resource> getAllResources()
700 throws RbacManagerException
702 Map<String, Resource> allResources = new HashMap<>();
703 boolean allFailed = true;
704 Exception lastException = null;
705 for ( RBACManager rbacManager : rbacManagersPerId.values() )
709 List<? extends Resource> resources = rbacManager.getAllResources();
710 for ( Resource r : resources )
712 allResources.put( r.getIdentifier(), r );
716 catch ( Exception e )
722 if ( lastException != null && allFailed )
724 throw new RbacManagerException( lastException.getMessage(), lastException );
726 return new ArrayList<>( allResources.values() );
730 public void removeResource( Resource resource )
731 throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
733 boolean allFailed = true;
734 Exception lastException = null;
735 for ( RBACManager rbacManager : rbacManagersPerId.values() )
739 rbacManager.removeResource( resource );
740 resourcesCache.remove( resource.getIdentifier() );
743 catch ( Exception e )
749 if ( lastException != null && allFailed )
751 throw new RbacManagerException( lastException.getMessage(), lastException );
756 public UserAssignment createUserAssignment( String principal )
757 throws RbacManagerException
759 return getRbacManagerForWrite().createUserAssignment( principal );
763 public UserAssignment saveUserAssignment( UserAssignment userAssignment )
764 throws RbacObjectInvalidException, RbacManagerException
766 boolean allFailed = true;
767 Exception lastException = null;
768 for ( RBACManager rbacManager : rbacManagersPerId.values() )
772 if ( !rbacManager.isReadOnly() )
774 userAssignment = rbacManager.saveUserAssignment( userAssignment );
778 catch ( Exception e )
784 if ( lastException != null && allFailed )
786 throw new RbacManagerException( lastException.getMessage(), lastException );
788 return userAssignment;
792 public UserAssignment getUserAssignment( String principal )
793 throws RbacObjectNotFoundException, RbacManagerException
795 UserAssignment el = userAssignmentsCache.get( principal );
800 UserAssignment ua = null;
801 Exception lastException = null;
802 for ( RBACManager rbacManager : rbacManagersPerId.values() )
808 ua = rbacManager.getUserAssignment( principal );
812 UserAssignment userAssignment = rbacManager.getUserAssignment( principal );
813 if ( userAssignment != null )
815 for ( String roleName : userAssignment.getRoleNames() )
817 ua.addRoleName( roleName );
822 catch ( Exception e )
830 userAssignmentsCache.put( principal, ua );
834 if ( lastException != null )
836 throw new RbacManagerException( lastException.getMessage(), lastException );
842 public boolean userAssignmentExists( String principal )
845 for ( RBACManager rbacManager : rbacManagersPerId.values() )
849 boolean exists = rbacManager.userAssignmentExists( principal );
855 catch ( Exception e )
865 public boolean userAssignmentExists( UserAssignment assignment )
867 for ( RBACManager rbacManager : rbacManagersPerId.values() )
871 boolean exists = rbacManager.userAssignmentExists( assignment );
877 catch ( Exception e )
887 public List<UserAssignment> getAllUserAssignments()
888 throws RbacManagerException
890 Map<String, UserAssignment> allUserAssignments = new HashMap<>();
891 boolean allFailed = true;
892 Exception lastException = null;
893 for ( RBACManager rbacManager : rbacManagersPerId.values() )
897 List<? extends UserAssignment> userAssignments = rbacManager.getAllUserAssignments();
898 for ( UserAssignment ua : userAssignments )
900 UserAssignment userAssignment = allUserAssignments.get( ua.getPrincipal() );
901 if ( userAssignment != null )
903 for ( String roleName : ua.getRoleNames() )
905 userAssignment.addRoleName( roleName );
908 allUserAssignments.put( ua.getPrincipal(), ua );
912 catch ( Exception e )
918 if ( lastException != null && allFailed )
920 throw new RbacManagerException( lastException.getMessage(), lastException );
922 return new ArrayList<>( allUserAssignments.values() );
926 public List<UserAssignment> getUserAssignmentsForRoles( Collection<String> roleNames )
927 throws RbacManagerException
929 List<UserAssignment> allUserAssignments = new ArrayList<>();
930 boolean allFailed = true;
931 Exception lastException = null;
932 for ( RBACManager rbacManager : rbacManagersPerId.values() )
936 List<? extends UserAssignment> userAssignments = rbacManager.getUserAssignmentsForRoles( roleNames );
938 allUserAssignments.addAll( userAssignments );
942 catch ( Exception e )
948 if ( lastException != null && allFailed )
950 throw new RbacManagerException( lastException.getMessage(), lastException );
952 return allUserAssignments;
956 public void removeUserAssignment( UserAssignment userAssignment )
957 throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
959 boolean allFailed = true;
960 Exception lastException = null;
961 for ( RBACManager rbacManager : rbacManagersPerId.values() )
965 rbacManager.removeUserAssignment( userAssignment );
966 userAssignmentsCache.remove( userAssignment.getPrincipal() );
969 catch ( Exception e )
975 if ( lastException != null && allFailed )
977 throw new RbacManagerException( lastException.getMessage(), lastException );
982 public boolean roleExists( String name )
983 throws RbacManagerException
985 Role r = rolesCache.get( name );
991 boolean allFailed = true;
992 Exception lastException = null;
993 for ( RBACManager rbacManager : rbacManagersPerId.values() )
997 boolean exists = rbacManager.roleExists( name );
1003 catch ( Exception e )
1009 if ( lastException != null && allFailed )
1011 throw new RbacManagerException( lastException.getMessage(), lastException );
1017 public boolean roleExists( Role role )
1018 throws RbacManagerException
1020 return roleExists( role.getName() );
1024 public void eraseDatabase()
1026 log.warn( "eraseDatabase not implemented" );
1030 public boolean isFinalImplementation()
1036 public String getDescriptionKey()
1038 return "archiva.redback.rbacmanager.archiva";
1042 public boolean isReadOnly()