1 package org.apache.archiva.web.security;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 import org.apache.archiva.admin.model.RepositoryAdminException;
22 import org.apache.archiva.admin.model.runtime.RedbackRuntimeConfigurationAdmin;
23 import org.apache.archiva.redback.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.springframework.context.ApplicationContext;
35 import org.springframework.stereotype.Service;
36
37 import javax.inject.Inject;
38 import javax.inject.Named;
39 import java.util.ArrayList;
40 import java.util.Collection;
41 import java.util.HashMap;
42 import java.util.LinkedHashMap;
43 import java.util.List;
44 import java.util.Map;
45 import java.util.Set;
46
47
48
49
50
51 @Service( "rbacManager#archiva" )
52 public class ArchivaRbacManager
53 extends AbstractRBACManager
54 implements RBACManager
55 {
56
57 private Map<String, RBACManager> rbacManagersPerId;
58
59 @Inject
60 private ApplicationContext applicationContext;
61
62 @Inject
63 private RedbackRuntimeConfigurationAdmin redbackRuntimeConfigurationAdmin;
64
65 @Inject
66 @Named( value = "cache#operations" )
67 private Cache<String, Operation> operationsCache;
68
69 @Inject
70 @Named( value = "cache#permissions" )
71 private Cache<String, Permission> permissionsCache;
72
73 @Inject
74 @Named( value = "cache#resources" )
75 private Cache<String, Resource> resourcesCache;
76
77 @Inject
78 @Named( value = "cache#roles" )
79 private Cache<String, Role> rolesCache;
80
81 @Inject
82 @Named( value = "cache#userAssignments" )
83 private Cache<String, UserAssignment> userAssignmentsCache;
84
85 @Inject
86 @Named( value = "cache#userPermissions" )
87 private Cache<String, Map<String, List<Permission>>> userPermissionsCache;
88
89 @Inject
90 @Named( value = "cache#effectiveRoleSet" )
91 private Cache<String, Set<Role>> effectiveRoleSetCache;
92
93 @Override
94 public void initialize()
95 {
96 try
97 {
98 List<String> rbacManagerIds =
99 redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration().getRbacManagerImpls();
100
101 log.info( "use rbacManagerIds: '{}'", rbacManagerIds );
102
103 this.rbacManagersPerId = new LinkedHashMap<String, RBACManager>( rbacManagerIds.size() );
104
105 for ( String id : rbacManagerIds )
106 {
107 RBACManager rbacManager = applicationContext.getBean( "rbacManager#" + id, RBACManager.class );
108
109 rbacManagersPerId.put( id, rbacManager );
110 }
111 }
112 catch ( RepositoryAdminException e )
113 {
114
115 log.error( e.getMessage(), e );
116 throw new RuntimeException( e.getMessage(), e );
117 }
118 }
119
120 protected RBACManager getRbacManagerForWrite()
121 {
122 for ( RBACManager rbacManager : this.rbacManagersPerId.values() )
123 {
124 if ( !rbacManager.isReadOnly() )
125 {
126 return rbacManager;
127 }
128 }
129 return this.rbacManagersPerId.values().iterator().next();
130 }
131
132 public Role createRole( String name )
133 {
134 return getRbacManagerForWrite().createRole( name );
135 }
136
137 public Role saveRole( Role role )
138 throws RbacObjectInvalidException, RbacManagerException
139 {
140 Exception lastException = null;
141 boolean allFailed = true;
142 for ( RBACManager rbacManager : rbacManagersPerId.values() )
143 {
144 try
145 {
146 if ( !rbacManager.isReadOnly() )
147 {
148 role = rbacManager.saveRole( role );
149 allFailed = false;
150 }
151 }
152 catch ( Exception e )
153 {
154 lastException = e;
155 }
156 }
157 if ( lastException != null && allFailed )
158 {
159 throw new RbacManagerException( lastException.getMessage(), lastException );
160 }
161 return role;
162 }
163
164 public void saveRoles( Collection<Role> roles )
165 throws RbacObjectInvalidException, RbacManagerException
166 {
167 Exception lastException = null;
168 boolean allFailed = true;
169 for ( RBACManager rbacManager : rbacManagersPerId.values() )
170 {
171 try
172 {
173 if ( !rbacManager.isReadOnly() )
174 {
175 rbacManager.saveRoles( roles );
176 allFailed = false;
177 }
178 }
179 catch ( Exception e )
180 {
181 lastException = e;
182 }
183 }
184 if ( lastException != null && allFailed )
185 {
186 throw new RbacManagerException( lastException.getMessage(), lastException );
187 }
188 }
189
190 public Role getRole( String roleName )
191 throws RbacObjectNotFoundException, RbacManagerException
192 {
193
194 Role el = rolesCache.get( roleName );
195 if ( el != null )
196 {
197 return el;
198 }
199
200 Exception lastException = null;
201 for ( RBACManager rbacManager : rbacManagersPerId.values() )
202 {
203 try
204 {
205 Role role = rbacManager.getRole( roleName );
206 if ( role != null )
207 {
208 rolesCache.put( role.getName(), role );
209 return role;
210 }
211 }
212 catch ( Exception e )
213 {
214 lastException = e;
215 }
216 }
217 log.debug( "cannot find role for name: ‘{}", roleName );
218 if ( lastException != null )
219 {
220 throw new RbacManagerException( lastException.getMessage(), lastException );
221 }
222 return null;
223 }
224
225 public List<Role> getAllRoles()
226 throws RbacManagerException
227 {
228 Map<String, Role> allRoles = new HashMap<String, Role>();
229 boolean allFailed = true;
230 Exception lastException = null;
231 for ( RBACManager rbacManager : rbacManagersPerId.values() )
232 {
233 try
234 {
235 List<Role> roles = rbacManager.getAllRoles();
236 for ( Role role : roles )
237 {
238 allRoles.put( role.getName(), role );
239 }
240 allFailed = false;
241 }
242 catch ( Exception e )
243 {
244 lastException = e;
245 }
246 }
247
248 if ( lastException != null && allFailed )
249 {
250 throw new RbacManagerException( lastException.getMessage(), lastException );
251 }
252
253 return new ArrayList<Role>( allRoles.values() );
254 }
255
256 public void removeRole( Role role )
257 throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
258 {
259 boolean allFailed = true;
260 Exception lastException = null;
261 for ( RBACManager rbacManager : rbacManagersPerId.values() )
262 {
263 try
264 {
265 rbacManager.removeRole( role );
266 rolesCache.remove( role.getName() );
267 allFailed = false;
268 }
269 catch ( Exception e )
270 {
271 lastException = e;
272 }
273 }
274
275 if ( lastException != null && allFailed )
276 {
277 throw new RbacManagerException( lastException.getMessage(), lastException );
278 }
279 }
280
281 public Permission createPermission( String name )
282 throws RbacManagerException
283 {
284 return getRbacManagerForWrite().createPermission( name );
285 }
286
287 public Permission createPermission( String name, String operationName, String resourceIdentifier )
288 throws RbacManagerException
289 {
290 return getRbacManagerForWrite().createPermission( name, operationName, resourceIdentifier );
291 }
292
293 public Permission savePermission( Permission permission )
294 throws RbacObjectInvalidException, RbacManagerException
295 {
296 boolean allFailed = true;
297 Exception lastException = null;
298 for ( RBACManager rbacManager : rbacManagersPerId.values() )
299 {
300 try
301 {
302 if ( rbacManager.isReadOnly() )
303 {
304 permission = rbacManager.savePermission( permission );
305 allFailed = false;
306 }
307 }
308 catch ( Exception e )
309 {
310 lastException = e;
311 }
312 }
313
314 if ( lastException != null && allFailed )
315 {
316 throw new RbacManagerException( lastException.getMessage(), lastException );
317 }
318
319 return permission;
320 }
321
322 public Permission getPermission( String permissionName )
323 throws RbacObjectNotFoundException, RbacManagerException
324 {
325
326 Permission el = permissionsCache.get( permissionName );
327 if ( el != null )
328 {
329 return el;
330 }
331
332 Exception lastException = null;
333 for ( RBACManager rbacManager : rbacManagersPerId.values() )
334 {
335 try
336 {
337 Permission p = rbacManager.getPermission( permissionName );
338 if ( p != null )
339 {
340 permissionsCache.put( permissionName, p );
341 return p;
342 }
343 }
344 catch ( Exception e )
345 {
346 lastException = e;
347 }
348 }
349
350 if ( lastException != null )
351 {
352 throw new RbacManagerException( lastException.getMessage(), lastException );
353 }
354 return null;
355 }
356
357 public List<Permission> getAllPermissions()
358 throws RbacManagerException
359 {
360 Map<String, Permission> allPermissions = new HashMap<String, Permission>();
361 boolean allFailed = true;
362 Exception lastException = null;
363 for ( RBACManager rbacManager : rbacManagersPerId.values() )
364 {
365 try
366 {
367 List<Permission> permissions = rbacManager.getAllPermissions();
368 for ( Permission p : permissions )
369 {
370 allPermissions.put( p.getName(), p );
371 }
372 allFailed = false;
373 }
374 catch ( Exception e )
375 {
376 lastException = e;
377 }
378 }
379
380 if ( lastException != null && allFailed )
381 {
382 throw new RbacManagerException( lastException.getMessage(), lastException );
383 }
384 return new ArrayList<Permission>( allPermissions.values() );
385 }
386
387 public void removePermission( Permission permission )
388 throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
389 {
390 boolean allFailed = true;
391 Exception lastException = null;
392 for ( RBACManager rbacManager : rbacManagersPerId.values() )
393 {
394 try
395 {
396 rbacManager.removePermission( permission );
397 permissionsCache.remove( permission.getName() );
398 allFailed = false;
399 }
400 catch ( Exception e )
401 {
402 lastException = e;
403 }
404 }
405
406 if ( lastException != null && allFailed )
407 {
408 throw new RbacManagerException( lastException.getMessage(), lastException );
409 }
410 }
411
412 public Operation createOperation( String name )
413 throws RbacManagerException
414 {
415 return getRbacManagerForWrite().createOperation( name );
416 }
417
418 public Operation saveOperation( Operation operation )
419 throws RbacObjectInvalidException, RbacManagerException
420 {
421 boolean allFailed = true;
422 Exception lastException = null;
423 for ( RBACManager rbacManager : rbacManagersPerId.values() )
424 {
425 try
426 {
427 if ( !rbacManager.isReadOnly() )
428 {
429 operation = rbacManager.saveOperation( operation );
430 allFailed = false;
431 }
432 }
433 catch ( Exception e )
434 {
435 lastException = e;
436 }
437 }
438
439 if ( lastException != null && allFailed )
440 {
441 throw new RbacManagerException( lastException.getMessage(), lastException );
442 }
443 return operation;
444 }
445
446 public Operation getOperation( String operationName )
447 throws RbacObjectNotFoundException, RbacManagerException
448 {
449
450 Operation el = operationsCache.get( operationName );
451 if ( el != null )
452 {
453 return el;
454 }
455
456 Exception lastException = null;
457 for ( RBACManager rbacManager : rbacManagersPerId.values() )
458 {
459 try
460 {
461 Operation o = rbacManager.getOperation( operationName );
462 if ( o != null )
463 {
464 operationsCache.put( operationName, o );
465 return o;
466 }
467 }
468 catch ( Exception e )
469 {
470 lastException = e;
471 }
472 }
473
474 if ( lastException != null )
475 {
476 throw new RbacManagerException( lastException.getMessage(), lastException );
477 }
478 return null;
479 }
480
481 public List<Operation> getAllOperations()
482 throws RbacManagerException
483 {
484 Map<String, Operation> allOperations = new HashMap<String, Operation>();
485 boolean allFailed = true;
486 Exception lastException = null;
487 for ( RBACManager rbacManager : rbacManagersPerId.values() )
488 {
489 try
490 {
491 List<Operation> operations = rbacManager.getAllOperations();
492 for ( Operation o : operations )
493 {
494 allOperations.put( o.getName(), o );
495 }
496 allFailed = false;
497 }
498 catch ( Exception e )
499 {
500 lastException = e;
501 }
502 }
503
504 if ( lastException != null && allFailed )
505 {
506 throw new RbacManagerException( lastException.getMessage(), lastException );
507 }
508 return new ArrayList<Operation>( allOperations.values() );
509 }
510
511 public void removeOperation( Operation operation )
512 throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
513 {
514 boolean allFailed = true;
515 Exception lastException = null;
516 for ( RBACManager rbacManager : rbacManagersPerId.values() )
517 {
518 try
519 {
520 rbacManager.removeOperation( operation );
521 operationsCache.remove( operation.getName() );
522 allFailed = false;
523 }
524 catch ( Exception e )
525 {
526 lastException = e;
527 }
528 }
529
530 if ( lastException != null && allFailed )
531 {
532 throw new RbacManagerException( lastException.getMessage(), lastException );
533 }
534 }
535
536 public Resource createResource( String identifier )
537 throws RbacManagerException
538 {
539 return getRbacManagerForWrite().createResource( identifier );
540 }
541
542 public Resource saveResource( Resource resource )
543 throws RbacObjectInvalidException, RbacManagerException
544 {
545 boolean allFailed = true;
546 Exception lastException = null;
547 for ( RBACManager rbacManager : rbacManagersPerId.values() )
548 {
549 try
550 {
551 if ( !rbacManager.isReadOnly() )
552 {
553 resource = rbacManager.saveResource( resource );
554 allFailed = false;
555 }
556 }
557 catch ( Exception e )
558 {
559 lastException = e;
560 }
561 }
562
563 if ( lastException != null && allFailed )
564 {
565 throw new RbacManagerException( lastException.getMessage(), lastException );
566 }
567 return resource;
568 }
569
570 public Resource getResource( String resourceIdentifier )
571 throws RbacObjectNotFoundException, RbacManagerException
572 {
573
574 Resource el = resourcesCache.get( resourceIdentifier );
575 if ( el != null )
576 {
577 return el;
578 }
579
580 Exception lastException = null;
581 for ( RBACManager rbacManager : rbacManagersPerId.values() )
582 {
583 try
584 {
585 Resource r = rbacManager.getResource( resourceIdentifier );
586 if ( r != null )
587 {
588 resourcesCache.put( resourceIdentifier, r );
589 return r;
590 }
591 }
592 catch ( Exception e )
593 {
594 lastException = e;
595 }
596 }
597
598 if ( lastException != null )
599 {
600 throw new RbacManagerException( lastException.getMessage(), lastException );
601 }
602 return null;
603 }
604
605 public List<Resource> getAllResources()
606 throws RbacManagerException
607 {
608 Map<String, Resource> allResources = new HashMap<String, Resource>();
609 boolean allFailed = true;
610 Exception lastException = null;
611 for ( RBACManager rbacManager : rbacManagersPerId.values() )
612 {
613 try
614 {
615 List<Resource> resources = rbacManager.getAllResources();
616 for ( Resource r : resources )
617 {
618 allResources.put( r.getIdentifier(), r );
619 }
620 allFailed = false;
621 }
622 catch ( Exception e )
623 {
624 lastException = e;
625 }
626 }
627
628 if ( lastException != null && allFailed )
629 {
630 throw new RbacManagerException( lastException.getMessage(), lastException );
631 }
632 return new ArrayList<Resource>( allResources.values() );
633 }
634
635 public void removeResource( Resource resource )
636 throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
637 {
638 boolean allFailed = true;
639 Exception lastException = null;
640 for ( RBACManager rbacManager : rbacManagersPerId.values() )
641 {
642 try
643 {
644 rbacManager.removeResource( resource );
645 resourcesCache.remove( resource.getIdentifier() );
646 allFailed = false;
647 }
648 catch ( Exception e )
649 {
650 lastException = e;
651 }
652 }
653
654 if ( lastException != null && allFailed )
655 {
656 throw new RbacManagerException( lastException.getMessage(), lastException );
657 }
658 }
659
660 public UserAssignment createUserAssignment( String principal )
661 throws RbacManagerException
662 {
663 return getRbacManagerForWrite().createUserAssignment( principal );
664 }
665
666 public UserAssignment saveUserAssignment( UserAssignment userAssignment )
667 throws RbacObjectInvalidException, RbacManagerException
668 {
669 boolean allFailed = true;
670 Exception lastException = null;
671 for ( RBACManager rbacManager : rbacManagersPerId.values() )
672 {
673 try
674 {
675 if ( !rbacManager.isReadOnly() )
676 {
677 userAssignment = rbacManager.saveUserAssignment( userAssignment );
678 allFailed = false;
679 }
680 }
681 catch ( Exception e )
682 {
683 lastException = e;
684 }
685 }
686
687 if ( lastException != null && allFailed )
688 {
689 throw new RbacManagerException( lastException.getMessage(), lastException );
690 }
691 return userAssignment;
692 }
693
694 public UserAssignment getUserAssignment( String principal )
695 throws RbacObjectNotFoundException, RbacManagerException
696 {
697 UserAssignment el = userAssignmentsCache.get( principal );
698 if ( el != null )
699 {
700 return el;
701 }
702 UserAssignment ua = null;
703 Exception lastException = null;
704 for ( RBACManager rbacManager : rbacManagersPerId.values() )
705 {
706 try
707 {
708 if ( ua == null )
709 {
710 ua = rbacManager.getUserAssignment( principal );
711 }
712 else
713 {
714 UserAssignment userAssignment = rbacManager.getUserAssignment( principal );
715 if ( userAssignment != null )
716 {
717 for ( String roleName : userAssignment.getRoleNames() )
718 {
719 ua.addRoleName( roleName );
720 }
721 }
722 }
723 }
724 catch ( Exception e )
725 {
726 lastException = e;
727 }
728 }
729
730 if ( ua != null )
731 {
732 userAssignmentsCache.put( principal, ua );
733 return ua;
734 }
735
736 if ( lastException != null )
737 {
738 throw new RbacManagerException( lastException.getMessage(), lastException );
739 }
740 return null;
741 }
742
743 @Override
744 public boolean userAssignmentExists( String principal )
745 {
746
747 for ( RBACManager rbacManager : rbacManagersPerId.values() )
748 {
749 try
750 {
751 boolean exists = rbacManager.userAssignmentExists( principal );
752 if ( exists )
753 {
754 return true;
755 }
756 }
757 catch ( Exception e )
758 {
759
760 }
761 }
762
763 return false;
764 }
765
766 @Override
767 public boolean userAssignmentExists( UserAssignment assignment )
768 {
769 for ( RBACManager rbacManager : rbacManagersPerId.values() )
770 {
771 try
772 {
773 boolean exists = rbacManager.userAssignmentExists( assignment );
774 if ( exists )
775 {
776 return true;
777 }
778 }
779 catch ( Exception e )
780 {
781
782 }
783 }
784
785 return false;
786 }
787
788 public List<UserAssignment> getAllUserAssignments()
789 throws RbacManagerException
790 {
791 Map<String, UserAssignment> allUserAssignments = new HashMap<String, UserAssignment>();
792 boolean allFailed = true;
793 Exception lastException = null;
794 for ( RBACManager rbacManager : rbacManagersPerId.values() )
795 {
796 try
797 {
798 List<UserAssignment> userAssignments = rbacManager.getAllUserAssignments();
799 for ( UserAssignment ua : userAssignments )
800 {
801 UserAssignment userAssignment = allUserAssignments.get( ua.getPrincipal() );
802 if ( userAssignment != null )
803 {
804 for ( String roleName : ua.getRoleNames() )
805 {
806 userAssignment.addRoleName( roleName );
807 }
808 }
809 allUserAssignments.put( ua.getPrincipal(), ua );
810 }
811 allFailed = false;
812 }
813 catch ( Exception e )
814 {
815 lastException = e;
816 }
817 }
818
819 if ( lastException != null && allFailed )
820 {
821 throw new RbacManagerException( lastException.getMessage(), lastException );
822 }
823 return new ArrayList<UserAssignment>( allUserAssignments.values() );
824 }
825
826 public List<UserAssignment> getUserAssignmentsForRoles( Collection<String> roleNames )
827 throws RbacManagerException
828 {
829 List<UserAssignment> allUserAssignments = new ArrayList<UserAssignment>();
830 boolean allFailed = true;
831 Exception lastException = null;
832 for ( RBACManager rbacManager : rbacManagersPerId.values() )
833 {
834 try
835 {
836 List<UserAssignment> userAssignments = rbacManager.getUserAssignmentsForRoles( roleNames );
837
838 allUserAssignments.addAll( userAssignments );
839
840 allFailed = false;
841 }
842 catch ( Exception e )
843 {
844 lastException = e;
845 }
846 }
847
848 if ( lastException != null && allFailed )
849 {
850 throw new RbacManagerException( lastException.getMessage(), lastException );
851 }
852 return allUserAssignments;
853 }
854
855 public void removeUserAssignment( UserAssignment userAssignment )
856 throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
857 {
858 boolean allFailed = true;
859 Exception lastException = null;
860 for ( RBACManager rbacManager : rbacManagersPerId.values() )
861 {
862 try
863 {
864 rbacManager.removeUserAssignment( userAssignment );
865 userAssignmentsCache.remove( userAssignment.getPrincipal() );
866 allFailed = false;
867 }
868 catch ( Exception e )
869 {
870 lastException = e;
871 }
872 }
873
874 if ( lastException != null && allFailed )
875 {
876 throw new RbacManagerException( lastException.getMessage(), lastException );
877 }
878 }
879
880 @Override
881 public boolean roleExists( String name )
882 throws RbacManagerException
883 {
884 Role r = rolesCache.get( name );
885 if ( r != null )
886 {
887 return true;
888 }
889
890 boolean allFailed = true;
891 Exception lastException = null;
892 for ( RBACManager rbacManager : rbacManagersPerId.values() )
893 {
894 try
895 {
896 boolean exists = rbacManager.roleExists( name );
897 if ( exists )
898 {
899 return true;
900 }
901 }
902 catch ( Exception e )
903 {
904 lastException = e;
905 }
906 }
907
908 if ( lastException != null && allFailed )
909 {
910 throw new RbacManagerException( lastException.getMessage(), lastException );
911 }
912 return false;
913 }
914
915 @Override
916 public boolean roleExists( Role role )
917 throws RbacManagerException
918 {
919 return roleExists( role.getName() );
920 }
921
922 public void eraseDatabase()
923 {
924 log.warn( "eraseDatabase not implemented" );
925 }
926
927 @Override
928 public boolean isFinalImplementation()
929 {
930 return false;
931 }
932
933 public String getDescriptionKey()
934 {
935 return "archiva.redback.rbacmanager.archiva";
936 }
937
938 public boolean isReadOnly()
939 {
940 return false;
941 }
942 }