package org.apache.archiva.rest.services; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.archiva.admin.model.RepositoryAdminException; import org.apache.archiva.admin.model.beans.LdapConfiguration; import org.apache.archiva.admin.model.beans.RedbackRuntimeConfiguration; import org.apache.archiva.admin.model.runtime.RedbackRuntimeConfigurationAdmin; import org.apache.archiva.redback.authentication.Authenticator; import org.apache.archiva.redback.common.ldap.connection.LdapConnection; import org.apache.archiva.redback.common.ldap.connection.LdapConnectionConfiguration; import org.apache.archiva.redback.common.ldap.connection.LdapConnectionFactory; import org.apache.archiva.redback.common.ldap.connection.LdapException; import org.apache.archiva.redback.common.ldap.user.LdapUserMapper; import org.apache.archiva.redback.components.cache.Cache; import org.apache.archiva.redback.policy.CookieSettings; import org.apache.archiva.redback.policy.PasswordRule; import org.apache.archiva.redback.rbac.RBACManager; import org.apache.archiva.redback.role.RoleManager; import org.apache.archiva.redback.users.UserManager; import org.apache.archiva.rest.api.model.RBACManagerImplementationInformation; import org.apache.archiva.rest.api.model.RedbackImplementationsInformations; import org.apache.archiva.rest.api.model.UserManagerImplementationInformation; import org.apache.archiva.rest.api.services.ArchivaRestServiceException; import org.apache.archiva.rest.api.services.RedbackRuntimeConfigurationService; import org.apache.commons.lang.StringUtils; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Service; import javax.inject.Inject; import javax.inject.Named; import javax.naming.InvalidNameException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Properties; /** * @author Olivier Lamy * @since 1.4-M4 */ @Service("redbackRuntimeConfigurationService#rest") public class DefaultRedbackRuntimeConfigurationService extends AbstractRestService implements RedbackRuntimeConfigurationService { @Inject private RedbackRuntimeConfigurationAdmin redbackRuntimeConfigurationAdmin; @Inject @Named(value = "userManager#configurable") private UserManager userManager; @Inject @Named(value = "rbacManager#default") private RBACManager rbacManager; @Inject private RoleManager roleManager; @Inject private ApplicationContext applicationContext; @Inject @Named(value = "ldapConnectionFactory#configurable") private LdapConnectionFactory ldapConnectionFactory; @Inject @Named(value = "cache#users") private Cache usersCache; @Inject private LdapUserMapper ldapUserMapper; @Override public RedbackRuntimeConfiguration getRedbackRuntimeConfiguration() throws ArchivaRestServiceException { try { RedbackRuntimeConfiguration redbackRuntimeConfiguration = redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration(); log.debug( "getRedbackRuntimeConfiguration -> {}", redbackRuntimeConfiguration ); return redbackRuntimeConfiguration; } catch ( RepositoryAdminException e ) { throw new ArchivaRestServiceException( e.getMessage(), e ); } } @Override public Boolean updateRedbackRuntimeConfiguration( RedbackRuntimeConfiguration redbackRuntimeConfiguration ) throws ArchivaRestServiceException { try { // has user manager impl changed ? boolean userManagerChanged = redbackRuntimeConfiguration.getUserManagerImpls().size() != redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration().getUserManagerImpls().size(); userManagerChanged = userManagerChanged || ( redbackRuntimeConfiguration.getUserManagerImpls().toString().hashCode() != redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration().getUserManagerImpls().toString().hashCode() ); boolean rbacManagerChanged = redbackRuntimeConfiguration.getRbacManagerImpls().size() != redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration().getRbacManagerImpls().size(); rbacManagerChanged = rbacManagerChanged || ( redbackRuntimeConfiguration.getRbacManagerImpls().toString().hashCode() != redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration().getRbacManagerImpls().toString().hashCode() ); boolean ldapConfigured = false; for (String um : redbackRuntimeConfiguration.getUserManagerImpls()) { if (um.contains("ldap")) { ldapConfigured=true; } } if (!ldapConfigured) { for (String rbm : redbackRuntimeConfiguration.getRbacManagerImpls()) { if (rbm.contains("ldap")) { ldapConfigured = true; } } } redbackRuntimeConfigurationAdmin.updateRedbackRuntimeConfiguration( redbackRuntimeConfiguration ); if ( userManagerChanged ) { log.info( "user managerImpls changed to {} so reload it", redbackRuntimeConfiguration.getUserManagerImpls() ); userManager.initialize(); } if ( rbacManagerChanged ) { log.info( "rbac manager changed to {} so reload it", redbackRuntimeConfiguration.getRbacManagerImpls() ); rbacManager.initialize(); roleManager.initialize(); } if (ldapConfigured) { try { ldapConnectionFactory.initialize(); } catch (Exception e) { ArchivaRestServiceException newEx = new ArchivaRestServiceException(e.getMessage(), e); newEx.setErrorKey("error.ldap.connectionFactory.init.failed"); throw newEx; } } Collection<PasswordRule> passwordRules = applicationContext.getBeansOfType( PasswordRule.class ).values(); for ( PasswordRule passwordRule : passwordRules ) { passwordRule.initialize(); } Collection<CookieSettings> cookieSettingsList = applicationContext.getBeansOfType( CookieSettings.class ).values(); for ( CookieSettings cookieSettings : cookieSettingsList ) { cookieSettings.initialize(); } Collection<Authenticator> authenticators = applicationContext.getBeansOfType( Authenticator.class ).values(); for ( Authenticator authenticator : authenticators ) { try { log.debug("Initializing authenticatior "+authenticator.getId()); authenticator.initialize(); } catch (Exception e) { log.error("Initialization of authenticator failed "+authenticator.getId(),e); } } // users cache usersCache.setTimeToIdleSeconds( redbackRuntimeConfiguration.getUsersCacheConfiguration().getTimeToIdleSeconds() ); usersCache.setTimeToLiveSeconds( redbackRuntimeConfiguration.getUsersCacheConfiguration().getTimeToLiveSeconds() ); usersCache.setMaxElementsInMemory( redbackRuntimeConfiguration.getUsersCacheConfiguration().getMaxElementsInMemory() ); usersCache.setMaxElementsOnDisk( redbackRuntimeConfiguration.getUsersCacheConfiguration().getMaxElementsOnDisk() ); if (ldapConfigured) { try { ldapUserMapper.initialize(); } catch (Exception e) { ArchivaRestServiceException newEx = new ArchivaRestServiceException(e.getMessage(), e); newEx.setErrorKey("error.ldap.userMapper.init.failed"); throw newEx; } } //check repositories roles are here !!! return Boolean.TRUE; } catch (ArchivaRestServiceException e) { log.error(e.getMessage(), e); throw e; } catch ( Exception e ) { log.error( e.getMessage(), e ); throw new ArchivaRestServiceException(e.getMessage(), e); } } @Override public List<UserManagerImplementationInformation> getUserManagerImplementationInformations() throws ArchivaRestServiceException { Map<String, UserManager> beans = applicationContext.getBeansOfType( UserManager.class ); if ( beans.isEmpty() ) { return Collections.emptyList(); } List<UserManagerImplementationInformation> informations = new ArrayList<>( beans.size() ); for ( Map.Entry<String, UserManager> entry : beans.entrySet() ) { UserManager userManager = applicationContext.getBean( entry.getKey(), UserManager.class ); if ( userManager.isFinalImplementation() ) { UserManagerImplementationInformation information = new UserManagerImplementationInformation(); information.setBeanId( StringUtils.substringAfter( entry.getKey(), "#" ) ); information.setDescriptionKey( userManager.getDescriptionKey() ); information.setReadOnly( userManager.isReadOnly() ); informations.add( information ); } } return informations; } @Override public List<RBACManagerImplementationInformation> getRbacManagerImplementationInformations() throws ArchivaRestServiceException { Map<String, RBACManager> beans = applicationContext.getBeansOfType( RBACManager.class ); if ( beans.isEmpty() ) { return Collections.emptyList(); } List<RBACManagerImplementationInformation> informations = new ArrayList<>( beans.size() ); for ( Map.Entry<String, RBACManager> entry : beans.entrySet() ) { RBACManager rbacManager = applicationContext.getBean( entry.getKey(), RBACManager.class ); if ( rbacManager.isFinalImplementation() ) { RBACManagerImplementationInformation information = new RBACManagerImplementationInformation(); information.setBeanId( StringUtils.substringAfter( entry.getKey(), "#" ) ); information.setDescriptionKey( rbacManager.getDescriptionKey() ); information.setReadOnly( rbacManager.isReadOnly() ); informations.add( information ); } } return informations; } @Override public RedbackImplementationsInformations getRedbackImplementationsInformations() throws ArchivaRestServiceException { return new RedbackImplementationsInformations( getUserManagerImplementationInformations(), getRbacManagerImplementationInformations() ); } @Override public Boolean checkLdapConnection() throws ArchivaRestServiceException { LdapConnection ldapConnection = null; try { ldapConnection = ldapConnectionFactory.getConnection(); } catch ( LdapException e ) { log.warn( "fail to get ldapConnection: {}", e.getMessage(), e ); throw new ArchivaRestServiceException( e.getMessage(), e ); } finally { if ( ldapConnection != null ) { ldapConnection.close(); } } return Boolean.TRUE; } @Override public Boolean checkLdapConnection( LdapConfiguration ldapConfiguration ) throws ArchivaRestServiceException { LdapConnection ldapConnection = null; try { LdapConnectionConfiguration ldapConnectionConfiguration = new LdapConnectionConfiguration( ldapConfiguration.getHostName(), ldapConfiguration.getPort(), ldapConfiguration.getBaseDn(), ldapConfiguration.getContextFactory(), ldapConfiguration.getBindDn(), ldapConfiguration.getPassword(), ldapConfiguration.getAuthenticationMethod(), toProperties( ldapConfiguration.getExtraProperties() ) ); ldapConnectionConfiguration.setSsl( ldapConfiguration.isSsl() ); ldapConnection = ldapConnectionFactory.getConnection( ldapConnectionConfiguration ); ldapConnection.close(); // verify groups dn value too ldapConnectionConfiguration = new LdapConnectionConfiguration( ldapConfiguration.getHostName(), ldapConfiguration.getPort(), ldapConfiguration.getBaseGroupsDn(), ldapConfiguration.getContextFactory(), ldapConfiguration.getBindDn(), ldapConfiguration.getPassword(), ldapConfiguration.getAuthenticationMethod(), toProperties( ldapConfiguration.getExtraProperties() ) ); ldapConnectionConfiguration.setSsl( ldapConfiguration.isSsl() ); ldapConnection = ldapConnectionFactory.getConnection( ldapConnectionConfiguration ); } catch ( InvalidNameException e ) { log.warn( "fail to get ldapConnection: {}", e.getMessage(), e ); throw new ArchivaRestServiceException( e.getMessage(), e ); } catch ( LdapException e ) { log.warn( "fail to get ldapConnection: {}", e.getMessage(), e ); throw new ArchivaRestServiceException( e.getMessage(), e ); } finally { if ( ldapConnection != null ) { ldapConnection.close(); } } return Boolean.TRUE; } private Properties toProperties( Map<String, String> map ) { Properties properties = new Properties(); if ( map == null || map.isEmpty() ) { return properties; } for ( Map.Entry<String, String> entry : map.entrySet() ) { properties.put( entry.getKey(), entry.getValue() ); } return properties; } }