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