001package org.apache.archiva.redback.rest.services;
002/*
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *   http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing,
014 * software distributed under the License is distributed on an
015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016 * KIND, either express or implied.  See the License for the
017 * specific language governing permissions and limitations
018 * under the License.
019 */
020
021import org.apache.archiva.redback.integration.model.AdminEditUserCredentials;
022import org.apache.archiva.redback.integration.security.role.RedbackRoleConstants;
023import org.apache.archiva.redback.integration.util.RoleSorter;
024import org.apache.archiva.redback.rbac.Permission;
025import org.apache.archiva.redback.rbac.RBACManager;
026import org.apache.archiva.redback.rbac.RbacManagerException;
027import org.apache.archiva.redback.rbac.Resource;
028import org.apache.archiva.redback.rbac.UserAssignment;
029import org.apache.archiva.redback.rest.api.model.ActionStatus;
030import org.apache.archiva.redback.rest.api.model.Application;
031import org.apache.archiva.redback.rest.api.model.ApplicationRoles;
032import org.apache.archiva.redback.rest.api.model.ErrorMessage;
033import org.apache.archiva.redback.rest.api.model.Role;
034import org.apache.archiva.redback.rest.api.model.RoleTemplate;
035import org.apache.archiva.redback.rest.api.model.VerificationStatus;
036import org.apache.archiva.redback.rest.api.services.RedbackServiceException;
037import org.apache.archiva.redback.rest.api.services.RoleManagementService;
038import org.apache.archiva.redback.role.RoleManager;
039import org.apache.archiva.redback.role.RoleManagerException;
040import org.apache.archiva.redback.role.model.ModelApplication;
041import org.apache.archiva.redback.role.model.ModelRole;
042import org.apache.archiva.redback.role.model.ModelTemplate;
043import org.apache.archiva.redback.users.User;
044import org.apache.archiva.redback.users.UserManager;
045import org.apache.archiva.redback.users.UserManagerException;
046import org.apache.archiva.redback.users.UserNotFoundException;
047import org.apache.commons.lang3.StringUtils;
048import org.slf4j.Logger;
049import org.slf4j.LoggerFactory;
050import org.springframework.stereotype.Service;
051
052import javax.inject.Inject;
053import javax.inject.Named;
054import javax.ws.rs.core.Response;
055import java.util.ArrayList;
056import java.util.Arrays;
057import java.util.Collection;
058import java.util.Collections;
059import java.util.Comparator;
060import java.util.HashSet;
061import java.util.List;
062import java.util.Map;
063import java.util.Optional;
064import java.util.Set;
065import java.util.stream.Collectors;
066
067/**
068 * @deprecated Use the new V2 version {@link org.apache.archiva.redback.rest.services.v2.DefaultRoleService}
069 * @author Olivier Lamy
070 * @since 1.3
071 */
072@Deprecated
073@Service("roleManagementService#rest")
074public class DefaultRoleManagementService
075    implements RoleManagementService
076{
077
078    private Logger log = LoggerFactory.getLogger( getClass() );
079
080    private RoleManager roleManager;
081
082    private RBACManager rbacManager;
083
084    private UserManager userManager;
085
086    @Inject
087    public DefaultRoleManagementService( RoleManager roleManager,
088                                         @Named(value = "rbacManager#default") RBACManager rbacManager,
089                                         @Named(value = "userManager#default") UserManager userManager )
090    {
091        this.roleManager = roleManager;
092        this.rbacManager = rbacManager;
093        this.userManager = userManager;
094
095        log.debug( "use rbacManager impl: {}", rbacManager.getClass().getName() );
096        log.debug( "use userManager impl: {}", userManager.getClass().getName() );
097    }
098
099    public ActionStatus createTemplatedRole( String templateId, String resource )
100        throws RedbackServiceException
101    {
102        try
103        {
104            roleManager.createTemplatedRole( templateId, resource );
105        }
106        catch ( RoleManagerException e )
107        {
108            throw new RedbackServiceException( e.getMessage() );
109        }
110        return ActionStatus.SUCCESS;
111    }
112
113    public ActionStatus removeTemplatedRole( String templateId, String resource )
114        throws RedbackServiceException
115    {
116
117        try
118        {
119            roleManager.removeTemplatedRole( templateId, resource );
120        }
121        catch ( RoleManagerException e )
122        {
123            throw new RedbackServiceException( e.getMessage() );
124        }
125        return ActionStatus.SUCCESS;
126    }
127
128    public ActionStatus updateRole( String templateId, String oldResource, String newResource )
129        throws RedbackServiceException
130    {
131        try
132        {
133            roleManager.moveTemplatedRole( templateId, oldResource, newResource );
134        }
135        catch ( RoleManagerException e )
136        {
137            throw new RedbackServiceException( e.getMessage() );
138        }
139        return ActionStatus.SUCCESS;
140    }
141
142    public ActionStatus assignRole( String roleId, String principal )
143        throws RedbackServiceException
144    {
145        try
146        {
147            roleManager.assignRole( roleId, principal );
148        }
149        catch ( RoleManagerException e )
150        {
151            throw new RedbackServiceException( e.getMessage() );
152        }
153        return ActionStatus.SUCCESS;
154    }
155
156    public ActionStatus assignRoleByName( String roleName, String principal )
157        throws RedbackServiceException
158    {
159        try
160        {
161            roleManager.assignRoleByName( roleName, principal );
162        }
163        catch ( RoleManagerException e )
164        {
165            throw new RedbackServiceException( e.getMessage() );
166        }
167        return ActionStatus.SUCCESS;
168    }
169
170    public ActionStatus assignTemplatedRole( String templateId, String resource, String principal )
171        throws RedbackServiceException
172    {
173        try
174        {
175            roleManager.assignTemplatedRole( templateId, resource, principal );
176        }
177        catch ( RoleManagerException e )
178        {
179            throw new RedbackServiceException( e.getMessage() );
180        }
181        return ActionStatus.SUCCESS;
182    }
183
184    public ActionStatus unassignRole( String roleId, String principal )
185        throws RedbackServiceException
186    {
187        try
188        {
189            roleManager.unassignRole( roleId, principal );
190        }
191        catch ( RoleManagerException e )
192        {
193            throw new RedbackServiceException( e.getMessage() );
194        }
195        return ActionStatus.SUCCESS;
196    }
197
198    public ActionStatus unassignRoleByName( String roleName, String principal )
199        throws RedbackServiceException
200    {
201        try
202        {
203            roleManager.unassignRoleByName( roleName, principal );
204        }
205        catch ( RoleManagerException e )
206        {
207            throw new RedbackServiceException( e.getMessage() );
208        }
209        return ActionStatus.SUCCESS;
210    }
211
212    public Boolean roleExists( String roleId )
213        throws RedbackServiceException
214    {
215        try
216        {
217            return roleManager.roleExists( roleId );
218        }
219        catch ( RoleManagerException e )
220        {
221            throw new RedbackServiceException( e.getMessage() );
222        }
223    }
224
225    public Boolean templatedRoleExists( String templateId, String resource )
226        throws RedbackServiceException
227    {
228        try
229        {
230            return roleManager.templatedRoleExists( templateId, resource );
231        }
232        catch ( RoleManagerException e )
233        {
234            throw new RedbackServiceException( e.getMessage() );
235        }
236
237    }
238
239    public VerificationStatus verifyTemplatedRole( String templateId, String resource )
240        throws RedbackServiceException
241    {
242        try
243        {
244            roleManager.verifyTemplatedRole( templateId, resource );
245        }
246        catch ( RoleManagerException e )
247        {
248            throw new RedbackServiceException( e.getMessage() );
249        }
250        return new VerificationStatus( true );
251    }
252
253    public List<Role> getEffectivelyAssignedRoles( String username )
254        throws RedbackServiceException
255    {
256        if ( StringUtils.isEmpty( username ) )
257        {
258            throw new RedbackServiceException( new ErrorMessage( "user.cannot.be.null" ) );
259        }
260        try
261        {
262            List<? extends org.apache.archiva.redback.rbac.Role> roles =
263                filterAssignableRoles( rbacManager.getEffectivelyAssignedRoles( username ) );
264
265            List<Role> effectivelyAssignedRoles = new ArrayList<Role>( roles.size() );
266
267            for ( org.apache.archiva.redback.rbac.Role r : roles )
268            {
269                effectivelyAssignedRoles.add( new Role( r ) );
270            }
271
272            Collections.sort( effectivelyAssignedRoles, RoleComparator.INSTANCE  );
273
274            return effectivelyAssignedRoles;
275        }
276        catch ( RbacManagerException rme )
277        {
278            // ignore, this can happen when the user has no roles assigned  
279        }
280        return new ArrayList<Role>( 0 );
281    }
282
283    private static class RoleComparator implements Comparator<Role> {
284
285        private static RoleComparator INSTANCE = new RoleComparator();
286
287        @Override
288        public int compare( Role role, Role role2 )
289        {
290            return role.getName().compareTo( role2.getName() );
291        }
292    }
293
294
295    public List<Application> getApplications( String username )
296        throws RedbackServiceException
297    {
298
299        List<ModelApplication> modelApplications = roleManager.getModel().getApplications();
300
301        List<Application> applications = new ArrayList<Application>( modelApplications.size() );
302
303        for ( ModelApplication modelApplication : modelApplications )
304        {
305            Application application = new Application();
306            application.setDescription( modelApplication.getDescription() );
307            application.setId( modelApplication.getId() );
308            application.setLongDescription( modelApplication.getLongDescription() );
309            application.setVersion( modelApplication.getVersion() );
310            applications.add( application );
311        }
312
313        return applications;
314    }
315
316    public List<Role> getAllRoles()
317        throws RedbackServiceException
318    {
319        try
320        {
321            List<? extends org.apache.archiva.redback.rbac.Role> roles = rbacManager.getAllRoles();
322
323            if ( roles == null )
324            {
325                return Collections.emptyList();
326            }
327
328            roles = filterRolesForCurrentUserAccess( roles );
329
330            List<Role> res = new ArrayList<Role>( roles.size() );
331
332            for ( org.apache.archiva.redback.rbac.Role r : roles )
333            {
334                res.add( new Role( r ) );
335            }
336            return res;
337
338        }
339        catch ( RbacManagerException e )
340        {
341            throw new RedbackServiceException( e.getMessage() );
342        }
343    }
344
345    public List<Role> getDetailedAllRoles()
346        throws RedbackServiceException
347    {
348        try
349        {
350            List<? extends org.apache.archiva.redback.rbac.Role> roles = rbacManager.getAllRoles();
351
352            if ( roles == null )
353            {
354                return Collections.emptyList();
355            }
356
357            roles = filterRolesForCurrentUserAccess( roles );
358
359            List<Role> res = new ArrayList<Role>( roles.size() );
360
361            for ( org.apache.archiva.redback.rbac.Role r : roles )
362            {
363                res.add( getRole( r.getName() ) );
364            }
365            return res;
366
367        }
368        catch ( RbacManagerException e )
369        {
370            throw new RedbackServiceException( e.getMessage() );
371        }
372    }
373
374    private List<? extends org.apache.archiva.redback.rbac.Role> filterAssignableRoles(
375        Collection<? extends org.apache.archiva.redback.rbac.Role> roles )
376    {
377        List<org.apache.archiva.redback.rbac.Role> assignableRoles =
378            new ArrayList<org.apache.archiva.redback.rbac.Role>( roles.size() );
379        for ( org.apache.archiva.redback.rbac.Role r : roles )
380        {
381            if ( r.isAssignable() )
382            {
383                assignableRoles.add( r );
384            }
385        }
386        return assignableRoles;
387    }
388
389    public Role getRole( String roleName )
390        throws RedbackServiceException
391    {
392        try
393        {
394            org.apache.archiva.redback.rbac.Role rbacRole = rbacManager.getRole( roleName );
395            Role role = new Role( rbacRole );
396
397            Map<String, ? extends org.apache.archiva.redback.rbac.Role> parentRoleIds = rbacManager.getParentRoleIds( rbacRole );
398            for ( String parentRoleId : parentRoleIds.keySet() )
399            {
400                org.apache.archiva.redback.rbac.Role rbacParentRole = rbacManager.getRoleById( parentRoleId );
401                role.getParentRoleNames().add( rbacParentRole.getName() );
402            }
403
404            List<? extends UserAssignment> userAssignments = rbacManager.getUserAssignmentsForRoles( Arrays.asList( rbacRole.getId() ) );
405
406            if ( userAssignments != null )
407            {
408                for ( UserAssignment userAssignment : userAssignments )
409                {
410                    try
411                    {
412                        User user = userManager.findUser( userAssignment.getPrincipal() );
413                        role.getUsers().add( new org.apache.archiva.redback.rest.api.model.User( user ) );
414                    }
415                    catch ( UserNotFoundException e )
416                    {
417                        log.warn( "User '{}' doesn't exist.", userAssignment.getPrincipal(), e );
418                    }
419                }
420            }
421
422            if ( !role.getParentRoleNames().isEmpty() )
423            {
424                List<? extends UserAssignment> userParentAssignments =
425                    rbacManager.getUserAssignmentsForRoles( parentRoleIds.keySet() );
426                if ( userParentAssignments != null )
427                {
428                    for ( UserAssignment userAssignment : userParentAssignments )
429                    {
430                        try
431                        {
432                            User user = userManager.findUser( userAssignment.getPrincipal() );
433                            role.getParentsRolesUsers().add(
434                                new org.apache.archiva.redback.rest.api.model.User( user ) );
435                        }
436                        catch ( UserNotFoundException e )
437                        {
438                            log.warn( "User '{}' doesn't exist.", userAssignment.getPrincipal(), e );
439                        }
440                    }
441                }
442            }
443
444            List<org.apache.archiva.redback.rest.api.model.User> otherUsers = new ArrayList<>();
445            for ( User u : userManager.getUsers() )
446            {
447                org.apache.archiva.redback.rest.api.model.User user =
448                    new org.apache.archiva.redback.rest.api.model.User( u );
449                if ( role.getParentsRolesUsers().contains( user ) )
450                {
451                    continue;
452                }
453                if ( role.getUsers().contains( user ) )
454                {
455                    continue;
456                }
457                otherUsers.add( user );
458            }
459
460            role.setOtherUsers( otherUsers );
461
462            return role;
463        }
464        catch ( RbacManagerException | UserManagerException e )
465        {
466            throw new RedbackServiceException( new ErrorMessage( e.getMessage() ) );
467        }
468    }
469
470    public ActionStatus updateRoleDescription( String roleName, String description )
471        throws RedbackServiceException
472    {
473        try
474        {
475            org.apache.archiva.redback.rbac.Role rbacRole = rbacManager.getRole( roleName );
476            rbacRole.setDescription( description == null ? "" : description);
477            rbacManager.saveRole( rbacRole );
478        }
479        catch ( RbacManagerException e )
480        {
481            throw new RedbackServiceException( new ErrorMessage( e.getMessage() ) );
482        }
483        return ActionStatus.SUCCESS;
484    }
485
486    public ActionStatus updateRoleUsers( Role role )
487        throws RedbackServiceException
488    {
489
490        for ( org.apache.archiva.redback.rest.api.model.User user : role.getUsers() )
491        {
492            String username = user.getUsername();
493
494            try
495            {
496
497                if ( !userManager.userExists( username ) )
498                {
499                    log.error( "user {} not exits", username );
500                    throw new RedbackServiceException(
501                        new ErrorMessage( "user.not.exists", new String[]{ username } ) );
502                }
503
504                UserAssignment assignment;
505
506                if ( rbacManager.userAssignmentExists( username ) )
507                {
508                    assignment = rbacManager.getUserAssignment( username );
509                }
510                else
511                {
512                    assignment = rbacManager.createUserAssignment( username );
513                }
514
515                org.apache.archiva.redback.rbac.Role rbacRole = rbacManager.getRole( role.getName( ) );
516                assignment.addRoleId( rbacRole.getId() );
517                assignment = rbacManager.saveUserAssignment( assignment );
518                log.info( "{} role assigned to {}", role.getName(), username );
519            }
520            catch ( RbacManagerException e )
521            {
522                log.error( "error during assign role {} to user {}" , role.getName(), username, e );
523                throw new RedbackServiceException(
524                    new ErrorMessage( "error.assign.role.user", new String[]{ role.getName(), username } ) );
525            }
526            catch ( UserManagerException e )
527            {
528                throw new RedbackServiceException( new ErrorMessage( e.getMessage() ) );
529            }
530        }
531
532        for ( org.apache.archiva.redback.rest.api.model.User user : role.getRemovedUsers() )
533        {
534            String username = user.getUsername();
535
536            try
537            {
538
539                if ( !userManager.userExists( username ) )
540                {
541                    log.error( "user {} not exits", username );
542                    throw new RedbackServiceException(
543                        new ErrorMessage( "user.not.exists", new String[]{ username } ) );
544                }
545
546                UserAssignment assignment;
547
548                if ( rbacManager.userAssignmentExists( username ) )
549                {
550                    assignment = rbacManager.getUserAssignment( username );
551                }
552                else
553                {
554                    assignment = rbacManager.createUserAssignment( username );
555                }
556
557                org.apache.archiva.redback.rbac.Role rbacRole = rbacManager.getRole( role.getName( ) );
558                assignment.removeRoleId( rbacRole.getId() );
559                assignment = rbacManager.saveUserAssignment( assignment );
560                log.info( "{} role unassigned to {}", role.getName(), username );
561            }
562            catch ( RbacManagerException e )
563            {
564                log.error( "error during assign role {} to user {}" , role.getName(), username, e );
565                throw new RedbackServiceException(
566                    new ErrorMessage( "error.unassign.role.user", new String[]{ role.getName(), username } ) );
567            }
568            catch ( UserManagerException e )
569            {
570                throw new RedbackServiceException( new ErrorMessage( e.getMessage() ) );
571            }
572        }
573
574        return ActionStatus.SUCCESS;
575    }
576
577    public List<ApplicationRoles> getApplicationRoles( String username )
578        throws RedbackServiceException
579    {
580        AdminEditUserCredentials user = null;
581        if ( StringUtils.isEmpty( username ) )
582        {
583            throw new RedbackServiceException( new ErrorMessage( "rbac.edit.user.empty.principal" ) );
584        }
585
586        try
587        {
588            if ( !userManager.userExists( username ) )
589            {
590                throw new RedbackServiceException(
591                    new ErrorMessage( "user.does.not.exist", new String[]{ username } ) );
592            }
593
594            User u = userManager.findUser( username );
595
596            if ( u == null )
597            {
598                throw new RedbackServiceException( new ErrorMessage( "cannot.operate.on.null.user" ) );
599            }
600
601            user = new AdminEditUserCredentials( u );
602        }
603        catch ( UserNotFoundException e )
604        {
605            throw new RedbackServiceException(
606                new ErrorMessage( "user.does.not.exist", new String[]{ username, e.getMessage() } ) );
607        }
608        catch ( UserManagerException e )
609        {
610            throw new RedbackServiceException( new ErrorMessage( e.getMessage() ) );
611        }
612        try
613        {
614            // check first if role assignments for user exist
615            if ( !rbacManager.userAssignmentExists( username ) )
616            {
617                UserAssignment assignment = rbacManager.createUserAssignment( username );
618                rbacManager.saveUserAssignment( assignment );
619            }
620
621            List<? extends org.apache.archiva.redback.rbac.Role> allRoles =
622                filterRolesForCurrentUserAccess( rbacManager.getAllRoles() );
623
624            List<ModelApplication> modelApplications = roleManager.getModel().getApplications();
625
626            List<ApplicationRoles> applicationRolesList = new ArrayList<>( modelApplications.size() );
627
628            for ( ModelApplication modelApplication : modelApplications )
629            {
630                ApplicationRoles applicationRoles = new ApplicationRoles();
631
632                applicationRoles.setDescription( modelApplication.getDescription() );
633                applicationRoles.setName( modelApplication.getId() );
634
635                Collection<? extends org.apache.archiva.redback.rbac.Role> appRoles =
636                    filterApplicationRoles( modelApplication, allRoles, modelApplication.getTemplates() );
637
638                List<String> roleNames = new ArrayList<>( toRoleNames( appRoles ) );
639
640                Collections.sort( roleNames );
641
642                applicationRoles.setGlobalRoles( roleNames );
643
644                Set<String> resources = discoverResources( modelApplication.getTemplates(), appRoles );
645
646                applicationRoles.setResources( resources );
647
648                applicationRoles.setRoleTemplates( toRoleTemplates( modelApplication.getTemplates() ) );
649
650                // cleanup app roles remove roles coming from templates
651
652                List<String> appRoleNames = new ArrayList<>( appRoles.size() );
653
654                for ( String appRoleName : applicationRoles.getGlobalRoles() )
655                {
656                    if ( !roleFromTemplate( appRoleName, modelApplication.getTemplates() ) )
657                    {
658                        appRoleNames.add( appRoleName );
659                    }
660                }
661
662                Collections.sort( appRoleNames );
663
664                applicationRoles.setGlobalRoles( appRoleNames );
665
666                Collections.sort( appRoleNames );
667
668                applicationRolesList.add( applicationRoles );
669            }
670
671            return applicationRolesList;
672
673        }
674        catch ( RbacManagerException e )
675        {
676            RedbackServiceException redbackServiceException =
677                new RedbackServiceException( new ErrorMessage( e.getMessage() ) );
678            redbackServiceException.setHttpErrorCode( Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() );
679            throw redbackServiceException;
680        }
681    }
682
683    public ActionStatus updateUserRoles( org.apache.archiva.redback.rest.api.model.User user )
684        throws RedbackServiceException
685    {
686
687        String username = user.getUsername();
688
689        if ( StringUtils.isEmpty( username ) )
690        {
691            throw new RedbackServiceException( new ErrorMessage( "rbac.edit.user.empty.principal" ) );
692        }
693
694        try
695        {
696
697            if ( !userManager.userExists( username ) )
698            {
699                throw new RedbackServiceException(
700                    new ErrorMessage( "user.does.not.exist", new String[]{ username } ) );
701            }
702
703            User u = userManager.findUser( username );
704
705            if ( u == null )
706            {
707                throw new RedbackServiceException( new ErrorMessage( "cannot.operate.on.null.user" ) );
708            }
709
710        }
711        catch ( UserNotFoundException e )
712        {
713            throw new RedbackServiceException(
714                new ErrorMessage( "user.does.not.exist", new String[]{ username, e.getMessage() } ) );
715        }
716        catch ( UserManagerException e )
717        {
718            throw new RedbackServiceException( new ErrorMessage( e.getMessage() ) );
719        }
720
721        try
722        {
723
724            UserAssignment assignment;
725
726            if ( rbacManager.userAssignmentExists( username ) )
727            {
728                assignment = rbacManager.getUserAssignment( username );
729            }
730            else
731            {
732                assignment = rbacManager.createUserAssignment( username );
733            }
734            List<String> assignedRoleIds = user.getAssignedRoles().stream().map(roleName -> {
735                try
736                {
737                    return Optional.of( rbacManager.getRole( roleName ).getId( ) );
738                }
739                catch ( RbacManagerException e )
740                {
741                    return Optional.<String>empty( );
742                }
743            } ).filter( Optional::isPresent ).map(Optional::get).collect( Collectors.toList());
744            assignment.setRoleIds( assignedRoleIds );
745            rbacManager.saveUserAssignment( assignment );
746
747        }
748        catch ( RbacManagerException e )
749        {
750            RedbackServiceException redbackServiceException =
751                new RedbackServiceException( new ErrorMessage( e.getMessage() ) );
752            redbackServiceException.setHttpErrorCode( Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() );
753            throw redbackServiceException;
754        }
755
756        return ActionStatus.SUCCESS;
757
758    }
759
760    //----------------------------------------------------------------
761    // Internal methods
762    //----------------------------------------------------------------
763
764    private org.apache.archiva.redback.rbac.Role isInList( String roleName,
765                                                           Collection<? extends org.apache.archiva.redback.rbac.Role> roles )
766    {
767        for ( org.apache.archiva.redback.rbac.Role role : roles )
768        {
769            if ( roleName.equals( role.getName() ) )
770            {
771                return role;
772            }
773        }
774        return null;
775    }
776
777    private Collection<? extends org.apache.archiva.redback.rbac.Role> filterApplicationRoles( ModelApplication application,
778                                                                                     List<? extends org.apache.archiva.redback.rbac.Role> allRoles,
779                                                                                     List<ModelTemplate> applicationTemplates )
780    {
781        Set<org.apache.archiva.redback.rbac.Role> applicationRoles = new HashSet<>();
782        List<ModelRole> roles = application.getRoles();
783
784        for ( ModelRole modelRole : roles )
785        {
786            org.apache.archiva.redback.rbac.Role r = isInList( modelRole.getName(), allRoles );
787            if ( r != null )
788            {
789                applicationRoles.add( r );
790            }
791        }
792
793        List<String> roleNames = toRoleNames( allRoles );
794
795        for ( ModelTemplate modelTemplate : applicationTemplates )
796        {
797            for ( org.apache.archiva.redback.rbac.Role r : allRoles )
798            {
799                if ( StringUtils.startsWith( r.getName(),
800                                             modelTemplate.getNamePrefix() + modelTemplate.getDelimiter() ) )
801                {
802                    applicationRoles.add( r );
803                }
804            }
805        }
806
807        return applicationRoles;
808    }
809
810    private boolean roleFromTemplate( String roleName, List<ModelTemplate> applicationTemplates )
811    {
812
813        for ( ModelTemplate modelTemplate : applicationTemplates )
814        {
815            if ( StringUtils.startsWith( roleName, modelTemplate.getNamePrefix() + modelTemplate.getDelimiter() ) )
816            {
817                return true;
818            }
819
820        }
821        return false;
822    }
823
824    private List<String> toRoleNames( Collection<? extends org.apache.archiva.redback.rbac.Role> roles )
825    {
826        List<String> names = new ArrayList<>( roles.size() );
827
828        for ( org.apache.archiva.redback.rbac.Role r : roles )
829        {
830            names.add( r.getName() );
831        }
832
833        return names;
834    }
835
836    private List<RoleTemplate> toRoleTemplates( List<ModelTemplate> modelTemplates )
837    {
838        if ( modelTemplates == null || modelTemplates.isEmpty() )
839        {
840            return new ArrayList<>( 0 );
841        }
842
843        List<RoleTemplate> roleTemplates = new ArrayList<RoleTemplate>( modelTemplates.size() );
844
845        for ( ModelTemplate modelTemplate : modelTemplates )
846        {
847            RoleTemplate roleTemplate = new RoleTemplate();
848
849            roleTemplate.setDelimiter( modelTemplate.getDelimiter() );
850            roleTemplate.setDescription( modelTemplate.getDescription() );
851            roleTemplate.setId( modelTemplate.getId() );
852            roleTemplate.setNamePrefix( modelTemplate.getNamePrefix() );
853
854            roleTemplates.add( roleTemplate );
855        }
856
857        return roleTemplates;
858    }
859
860    private Set<String> discoverResources( List<ModelTemplate> applicationTemplates,
861                                           Collection<? extends org.apache.archiva.redback.rbac.Role> roles )
862    {
863        Set<String> resources = new HashSet<>();
864        for ( ModelTemplate modelTemplate : applicationTemplates )
865        {
866            for ( org.apache.archiva.redback.rbac.Role role : roles )
867            {
868                String roleName = role.getName();
869                if ( roleName.startsWith( modelTemplate.getNamePrefix() ) )
870                {
871                    String delimiter = modelTemplate.getDelimiter();
872                    resources.add( roleName.substring( roleName.indexOf( delimiter ) + delimiter.length() ) );
873                }
874            }
875        }
876        return resources;
877    }
878
879    /**
880     * this is a hack. this is a hack around the requirements of putting RBAC constraints into the model. this adds one
881     * very major restriction to this security system, that a role name must contain the identifiers of the resource
882     * that is being constrained for adding and granting of roles, this is unacceptable in the long term and we need to
883     * get the model refactored to include this RBAC concept
884     *
885     * @param roleList
886     * @return
887     * @throws RedbackServiceException
888     *
889     */
890    protected List<? extends org.apache.archiva.redback.rbac.Role> filterRolesForCurrentUserAccess(
891        List<? extends org.apache.archiva.redback.rbac.Role> roleList )
892        throws RedbackServiceException
893    {
894        RedbackRequestInformation redbackRequestInformation = RedbackAuthenticationThreadLocal.get();
895        // olamy: should not happened normally as annotations check this first
896        if ( redbackRequestInformation == null || redbackRequestInformation.getUser() == null )
897        {
898            throw new RedbackServiceException( new ErrorMessage( "login.mandatory" ) );
899        }
900        String currentUser = redbackRequestInformation.getUser().getUsername();
901
902        List<org.apache.archiva.redback.rbac.Role> filteredRoleList = new ArrayList<>();
903        try
904        {
905            Map<String, List<? extends Permission>> assignedPermissionMap = rbacManager.getAssignedPermissionMap( currentUser );
906            List<String> resourceGrants = new ArrayList<String>();
907
908            if ( assignedPermissionMap.containsKey( RedbackRoleConstants.USER_MANAGEMENT_ROLE_GRANT_OPERATION ) )
909            {
910                List<? extends Permission> roleGrantPermissions =
911                    assignedPermissionMap.get( RedbackRoleConstants.USER_MANAGEMENT_ROLE_GRANT_OPERATION );
912
913                for ( Permission permission : roleGrantPermissions )
914                {
915                    if ( permission.getResource().getIdentifier().equals( Resource.GLOBAL ) )
916                    {
917                        // the current user has the rights to assign any given role
918                        return roleList;
919                    }
920                    else
921                    {
922                        resourceGrants.add( permission.getResource().getIdentifier() );
923                    }
924                }
925
926            }
927            else
928            {
929                return Collections.emptyList();
930            }
931
932            String delimiter = " - ";
933
934            // we should have a list of resourceGrants now, this will provide us with the information necessary to restrict
935            // the role list
936            for ( org.apache.archiva.redback.rbac.Role role : roleList )
937            {
938                int delimiterIndex = role.getName().indexOf( delimiter );
939                for ( String resourceIdentifier : resourceGrants )
940                {
941
942                    if ( ( role.getName().indexOf( resourceIdentifier ) != -1 ) && ( delimiterIndex != -1 ) )
943                    {
944                        String resourceName = role.getName().substring( delimiterIndex + delimiter.length() );
945                        if ( resourceName.equals( resourceIdentifier ) )
946                        {
947                            filteredRoleList.add( role );
948                        }
949                    }
950                }
951            }
952        }
953        catch ( RbacManagerException rme )
954        {
955            // ignore, this can happen when the user has no roles assigned  
956        }
957        Collections.sort( filteredRoleList, new RoleSorter() );
958        return filteredRoleList;
959    }
960
961
962}