]> source.dussan.org Git - archiva.git/blob
c4ab09ee24e19181cb4b958092ad2a51ef2c5747
[archiva.git] /
1 package org.apache.archiva.rest.services.v2;/*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  * Unless required by applicable law or agreed to in writing,
12  * software distributed under the License is distributed on an
13  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14  * KIND, either express or implied.  See the License for the
15  * specific language governing permissions and limitations
16  * under the License.
17  */
18
19 import org.apache.archiva.admin.model.RepositoryAdminException;
20 import org.apache.archiva.admin.model.beans.RedbackRuntimeConfiguration;
21 import org.apache.archiva.admin.model.runtime.RedbackRuntimeConfigurationAdmin;
22 import org.apache.archiva.components.rest.model.PagedResult;
23 import org.apache.archiva.components.rest.model.PropertyEntry;
24 import org.apache.archiva.components.rest.util.QueryHelper;
25 import org.apache.archiva.redback.authentication.Authenticator;
26 import org.apache.archiva.redback.common.ldap.connection.LdapConnection;
27 import org.apache.archiva.redback.common.ldap.connection.LdapConnectionConfiguration;
28 import org.apache.archiva.redback.common.ldap.connection.LdapConnectionFactory;
29 import org.apache.archiva.redback.common.ldap.connection.LdapException;
30 import org.apache.archiva.redback.common.ldap.user.LdapUserMapper;
31 import org.apache.archiva.redback.policy.CookieSettings;
32 import org.apache.archiva.redback.policy.PasswordRule;
33 import org.apache.archiva.redback.rbac.RBACManager;
34 import org.apache.archiva.redback.role.RoleManager;
35 import org.apache.archiva.redback.users.UserManager;
36 import org.apache.archiva.rest.api.model.v2.BeanInformation;
37 import org.apache.archiva.rest.api.model.v2.CacheConfiguration;
38 import org.apache.archiva.rest.api.model.v2.LdapConfiguration;
39 import org.apache.archiva.rest.api.model.v2.SecurityConfiguration;
40 import org.apache.archiva.rest.api.services.v2.ArchivaRestServiceException;
41 import org.apache.archiva.rest.api.services.v2.ErrorMessage;
42 import org.apache.archiva.rest.api.services.v2.SecurityConfigurationService;
43 import org.apache.commons.collections4.CollectionUtils;
44 import org.apache.commons.lang3.StringUtils;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47 import org.springframework.context.ApplicationContext;
48 import org.springframework.stereotype.Service;
49
50 import javax.annotation.PostConstruct;
51 import javax.inject.Inject;
52 import javax.inject.Named;
53 import javax.naming.AuthenticationException;
54 import javax.naming.AuthenticationNotSupportedException;
55 import javax.naming.CommunicationException;
56 import javax.naming.InvalidNameException;
57 import javax.naming.NamingException;
58 import javax.naming.NoPermissionException;
59 import javax.naming.ServiceUnavailableException;
60 import javax.ws.rs.core.Response;
61 import java.util.ArrayList;
62 import java.util.Collection;
63 import java.util.Collections;
64 import java.util.Comparator;
65 import java.util.List;
66 import java.util.Map;
67 import java.util.Properties;
68 import java.util.ResourceBundle;
69 import java.util.function.Predicate;
70 import java.util.stream.Collectors;
71
72 import static org.apache.archiva.rest.services.v2.ErrorKeys.INVALID_RESULT_SET_ERROR;
73 import static org.apache.archiva.rest.services.v2.ErrorKeys.REPOSITORY_ADMIN_ERROR;
74
75 /**
76  * @author Martin Stockhammer <martin_s@apache.org>
77  */
78 @Service( "v2.defaultSecurityConfigurationService" )
79 public class DefaultSecurityConfigurationService implements SecurityConfigurationService
80 {
81     private static final Logger log = LoggerFactory.getLogger( DefaultSecurityConfigurationService.class );
82
83     private static final String[] KNOWN_LDAP_CONTEXT_PROVIDERS = {"com.sun.jndi.ldap.LdapCtxFactory","com.ibm.jndi.LDAPCtxFactory"};
84     private final List<String> availableContextProviders = new ArrayList<>( );
85
86     private static final QueryHelper<PropertyEntry> PROP_QUERY_HELPER = new QueryHelper<>( new String[]{"key"} );
87
88     static
89     {
90         PROP_QUERY_HELPER.addStringFilter( "key", PropertyEntry::getKey );
91         PROP_QUERY_HELPER.addStringFilter( "value", PropertyEntry::getValue );
92         PROP_QUERY_HELPER.addNullsafeFieldComparator( "key", PropertyEntry::getKey );
93         PROP_QUERY_HELPER.addNullsafeFieldComparator( "value", PropertyEntry::getValue );
94
95     }
96
97     private ResourceBundle bundle;
98
99
100     @Inject
101     private RedbackRuntimeConfigurationAdmin redbackRuntimeConfigurationAdmin;
102
103     @Inject
104     private ApplicationContext applicationContext;
105
106     @Inject
107     @Named( value = "userManager#default" )
108     private UserManager userManager;
109
110     @Inject
111     @Named( value = "rbacManager#default" )
112     private RBACManager rbacManager;
113
114     @Inject
115     private RoleManager roleManager;
116
117     @Inject
118     @Named( value = "ldapConnectionFactory#configurable" )
119     private LdapConnectionFactory ldapConnectionFactory;
120
121     @Inject
122     private LdapUserMapper ldapUserMapper;
123
124
125     @PostConstruct
126     void init( )
127     {
128         bundle = ResourceBundle.getBundle( "org.apache.archiva.rest.RestBundle" );
129         for (String ldapClass : KNOWN_LDAP_CONTEXT_PROVIDERS) {
130             if (isContextFactoryAvailable( ldapClass )) {
131                 availableContextProviders.add( ldapClass );
132             }
133         }
134     }
135
136     @Override
137     public SecurityConfiguration getConfiguration( ) throws ArchivaRestServiceException
138     {
139         try
140         {
141             RedbackRuntimeConfiguration redbackRuntimeConfiguration =
142                 redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
143
144             log.debug( "getRedbackRuntimeConfiguration -> {}", redbackRuntimeConfiguration );
145
146             return SecurityConfiguration.ofRedbackConfiguration( redbackRuntimeConfiguration );
147         }
148         catch ( RepositoryAdminException e )
149         {
150             throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR ) );
151         }
152     }
153
154     private void updateConfig( SecurityConfiguration newConfig, RedbackRuntimeConfiguration rbConfig )
155     {
156         rbConfig.setUserManagerImpls( newConfig.getActiveUserManagers( ) );
157         rbConfig.setRbacManagerImpls( newConfig.getActiveRbacManagers( ) );
158         rbConfig.setUseUsersCache( newConfig.isUserCacheEnabled( ) );
159         Map<String, String> props = rbConfig.getConfigurationProperties( );
160         for ( Map.Entry<String, String> newProp : newConfig.getProperties( ).entrySet( ) )
161         {
162             props.put( newProp.getKey( ), newProp.getValue( ) );
163         }
164     }
165
166     private void updateConfig( LdapConfiguration newConfig, RedbackRuntimeConfiguration rbConfig )
167     {
168         org.apache.archiva.admin.model.beans.LdapConfiguration ldapConfig = rbConfig.getLdapConfiguration( );
169         ldapConfig.setBaseDn( newConfig.getBaseDn( ) );
170         ldapConfig.setAuthenticationMethod( newConfig.getAuthenticationMethod( ) );
171         ldapConfig.setBindAuthenticatorEnabled( newConfig.isBindAuthenticatorEnabled( ) );
172         ldapConfig.setBindDn( newConfig.getBindDn( ) );
173         ldapConfig.setSsl( newConfig.isSslEnabled( ) );
174         ldapConfig.setBaseGroupsDn( newConfig.getGroupsBaseDn( ) );
175         ldapConfig.setHostName( newConfig.getHostName( ) );
176         ldapConfig.setPort( newConfig.getPort( ) );
177         ldapConfig.setPassword( newConfig.getBindPassword( ) );
178         ldapConfig.setUseRoleNameAsGroup( newConfig.isUseRoleNameAsGroup( ) );
179         ldapConfig.setWritable( newConfig.isWritable( ) );
180         ldapConfig.setContextFactory( newConfig.getContextFactory( ) );
181
182         Map<String, String> props = ldapConfig.getExtraProperties( );
183         for ( Map.Entry<String, String> newProp : newConfig.getProperties( ).entrySet( ) )
184         {
185             props.put( newProp.getKey( ), newProp.getValue( ) );
186         }
187     }
188
189     private void updateConfig( CacheConfiguration newConfig, RedbackRuntimeConfiguration rbConfig )
190     {
191         org.apache.archiva.admin.model.beans.CacheConfiguration cacheConfig = rbConfig.getUsersCacheConfiguration( );
192         cacheConfig.setMaxElementsInMemory( newConfig.getMaxEntriesInMemory( ) );
193         cacheConfig.setMaxElementsOnDisk( newConfig.getMaxEntriesOnDisk( ) );
194         cacheConfig.setTimeToLiveSeconds( newConfig.getTimeToLiveSeconds( ) );
195         cacheConfig.setTimeToIdleSeconds( newConfig.getTimeToIdleSeconds( ) );
196     }
197
198     @Override
199     public SecurityConfiguration updateConfiguration( SecurityConfiguration newConfiguration ) throws ArchivaRestServiceException
200     {
201         if ( newConfiguration == null )
202         {
203             throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.MISSING_DATA ), 400 );
204         }
205         try
206         {
207             RedbackRuntimeConfiguration conf = redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
208             boolean userManagerChanged = !CollectionUtils.isEqualCollection( newConfiguration.getActiveUserManagers( ), conf.getUserManagerImpls( ) );
209             boolean rbacManagerChanged = !CollectionUtils.isEqualCollection( newConfiguration.getActiveRbacManagers( ), conf.getRbacManagerImpls( ) );
210
211             boolean ldapConfigured = newConfiguration.getActiveUserManagers( ).stream( ).anyMatch( um -> um.contains( "ldap" ) );
212             if ( !ldapConfigured )
213             {
214                 ldapConfigured= newConfiguration.getActiveRbacManagers( ).stream( ).anyMatch( um -> um.contains( "ldap" ) );
215             }
216
217             updateConfig( newConfiguration, conf );
218             redbackRuntimeConfigurationAdmin.updateRedbackRuntimeConfiguration( conf );
219
220             if ( userManagerChanged )
221             {
222                 log.info( "user managerImpls changed to {} so reload it",
223                     newConfiguration.getActiveUserManagers( ) );
224                 userManager.initialize( );
225             }
226
227             if ( rbacManagerChanged )
228             {
229                 log.info( "rbac manager changed to {} so reload it",
230                     newConfiguration.getActiveRbacManagers( ) );
231                 rbacManager.initialize( );
232                 roleManager.initialize( );
233             }
234
235             if ( ldapConfigured )
236             {
237                 try
238                 {
239                     ldapConnectionFactory.initialize( );
240                 }
241                 catch ( Exception e )
242                 {
243                     log.error( "Could not initialize LDAP connection factory: {}", e.getMessage( ) );
244                     throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_CF_INIT_FAILED, e.getMessage( ) ) );
245                 }
246             }
247             Collection<PasswordRule> passwordRules = applicationContext.getBeansOfType( PasswordRule.class ).values( );
248
249             for ( PasswordRule passwordRule : passwordRules )
250             {
251                 passwordRule.initialize( );
252             }
253
254             Collection<CookieSettings> cookieSettingsList =
255                 applicationContext.getBeansOfType( CookieSettings.class ).values( );
256
257             for ( CookieSettings cookieSettings : cookieSettingsList )
258             {
259                 cookieSettings.initialize( );
260             }
261
262             Collection<Authenticator> authenticators =
263                 applicationContext.getBeansOfType( Authenticator.class ).values( );
264
265             for ( Authenticator authenticator : authenticators )
266             {
267                 try
268                 {
269                     log.debug( "Initializing authenticatior " + authenticator.getId( ) );
270                     authenticator.initialize( );
271                 }
272                 catch ( Exception e )
273                 {
274                     log.error( "Initialization of authenticator failed " + authenticator.getId( ), e );
275                 }
276             }
277
278             if ( ldapConfigured )
279             {
280                 try
281                 {
282                     ldapUserMapper.initialize( );
283                 }
284                 catch ( Exception e )
285                 {
286                     throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_USER_MAPPER_INIT_FAILED, e.getMessage( ) ) );
287                 }
288             }
289         }
290         catch ( RepositoryAdminException e )
291         {
292             throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) );
293         }
294         try
295         {
296             return SecurityConfiguration.ofRedbackConfiguration( redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( ) );
297         }
298         catch ( RepositoryAdminException e )
299         {
300             log.error( "Error while retrieve updated configuration: {}", e.getMessage( ) );
301             throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) );
302         }
303     }
304
305     @Override
306     public PagedResult<PropertyEntry> getConfigurationProperties( String searchTerm, Integer offset, Integer limit, List<String> orderBy, String order ) throws ArchivaRestServiceException
307     {
308         try
309         {
310             RedbackRuntimeConfiguration redbackRuntimeConfiguration =
311                 redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
312
313             log.debug( "getRedbackRuntimeConfiguration -> {}", redbackRuntimeConfiguration );
314
315             boolean ascending = PROP_QUERY_HELPER.isAscending( order );
316             Predicate<PropertyEntry> filter = PROP_QUERY_HELPER.getQueryFilter( searchTerm );
317             Comparator<PropertyEntry> comparator = PROP_QUERY_HELPER.getComparator( orderBy, ascending );
318             Map<String, String> props = redbackRuntimeConfiguration.getConfigurationProperties( );
319             int totalCount = Math.toIntExact( props.entrySet( ).stream( ).map(
320                 entry -> new PropertyEntry( entry.getKey( ), entry.getValue( ) )
321             ).filter( filter ).count( ) );
322             List<PropertyEntry> result = props.entrySet( ).stream( ).map(
323                 entry -> new PropertyEntry( entry.getKey( ), entry.getValue( ) )
324             ).filter( filter )
325                 .sorted( comparator )
326                 .skip( offset ).limit( limit )
327                 .collect( Collectors.toList( ) );
328             return new PagedResult<>( totalCount, offset, limit, result );
329         } catch (ArithmeticException e) {
330             log.error( "The total count of the result properties is higher than max integer value!" );
331             throw new ArchivaRestServiceException( ErrorMessage.of( INVALID_RESULT_SET_ERROR ) );
332         }
333         catch ( RepositoryAdminException e )
334         {
335             throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR ) );
336         }
337     }
338
339     @Override
340     public PropertyEntry getConfigurationProperty( String propertyName ) throws ArchivaRestServiceException
341     {
342         try
343         {
344             RedbackRuntimeConfiguration conf = redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
345             if ( conf.getConfigurationProperties( ).containsKey( propertyName ) )
346             {
347                 String value = conf.getConfigurationProperties( ).get( propertyName );
348                 return new PropertyEntry( propertyName, value );
349             }
350             else
351             {
352                 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.PROPERTY_NOT_FOUND ), 404 );
353             }
354
355         }
356         catch ( RepositoryAdminException e )
357         {
358             throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) );
359         }
360
361     }
362
363     @Override
364     public Response updateConfigurationProperty( String propertyName, PropertyEntry propertyValue ) throws ArchivaRestServiceException
365     {
366         if ( propertyValue == null )
367         {
368             throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.MISSING_DATA ), 400 );
369         }
370         try
371         {
372             RedbackRuntimeConfiguration conf = redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
373             if ( conf.getConfigurationProperties( ).containsKey( propertyName ) )
374             {
375                 conf.getConfigurationProperties( ).put( propertyName, propertyValue.getValue( ) );
376                 redbackRuntimeConfigurationAdmin.updateRedbackRuntimeConfiguration( conf );
377                 return Response.ok( ).build( );
378             }
379             else
380             {
381                 throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.PROPERTY_NOT_FOUND ), 404 );
382             }
383
384         }
385         catch ( RepositoryAdminException e )
386         {
387             throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) );
388         }
389     }
390
391     @Override
392     public LdapConfiguration getLdapConfiguration( ) throws ArchivaRestServiceException
393     {
394         try
395         {
396             RedbackRuntimeConfiguration redbackRuntimeConfiguration =
397                 redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
398
399             log.debug( "getRedbackRuntimeConfiguration -> {}", redbackRuntimeConfiguration );
400
401             LdapConfiguration ldapConfig = LdapConfiguration.of( redbackRuntimeConfiguration.getLdapConfiguration( ) );
402             ldapConfig.setAvailableContextFactories( availableContextProviders );
403             return ldapConfig;
404         }
405         catch ( RepositoryAdminException e )
406         {
407             throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR ) );
408         }
409
410     }
411
412     @Override
413     public LdapConfiguration updateLdapConfiguration( LdapConfiguration configuration ) throws ArchivaRestServiceException
414     {
415         try
416         {
417             RedbackRuntimeConfiguration redbackRuntimeConfiguration =
418                 redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
419
420             log.debug( "getRedbackRuntimeConfiguration -> {}", redbackRuntimeConfiguration );
421
422             updateConfig( configuration, redbackRuntimeConfiguration );
423
424             redbackRuntimeConfigurationAdmin.updateRedbackRuntimeConfiguration( redbackRuntimeConfiguration );
425             ldapConnectionFactory.initialize( );
426         }
427         catch ( RepositoryAdminException e )
428         {
429             throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR ) );
430         }
431
432         try
433         {
434             return LdapConfiguration.of( redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( ).getLdapConfiguration() );
435         }
436         catch ( RepositoryAdminException e )
437         {
438             log.error( "Error while retrieve updated configuration: {}", e.getMessage( ) );
439             throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) );
440         }
441
442     }
443
444     static Properties toProperties( Map<String, String> values )
445     {
446         Properties result = new Properties( );
447         for ( Map.Entry<String, String> entry : values.entrySet( ) )
448         {
449             result.setProperty( entry.getKey( ), entry.getValue( ) );
450         }
451         return result;
452     }
453
454     private static boolean isContextFactoryAvailable( final String factoryClass)
455     {
456         try
457         {
458             return Thread.currentThread().getContextClassLoader().loadClass( factoryClass )
459                 != null;
460         }
461         catch ( ClassNotFoundException e )
462         {
463             return false;
464         }
465     }
466
467
468     @Override
469     public Response verifyLdapConfiguration( LdapConfiguration ldapConfiguration ) throws ArchivaRestServiceException
470     {
471         LdapConnection ldapConnection = null;
472         try
473         {
474             LdapConnectionConfiguration ldapConnectionConfiguration =
475                 new LdapConnectionConfiguration( ldapConfiguration.getHostName( ), ldapConfiguration.getPort( ),
476                     ldapConfiguration.getBaseDn( ), ldapConfiguration.getContextFactory( ),
477                     ldapConfiguration.getBindDn( ), ldapConfiguration.getBindPassword( ),
478                     ldapConfiguration.getAuthenticationMethod( ),
479                     toProperties( ldapConfiguration.getProperties( ) ) );
480             ldapConnectionConfiguration.setSsl( ldapConfiguration.isSslEnabled( ) );
481
482             ldapConnection = ldapConnectionFactory.getConnection( ldapConnectionConfiguration );
483         }
484         catch ( InvalidNameException e )
485         {
486             log.warn( "LDAP connection check failed with invalid name : {}", e.getMessage( ), e );
487             throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_INVALID_NAME, e.getMessage( ) ), 400 );
488         }
489         catch ( LdapException e )
490         {
491             handleLdapException( e );
492         }
493         finally
494         {
495             if ( ldapConnection != null )
496             {
497                 try
498                 {
499                     ldapConnection.close( );
500                 }
501                 catch ( NamingException e )
502                 {
503                     log.error( "Could not close connection: {}", e.getMessage( ) );
504                 }
505             }
506             ldapConnection = null;
507         }
508
509         try
510         {
511             // verify groups dn value too
512
513             LdapConnectionConfiguration ldapConnectionConfiguration = new LdapConnectionConfiguration( ldapConfiguration.getHostName( ), ldapConfiguration.getPort( ),
514                 ldapConfiguration.getGroupsBaseDn( ),
515                 ldapConfiguration.getContextFactory( ), ldapConfiguration.getBindDn( ),
516                 ldapConfiguration.getBindPassword( ),
517                 ldapConfiguration.getAuthenticationMethod( ),
518                 toProperties( ldapConfiguration.getProperties( ) ) );
519
520             ldapConnectionConfiguration.setSsl( ldapConfiguration.isSslEnabled( ) );
521
522             ldapConnection = ldapConnectionFactory.getConnection( ldapConnectionConfiguration );
523         }
524         catch ( InvalidNameException e )
525         {
526             log.warn( "LDAP connection check failed with invalid name : {}", e.getMessage( ), e );
527             throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_INVALID_NAME, e.getMessage( ) ), 400 );
528         }
529         catch ( LdapException e )
530         {
531             handleLdapException( e );
532         }
533         finally
534         {
535             if ( ldapConnection != null )
536             {
537                 try
538                 {
539                     ldapConnection.close( );
540                 }
541                 catch ( NamingException e )
542                 {
543                     log.error( "Could not close connection: {}", e.getMessage( ), e );
544                 }
545             }
546         }
547
548         return Response.ok( ).build( );
549     }
550
551     private void handleLdapException( LdapException e ) throws ArchivaRestServiceException
552     {
553         Throwable rootCause = e.getRootCause( );
554         if ( rootCause instanceof CommunicationException )
555         {
556             log.warn( "LDAP connection check failed with CommunicationException: {}", e.getMessage( ), e );
557             throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_COMMUNICATION_ERROR, e.getMessage( ) ), 400 );
558         } else if (rootCause instanceof ServiceUnavailableException ) {
559             log.warn( "LDAP connection check failed with ServiceUnavailableException: {}", e.getMessage( ), e );
560             throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_SERVICE_UNAVAILABLE, e.getMessage( ) ), 400 );
561         } else if (rootCause instanceof AuthenticationException ) {
562             log.warn( "LDAP connection check failed with AuthenticationException: {}", e.getMessage( ), e );
563             throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_SERVICE_AUTHENTICATION_FAILED, e.getMessage( ) ), 400 );
564         } else if (rootCause instanceof AuthenticationNotSupportedException ) {
565             log.warn( "LDAP connection check failed with AuthenticationNotSupportedException: {}", e.getMessage( ), e );
566             throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_SERVICE_AUTHENTICATION_NOT_SUPPORTED, e.getMessage( ) ), 400 );
567         } else if (rootCause instanceof NoPermissionException ) {
568             log.warn( "LDAP connection check failed with NoPermissionException: {}", e.getMessage( ), e );
569             throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_SERVICE_NO_PERMISSION, e.getMessage( ) ), 400 );
570         }
571         log.warn( "LDAP connection check failed: {} - {}", e.getClass().getName(), e.getMessage( ), e );
572         throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.LDAP_GENERIC_ERROR, e.getMessage( ) ), 400 );
573     }
574
575     @Override
576     public CacheConfiguration getCacheConfiguration( ) throws ArchivaRestServiceException
577     {
578         try
579         {
580             RedbackRuntimeConfiguration redbackRuntimeConfiguration =
581                 redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
582
583             log.debug( "getRedbackRuntimeConfiguration -> {}", redbackRuntimeConfiguration );
584
585             return CacheConfiguration.of( redbackRuntimeConfiguration.getUsersCacheConfiguration( ) );
586         }
587         catch ( RepositoryAdminException e )
588         {
589             throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR ) );
590         }
591
592     }
593
594     @Override
595     public CacheConfiguration updateCacheConfiguration( CacheConfiguration cacheConfiguration ) throws ArchivaRestServiceException
596     {
597         if ( cacheConfiguration == null )
598         {
599             throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.MISSING_DATA ), 400 );
600         }
601         try
602         {
603             RedbackRuntimeConfiguration redbackRuntimeConfiguration =
604                 redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration( );
605
606             log.debug( "getRedbackRuntimeConfiguration -> {}", redbackRuntimeConfiguration );
607             updateConfig( cacheConfiguration, redbackRuntimeConfiguration );
608             redbackRuntimeConfigurationAdmin.updateRedbackRuntimeConfiguration( redbackRuntimeConfiguration );
609             return getCacheConfiguration( );
610         }
611         catch ( RepositoryAdminException e )
612         {
613             throw new ArchivaRestServiceException( ErrorMessage.of( REPOSITORY_ADMIN_ERROR ) );
614         }
615     }
616
617     @Override
618     public List<BeanInformation> getAvailableUserManagers( )
619     {
620         Map<String, UserManager> beans = applicationContext.getBeansOfType( UserManager.class );
621
622         if ( beans.isEmpty( ) )
623         {
624             return Collections.emptyList( );
625         }
626
627         return beans.entrySet( ).stream( )
628             .filter( entry -> entry.getValue( ).isFinalImplementation( ) )
629             .map( ( Map.Entry<String, UserManager> entry ) -> {
630                 UserManager um = entry.getValue( );
631                 String id = StringUtils.substringAfter( entry.getKey( ), "#" );
632                 String displayName = bundle.getString( "user_manager." + id + ".display_name" );
633                 String description = bundle.getString( "user_manager." + id + ".description" );
634                 return new BeanInformation( StringUtils.substringAfter( entry.getKey( ), "#" ), displayName, um.getDescriptionKey( ), description, um.isReadOnly( ) );
635             } ).collect( Collectors.toList( ) );
636     }
637
638     @Override
639     public List<BeanInformation> getAvailableRbacManagers( )
640     {
641         Map<String, RBACManager> beans = applicationContext.getBeansOfType( RBACManager.class );
642
643         if ( beans.isEmpty( ) )
644         {
645             return Collections.emptyList( );
646         }
647
648         return beans.entrySet( ).stream( )
649             .filter( entry -> entry.getValue( ).isFinalImplementation( ) )
650             .map( ( Map.Entry<String, RBACManager> entry ) -> {
651                 RBACManager rm = entry.getValue( );
652                 String id = StringUtils.substringAfter( entry.getKey( ), "#" );
653                 String displayName = bundle.getString( "rbac_manager." + id + ".display_name" );
654                 String description = bundle.getString( "rbac_manager." + id + ".description" );
655                 return new BeanInformation( StringUtils.substringAfter( entry.getKey( ), "#" ), displayName, rm.getDescriptionKey( ), description, rm.isReadOnly( ) );
656             } ).collect( Collectors.toList( ) );
657     }
658 }