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