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