]> source.dussan.org Git - archiva.git/blob
95414b758592641ea5fb2a3b9abafc77ae8932e9
[archiva.git] /
1 package org.apache.archiva.redback.rbac.ldap;
2
3 /*
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
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
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
19  * under the License.
20  */
21
22 import com.google.common.base.Function;
23 import com.google.common.collect.Lists;
24 import org.apache.archiva.redback.common.ldap.MappingException;
25 import org.apache.archiva.redback.common.ldap.connection.LdapConnection;
26 import org.apache.archiva.redback.common.ldap.connection.LdapConnectionFactory;
27 import org.apache.archiva.redback.common.ldap.connection.LdapException;
28 import org.apache.archiva.redback.common.ldap.role.LdapRoleMapper;
29 import org.apache.archiva.redback.components.cache.Cache;
30 import org.apache.archiva.redback.configuration.UserConfiguration;
31 import org.apache.archiva.redback.configuration.UserConfigurationKeys;
32 import org.apache.archiva.redback.rbac.AbstractRBACManager;
33 import org.apache.archiva.redback.rbac.AbstractRole;
34 import org.apache.archiva.redback.rbac.Operation;
35 import org.apache.archiva.redback.rbac.Permission;
36 import org.apache.archiva.redback.rbac.RBACManager;
37 import org.apache.archiva.redback.rbac.RBACManagerListener;
38 import org.apache.archiva.redback.rbac.RBACObjectAssertions;
39 import org.apache.archiva.redback.rbac.RbacManagerException;
40 import org.apache.archiva.redback.rbac.RbacObjectInvalidException;
41 import org.apache.archiva.redback.rbac.RbacObjectNotFoundException;
42 import org.apache.archiva.redback.rbac.RbacPermanentException;
43 import org.apache.archiva.redback.rbac.Resource;
44 import org.apache.archiva.redback.rbac.Role;
45 import org.apache.archiva.redback.rbac.UserAssignment;
46 import org.apache.archiva.redback.users.User;
47 import org.apache.archiva.redback.users.UserManager;
48 import org.apache.archiva.redback.users.UserManagerException;
49 import org.apache.archiva.redback.users.ldap.ctl.LdapController;
50 import org.apache.archiva.redback.users.ldap.ctl.LdapControllerException;
51 import org.apache.commons.lang.StringUtils;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54 import org.springframework.stereotype.Service;
55
56 import javax.annotation.PostConstruct;
57 import javax.inject.Inject;
58 import javax.inject.Named;
59 import java.util.ArrayList;
60 import java.util.Collection;
61 import java.util.Collections;
62 import java.util.List;
63 import java.util.Map;
64 import java.util.Set;
65
66 /**
67  * LdapRbacManager will read datas from ldap for mapping groups to role.
68  * Write operations will delegate to cached implementation.
69  *
70  * @author Olivier Lamy
71  */
72 @Service( "rbacManager#ldap" )
73 public class LdapRbacManager
74     extends AbstractRBACManager
75     implements RBACManager, RBACManagerListener
76 {
77
78     private Logger log = LoggerFactory.getLogger( getClass() );
79
80     @Inject
81     @Named( value = "rbacManager#cached" )
82     private RBACManager rbacImpl;
83
84     @Inject
85     @Named( value = "ldapRoleMapper#default" )
86     private LdapRoleMapper ldapRoleMapper;
87
88     @Inject
89     @Named( value = "userConfiguration#default" )
90     private UserConfiguration userConf;
91
92     @Inject
93     @Named( value = "userManager#ldap" )
94     private UserManager userManager;
95
96     @Inject
97     private LdapConnectionFactory ldapConnectionFactory;
98
99     @Inject
100     private LdapController ldapController;
101
102     private boolean writableLdap = false;
103
104     @PostConstruct
105     public void initialize()
106     {
107         this.writableLdap = userConf.getBoolean( UserConfigurationKeys.LDAP_WRITABLE, this.writableLdap );
108     }
109
110
111     public void addChildRole( Role role, Role childRole )
112         throws RbacObjectInvalidException, RbacManagerException
113     {
114         this.rbacImpl.addChildRole( role, childRole );
115     }
116
117     public void addListener( RBACManagerListener listener )
118     {
119         super.addListener( listener );
120         this.rbacImpl.addListener( listener );
121     }
122
123     public Operation createOperation( String name )
124         throws RbacManagerException
125     {
126         return this.rbacImpl.createOperation( name );
127     }
128
129     public Permission createPermission( String name )
130         throws RbacManagerException
131     {
132         return this.rbacImpl.createPermission( name );
133     }
134
135     public Permission createPermission( String name, String operationName, String resourceIdentifier )
136         throws RbacManagerException
137     {
138         return this.rbacImpl.createPermission( name, operationName, resourceIdentifier );
139     }
140
141     public Resource createResource( String identifier )
142         throws RbacManagerException
143     {
144         return this.rbacImpl.createResource( identifier );
145     }
146
147     public Role createRole( String name )
148     {
149         return this.rbacImpl.createRole( name );
150     }
151
152     public UserAssignment createUserAssignment( String username )
153         throws RbacManagerException
154     {
155         // TODO ldap cannot or isWritable ldap ?
156         return this.rbacImpl.createUserAssignment( username );
157     }
158
159     public void eraseDatabase()
160     {
161         if ( writableLdap )
162         {
163             try
164             {
165                 ldapRoleMapper.removeAllRoles();
166             }
167             catch ( MappingException e )
168             {
169                 log.warn( "skip error removing all roles {}", e.getMessage() );
170             }
171         }
172         this.rbacImpl.eraseDatabase();
173     }
174
175     /**
176      * @see org.apache.archiva.redback.rbac.RBACManager#getAllAssignableRoles()
177      */
178     public List<Role> getAllAssignableRoles()
179         throws RbacManagerException
180     {
181         try
182         {
183             Collection<String> roleNames = ldapRoleMapper.getLdapGroupMappings().values();
184
185             List<Role> roles = new ArrayList<Role>();
186
187             for ( String name : roleNames )
188             {
189                 roles.add( new RoleImpl( name ) );
190             }
191
192             return roles;
193         }
194         catch ( MappingException e )
195         {
196             throw new RbacManagerException( e.getMessage(), e );
197         }
198     }
199
200     public List<Operation> getAllOperations()
201         throws RbacManagerException
202     {
203         return this.rbacImpl.getAllOperations();
204     }
205
206     public List<Permission> getAllPermissions()
207         throws RbacManagerException
208     {
209         return this.rbacImpl.getAllPermissions();
210     }
211
212     public List<Resource> getAllResources()
213         throws RbacManagerException
214     {
215         return this.rbacImpl.getAllResources();
216     }
217
218     public List<Role> getAllRoles()
219         throws RbacManagerException
220     {
221         try
222         {
223             List<String> groups = ldapRoleMapper.getAllGroups();
224             return mapToRoles( groups );
225         }
226         catch ( MappingException e )
227         {
228             throw new RbacManagerException( e.getMessage(), e );
229         }
230         //return this.rbacImpl.getAllRoles();
231     }
232
233     public List<UserAssignment> getAllUserAssignments()
234         throws RbacManagerException
235     {
236         // TODO FROM ldap or from real impl ?
237         //return this.rbacImpl.getAllUserAssignments();
238         LdapConnection ldapConnection = null;
239         try
240         {
241             ldapConnection = ldapConnectionFactory.getConnection();
242             Map<String, Collection<String>> usersWithRoles =
243                 ldapController.findUsersWithRoles( ldapConnection.getDirContext() );
244             List<UserAssignment> userAssignments = new ArrayList<UserAssignment>( usersWithRoles.size() );
245
246             for ( Map.Entry<String, Collection<String>> entry : usersWithRoles.entrySet() )
247             {
248                 UserAssignment userAssignment = new UserAssignmentImpl( entry.getKey(), entry.getValue() );
249                 userAssignments.add( userAssignment );
250             }
251
252             return userAssignments;
253         }
254         catch ( LdapControllerException e )
255         {
256             throw new RbacManagerException( e.getMessage(), e );
257         }
258         catch ( LdapException e )
259         {
260             throw new RbacManagerException( e.getMessage(), e );
261         }
262         finally
263         {
264             if ( ldapConnection != null )
265             {
266                 ldapConnection.close();
267             }
268         }
269     }
270
271     /**
272      * public Map<String, List<Permission>> getAssignedPermissionMap( String username )
273      * throws RbacManagerException
274      * {
275      * return this.rbacImpl.getAssignedPermissionMap( username );
276      * }*
277      */
278
279     /*public Set<Permission> getAssignedPermissions( String username )
280         throws RbacObjectNotFoundException, RbacManagerException
281     {
282         // TODO here !!
283         return this.rbacImpl.getAssignedPermissions( username );
284     }*/
285     private List<Role> mapToRoles( List<String> groups )
286         throws MappingException, RbacManagerException
287     {
288         if ( groups == null || groups.isEmpty() )
289         {
290             return Collections.emptyList();
291         }
292
293         List<Role> roles = new ArrayList<Role>( groups.size() );
294         Map<String, String> mappedGroups = ldapRoleMapper.getLdapGroupMappings();
295         for ( String group : groups )
296         {
297             String roleName = mappedGroups.get( group );
298             if ( roleName != null )
299             {
300                 Role role = getRole( roleName );
301                 if ( role != null )
302                 {
303                     roles.add( role );
304                 }
305             }
306         }
307         return roles;
308
309     }
310
311     public Collection<Role> getAssignedRoles( String username )
312         throws RbacManagerException
313     {
314         try
315         {
316             // TODO here !!
317             List<String> roleNames = ldapRoleMapper.getRoles( username );
318
319             if ( roleNames.isEmpty() )
320             {
321                 return Collections.emptyList();
322             }
323
324             List<Role> roles = new ArrayList<Role>( roleNames.size() );
325
326             for ( String name : roleNames )
327             {
328                 roles.add( this.rbacImpl.getRole( name ) );// new RoleImpl( name ) );
329             }
330
331             return roles;
332         }
333         catch ( MappingException e )
334         {
335             throw new RbacManagerException( e.getMessage(), e );
336         }
337     }
338
339     public Collection<Role> getAssignedRoles( UserAssignment userAssignment )
340         throws RbacManagerException
341     {
342         return getAssignedRoles( userAssignment.getPrincipal() );
343     }
344
345     public Map<String, Role> getChildRoles( Role role )
346         throws RbacManagerException
347     {
348         return this.rbacImpl.getChildRoles( role );
349     }
350
351     public Map<String, Role> getParentRoles( Role role )
352         throws RbacManagerException
353     {
354         return this.rbacImpl.getParentRoles( role );
355     }
356
357     /**
358     public Collection<Role> getEffectivelyAssignedRoles( String username )
359         throws RbacManagerException
360     {
361         // TODO here !!
362         return this.rbacImpl.getEffectivelyAssignedRoles( username );
363     }**/
364
365     /**
366     public Collection<Role> getEffectivelyUnassignedRoles( String username )
367         throws RbacManagerException
368     {
369         // TODO here !!
370         return this.rbacImpl.getEffectivelyUnassignedRoles( username );
371     }**/
372
373     public Set<Role> getEffectiveRoles( Role role )
374         throws RbacManagerException
375     {
376         return this.rbacImpl.getEffectiveRoles( role );
377     }
378
379     public Resource getGlobalResource()
380         throws RbacManagerException
381     {
382         return this.rbacImpl.getGlobalResource();
383     }
384
385     public Operation getOperation( String operationName )
386         throws RbacManagerException
387     {
388         return this.rbacImpl.getOperation( operationName );
389     }
390
391     public Permission getPermission( String permissionName )
392         throws RbacManagerException
393     {
394         return this.rbacImpl.getPermission( permissionName );
395     }
396
397     public Resource getResource( String resourceIdentifier )
398         throws RbacManagerException
399     {
400         return this.rbacImpl.getResource( resourceIdentifier );
401     }
402
403     public Role getRole( String roleName )
404         throws RbacManagerException
405     {
406         //verify it's a ldap group
407         try
408         {
409             if ( !ldapRoleMapper.getAllRoles().contains( roleName ) )
410             {
411                 return null;
412             }
413         }
414         catch ( MappingException e )
415         {
416             throw new RbacManagerException( e.getMessage(), e );
417         }
418         return this.rbacImpl.getRole( roleName );
419     }
420
421     public Map<String, Role> getRoles( Collection<String> roleNames )
422         throws RbacManagerException
423     {
424         return this.rbacImpl.getRoles( roleNames );
425     }
426
427     public Collection<Role> getUnassignedRoles( String username )
428         throws RbacManagerException
429     {
430         try
431         {
432             List<String> allRoles = ldapRoleMapper.getAllRoles();
433             final List<String> userRoles = ldapRoleMapper.getRoles( username );
434
435             List<Role> unassignedRoles = new ArrayList<Role>();
436
437             for ( String roleName : allRoles )
438             {
439                 if ( !userRoles.contains( roleName ) )
440                 {
441                     unassignedRoles.add( rbacImpl.getRole( roleName ) );
442                 }
443             }
444             return unassignedRoles;
445         }
446         catch ( MappingException e )
447         {
448             throw new RbacManagerException( e.getMessage(), e );
449         }
450     }
451
452     public UserAssignment getUserAssignment( String username )
453         throws RbacManagerException
454     {
455         try
456         {
457             List<String> roles = ldapRoleMapper.getRoles( username );
458
459             return new UserAssignmentImpl( username, roles );
460         }
461         catch ( MappingException e )
462         {
463             throw new RbacManagerException( e.getMessage(), e );
464         }
465
466         //return this.rbacImpl.getUserAssignment( username );
467     }
468
469     public List<UserAssignment> getUserAssignmentsForRoles( Collection<String> roleNames )
470         throws RbacManagerException
471     {
472         // TODO from ldap
473         return this.rbacImpl.getUserAssignmentsForRoles( roleNames );
474     }
475
476     public boolean operationExists( Operation operation )
477     {
478         return this.rbacImpl.operationExists( operation );
479     }
480
481     public boolean operationExists( String name )
482     {
483         return this.rbacImpl.operationExists( name );
484     }
485
486     public boolean permissionExists( Permission permission )
487     {
488         return this.rbacImpl.permissionExists( permission );
489     }
490
491     public boolean permissionExists( String name )
492     {
493         return this.rbacImpl.permissionExists( name );
494     }
495
496     public void rbacInit( boolean freshdb )
497     {
498         if ( rbacImpl instanceof RBACManagerListener )
499         {
500             ( (RBACManagerListener) this.rbacImpl ).rbacInit( freshdb );
501         }
502     }
503
504     public void rbacPermissionRemoved( Permission permission )
505     {
506         if ( rbacImpl instanceof RBACManagerListener )
507         {
508             ( (RBACManagerListener) this.rbacImpl ).rbacPermissionRemoved( permission );
509         }
510
511     }
512
513     public void rbacPermissionSaved( Permission permission )
514     {
515         if ( rbacImpl instanceof RBACManagerListener )
516         {
517             ( (RBACManagerListener) this.rbacImpl ).rbacPermissionSaved( permission );
518         }
519
520     }
521
522     public void rbacRoleRemoved( Role role )
523     {
524         if ( rbacImpl instanceof RBACManagerListener )
525         {
526             ( (RBACManagerListener) this.rbacImpl ).rbacRoleRemoved( role );
527         }
528
529     }
530
531     public void rbacRoleSaved( Role role )
532     {
533         if ( rbacImpl instanceof RBACManagerListener )
534         {
535             ( (RBACManagerListener) this.rbacImpl ).rbacRoleSaved( role );
536         }
537
538     }
539
540     public void rbacUserAssignmentRemoved( UserAssignment userAssignment )
541     {
542         if ( rbacImpl instanceof RBACManagerListener )
543         {
544             ( (RBACManagerListener) this.rbacImpl ).rbacUserAssignmentRemoved( userAssignment );
545         }
546
547     }
548
549     public void rbacUserAssignmentSaved( UserAssignment userAssignment )
550     {
551         if ( rbacImpl instanceof RBACManagerListener )
552         {
553             ( (RBACManagerListener) this.rbacImpl ).rbacUserAssignmentSaved( userAssignment );
554         }
555
556     }
557
558     public void removeListener( RBACManagerListener listener )
559     {
560         this.rbacImpl.removeListener( listener );
561     }
562
563     public void removeOperation( Operation operation )
564         throws RbacManagerException
565     {
566         this.rbacImpl.removeOperation( operation );
567     }
568
569     public void removeOperation( String operationName )
570         throws RbacManagerException
571     {
572         this.rbacImpl.removeOperation( operationName );
573     }
574
575     public void removePermission( Permission permission )
576         throws RbacManagerException
577     {
578         this.rbacImpl.removePermission( permission );
579     }
580
581     public void removePermission( String permissionName )
582         throws RbacManagerException
583     {
584         this.rbacImpl.removePermission( permissionName );
585     }
586
587     public void removeResource( Resource resource )
588         throws RbacManagerException
589     {
590         this.rbacImpl.removeResource( resource );
591     }
592
593     public void removeResource( String resourceIdentifier )
594         throws RbacManagerException
595     {
596         this.rbacImpl.removeResource( resourceIdentifier );
597     }
598
599     public void removeRole( Role role )
600         throws RbacManagerException
601     {
602         RBACObjectAssertions.assertValid( role );
603
604         if ( role.isPermanent() )
605         {
606             throw new RbacPermanentException( "Unable to delete permanent role [" + role.getName() + "]" );
607         }
608         if ( writableLdap )
609         {
610             try
611             {
612                 ldapRoleMapper.removeRole( role.getName() );
613             }
614             catch ( MappingException e )
615             {
616                 throw new RbacManagerException( e.getMessage(), e );
617             }
618             fireRbacRoleRemoved( role );
619         }
620     }
621
622     public void removeRole( String roleName )
623         throws RbacManagerException
624     {
625         if ( roleName == null )
626         {
627             return;
628         }
629         removeRole( new RoleImpl( roleName ) );
630     }
631
632     public void removeUserAssignment( String username )
633         throws RbacManagerException
634     {
635         // TODO ldap cannot or isWritable ldap ?
636         this.rbacImpl.removeUserAssignment( username );
637     }
638
639     public void removeUserAssignment( UserAssignment userAssignment )
640         throws RbacManagerException
641     {
642         // TODO ldap cannot or isWritable ldap ?
643         this.rbacImpl.removeUserAssignment( userAssignment );
644     }
645
646     public boolean resourceExists( Resource resource )
647     {
648         return this.rbacImpl.resourceExists( resource );
649     }
650
651     public boolean resourceExists( String identifier )
652     {
653         return this.rbacImpl.resourceExists( identifier );
654     }
655
656     @Override
657     public boolean roleExists( Role role )
658         throws RbacManagerException
659     {
660         if ( role == null )
661         {
662             return false;
663         }
664         return roleExists( role.getName() );
665     }
666
667     public boolean roleExists( String name )
668         throws RbacManagerException
669     {
670         if ( StringUtils.isEmpty( name ) )
671         {
672             return false;
673         }
674         try
675         {
676             return ldapRoleMapper.getAllRoles().contains( name );
677         }
678         catch ( Exception e )
679         {
680             throw new RbacManagerException( e.getMessage(), e );
681         }
682     }
683
684     public Operation saveOperation( Operation operation )
685         throws RbacManagerException
686     {
687         return this.rbacImpl.saveOperation( operation );
688     }
689
690     public Permission savePermission( Permission permission )
691         throws RbacManagerException
692     {
693         return this.rbacImpl.savePermission( permission );
694     }
695
696     public Resource saveResource( Resource resource )
697         throws RbacManagerException
698     {
699         return this.rbacImpl.saveResource( resource );
700     }
701
702     public synchronized Role saveRole( Role role )
703         throws RbacManagerException
704     {
705         if ( writableLdap )
706         {
707             try
708             {
709                 ldapRoleMapper.saveRole( role.getName() );
710                 if ( !role.getChildRoleNames().isEmpty() )
711                 {
712                     for ( String roleName : role.getChildRoleNames() )
713                     {
714                         ldapRoleMapper.saveRole( roleName );
715                     }
716                 }
717                 fireRbacRoleSaved( role );
718             }
719             catch ( MappingException e )
720             {
721                 throw new RbacManagerException( e.getMessage(), e );
722             }
723         }
724         return this.rbacImpl.saveRole( role );
725         //return new RoleImpl( role.getName(), role.getPermissions() );
726     }
727
728     public synchronized void saveRoles( Collection<Role> roles )
729         throws RbacManagerException
730     {
731         if ( writableLdap )
732         {
733             try
734             {
735                 for ( Role role : roles )
736                 {
737                     ldapRoleMapper.saveRole( role.getName() );
738                     fireRbacRoleSaved( role );
739                 }
740             }
741             catch ( MappingException e )
742             {
743                 throw new RbacManagerException( e.getMessage(), e );
744             }
745         }
746         this.rbacImpl.saveRoles( roles );
747
748     }
749
750     public UserAssignment saveUserAssignment( UserAssignment userAssignment )
751         throws RbacManagerException
752     {
753
754         try
755         {
756             if ( !userManager.userExists( userAssignment.getPrincipal() ) )
757             {
758                 User user = userManager.createUser( userAssignment.getPrincipal(), null, null );
759                 userManager.addUser( user );
760             }
761
762             List<String> allRoles = ldapRoleMapper.getAllRoles();
763
764             List<String> currentUserRoles = ldapRoleMapper.getRoles( userAssignment.getPrincipal() );
765
766             for ( String role : userAssignment.getRoleNames() )
767             {
768                 if ( !currentUserRoles.contains( role ) && writableLdap )
769                 {
770                     // role exists in ldap ?
771                     if ( !allRoles.contains( role ) )
772                     {
773                         ldapRoleMapper.saveRole( role );
774                         allRoles.add( role );
775                     }
776                     ldapRoleMapper.saveUserRole( role, userAssignment.getPrincipal() );
777                     currentUserRoles.add( role );
778                 }
779             }
780
781             for ( String role : currentUserRoles )
782             {
783                 if ( !userAssignment.getRoleNames().contains( role ) && writableLdap )
784                 {
785                     ldapRoleMapper.removeUserRole( role, userAssignment.getPrincipal() );
786                 }
787             }
788
789             return userAssignment;
790         }
791         catch ( UserManagerException e )
792         {
793             throw new RbacManagerException( e.getMessage(), e );
794         }
795         catch ( MappingException e )
796         {
797             throw new RbacManagerException( e.getMessage(), e );
798         }
799
800         //this.rbacImpl.saveUserAssignment( userAssignment );
801
802         //return userAssignment;
803     }
804
805     public boolean userAssignmentExists( String principal )
806     {
807         // TODO here
808         return this.rbacImpl.userAssignmentExists( principal );
809     }
810
811     public boolean userAssignmentExists( UserAssignment assignment )
812     {
813         // TODO here
814         return this.rbacImpl.userAssignmentExists( assignment );
815     }
816
817     public RBACManager getRbacImpl()
818     {
819         return rbacImpl;
820     }
821
822     public void setRbacImpl( RBACManager rbacImpl )
823     {
824         this.rbacImpl = rbacImpl;
825     }
826
827     public boolean isWritableLdap()
828     {
829         return writableLdap;
830     }
831
832     public void setWritableLdap( boolean writableLdap )
833     {
834         this.writableLdap = writableLdap;
835     }
836
837     public LdapRoleMapper getLdapRoleMapper()
838     {
839         return ldapRoleMapper;
840     }
841
842     public void setLdapRoleMapper( LdapRoleMapper ldapRoleMapper )
843     {
844         this.ldapRoleMapper = ldapRoleMapper;
845     }
846
847     private static class RoleImpl
848         extends AbstractRole
849     {
850         private String name;
851
852         private String description;
853
854         private List<Permission> permissions = new ArrayList<Permission>();
855
856         private List<String> childRoleNames = new ArrayList<String>();
857
858         private RoleImpl( String name )
859         {
860             this.name = name;
861         }
862
863         private RoleImpl( String name, List<Permission> permissions )
864         {
865             this.name = name;
866             this.permissions = permissions;
867         }
868
869         public void addPermission( Permission permission )
870         {
871             this.permissions.add( permission );
872         }
873
874         public void addChildRoleName( String name )
875         {
876             this.childRoleNames.add( name );
877         }
878
879         public List<String> getChildRoleNames()
880         {
881             return this.childRoleNames;
882         }
883
884         public String getDescription()
885         {
886             return this.description;
887         }
888
889         public String getName()
890         {
891             return this.name;
892         }
893
894         public List<Permission> getPermissions()
895         {
896             return this.permissions;
897         }
898
899         public boolean isAssignable()
900         {
901             return true;
902         }
903
904         public void removePermission( Permission permission )
905         {
906             this.permissions.remove( permission );
907         }
908
909         public void setAssignable( boolean assignable )
910         {
911             // no op
912         }
913
914         public void setChildRoleNames( List<String> names )
915         {
916             this.childRoleNames = names;
917         }
918
919         public void setDescription( String description )
920         {
921             this.description = description;
922         }
923
924         public void setName( String name )
925         {
926             this.name = name;
927         }
928
929         public void setPermissions( List<Permission> permissions )
930         {
931             this.permissions = permissions;
932         }
933
934         public boolean isPermanent()
935         {
936             return true;
937         }
938
939         public void setPermanent( boolean permanent )
940         {
941             // no op
942         }
943
944         @Override
945         public String toString()
946         {
947             final StringBuilder sb = new StringBuilder();
948             sb.append( "RoleImpl" );
949             sb.append( "{name='" ).append( name ).append( '\'' );
950             sb.append( '}' );
951             return sb.toString();
952         }
953
954         @Override
955         public boolean equals( Object o )
956         {
957             if ( this == o )
958             {
959                 return true;
960             }
961             if ( o == null || getClass() != o.getClass() )
962             {
963                 return false;
964             }
965
966             RoleImpl role = (RoleImpl) o;
967
968             if ( name != null ? !name.equals( role.name ) : role.name != null )
969             {
970                 return false;
971             }
972
973             return true;
974         }
975
976         @Override
977         public int hashCode()
978         {
979             return name != null ? name.hashCode() : 0;
980         }
981     }
982
983     private static class UserAssignmentImpl
984         implements UserAssignment
985     {
986         private String username;
987
988         private List<String> roleNames;
989
990         private boolean permanent;
991
992         private UserAssignmentImpl( String username, Collection<String> roleNames )
993         {
994             this.username = username;
995
996             if ( roleNames == null )
997             {
998                 this.roleNames = new ArrayList<String>();
999             }
1000             else
1001             {
1002                 this.roleNames = new ArrayList<String>( roleNames );
1003             }
1004         }
1005
1006         public String getPrincipal()
1007         {
1008             return this.username;
1009         }
1010
1011         public List<String> getRoleNames()
1012         {
1013             return this.roleNames;
1014         }
1015
1016         public void addRoleName( Role role )
1017         {
1018             if ( role == null )
1019             {
1020                 return;
1021             }
1022             this.roleNames.add( role.getName() );
1023         }
1024
1025         public void addRoleName( String roleName )
1026         {
1027             if ( roleName == null )
1028             {
1029                 return;
1030             }
1031             this.roleNames.add( roleName );
1032         }
1033
1034         public void removeRoleName( Role role )
1035         {
1036             if ( role == null )
1037             {
1038                 return;
1039             }
1040             this.roleNames.remove( role.getName() );
1041         }
1042
1043         public void removeRoleName( String roleName )
1044         {
1045             if ( roleName == null )
1046             {
1047                 return;
1048             }
1049             this.roleNames.remove( roleName );
1050         }
1051
1052         public void setPrincipal( String principal )
1053         {
1054             this.username = principal;
1055         }
1056
1057         public void setRoleNames( List<String> roles )
1058         {
1059             this.roleNames = roles;
1060         }
1061
1062         public boolean isPermanent()
1063         {
1064             return this.permanent;
1065         }
1066
1067         public void setPermanent( boolean permanent )
1068         {
1069             this.permanent = permanent;
1070         }
1071
1072         @Override
1073         public String toString()
1074         {
1075             final StringBuilder sb = new StringBuilder();
1076             sb.append( "UserAssignmentImpl" );
1077             sb.append( "{username='" ).append( username ).append( '\'' );
1078             sb.append( ", roleNames=" ).append( roleNames );
1079             sb.append( ", permanent=" ).append( permanent );
1080             sb.append( '}' );
1081             return sb.toString();
1082         }
1083     }
1084 }