You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DefaultSecurityConfigurationService.java 29KB

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