001package org.apache.archiva.rest.services; 002/* 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, 014 * software distributed under the License is distributed on an 015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 016 * KIND, either express or implied. See the License for the 017 * specific language governing permissions and limitations 018 * under the License. 019 */ 020 021import org.apache.archiva.admin.model.RepositoryAdminException; 022import org.apache.archiva.admin.model.beans.LdapConfiguration; 023import org.apache.archiva.admin.model.beans.RedbackRuntimeConfiguration; 024import org.apache.archiva.admin.model.runtime.RedbackRuntimeConfigurationAdmin; 025import org.apache.archiva.redback.authentication.Authenticator; 026import org.apache.archiva.redback.common.ldap.connection.LdapConnection; 027import org.apache.archiva.redback.common.ldap.connection.LdapConnectionConfiguration; 028import org.apache.archiva.redback.common.ldap.connection.LdapConnectionFactory; 029import org.apache.archiva.redback.common.ldap.connection.LdapException; 030import org.apache.archiva.redback.common.ldap.user.LdapUserMapper; 031import org.apache.archiva.components.cache.Cache; 032import org.apache.archiva.redback.policy.CookieSettings; 033import org.apache.archiva.redback.policy.PasswordRule; 034import org.apache.archiva.redback.rbac.RBACManager; 035import org.apache.archiva.redback.role.RoleManager; 036import org.apache.archiva.redback.users.UserManager; 037import org.apache.archiva.rest.api.model.RBACManagerImplementationInformation; 038import org.apache.archiva.rest.api.model.RedbackImplementationsInformations; 039import org.apache.archiva.rest.api.model.UserManagerImplementationInformation; 040import org.apache.archiva.rest.api.services.ArchivaRestServiceException; 041import org.apache.archiva.rest.api.services.RedbackRuntimeConfigurationService; 042import org.apache.commons.lang3.StringUtils; 043import org.springframework.context.ApplicationContext; 044import org.springframework.stereotype.Service; 045 046import javax.inject.Inject; 047import javax.inject.Named; 048import javax.naming.InvalidNameException; 049import java.util.ArrayList; 050import java.util.Collection; 051import java.util.Collections; 052import java.util.List; 053import java.util.Map; 054import java.util.Properties; 055 056/** 057 * @author Olivier Lamy 058 * @since 1.4-M4 059 */ 060@Service("redbackRuntimeConfigurationService#rest") 061public class DefaultRedbackRuntimeConfigurationService 062 extends AbstractRestService 063 implements RedbackRuntimeConfigurationService 064{ 065 066 @Inject 067 private RedbackRuntimeConfigurationAdmin redbackRuntimeConfigurationAdmin; 068 069 @Inject 070 @Named(value = "userManager#default") 071 private UserManager userManager; 072 073 @Inject 074 @Named(value = "rbacManager#default") 075 private RBACManager rbacManager; 076 077 @Inject 078 private RoleManager roleManager; 079 080 @Inject 081 private ApplicationContext applicationContext; 082 083 @Inject 084 @Named(value = "ldapConnectionFactory#configurable") 085 private LdapConnectionFactory ldapConnectionFactory; 086 087 @Inject 088 @Named(value = "cache#users") 089 private Cache usersCache; 090 091 @Inject 092 private LdapUserMapper ldapUserMapper; 093 094 095 @Override 096 public RedbackRuntimeConfiguration getRedbackRuntimeConfiguration() 097 throws ArchivaRestServiceException 098 { 099 try 100 { 101 RedbackRuntimeConfiguration redbackRuntimeConfiguration = 102 redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration(); 103 104 log.debug( "getRedbackRuntimeConfiguration -> {}", redbackRuntimeConfiguration ); 105 106 return redbackRuntimeConfiguration; 107 } 108 catch ( RepositoryAdminException e ) 109 { 110 throw new ArchivaRestServiceException( e.getMessage(), e ); 111 } 112 } 113 114 @Override 115 public Boolean updateRedbackRuntimeConfiguration( RedbackRuntimeConfiguration redbackRuntimeConfiguration ) 116 throws ArchivaRestServiceException 117 { 118 try 119 { 120 // has user manager impl changed ? 121 boolean userManagerChanged = redbackRuntimeConfiguration.getUserManagerImpls().size() 122 != redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration().getUserManagerImpls().size(); 123 124 userManagerChanged = 125 userManagerChanged || ( redbackRuntimeConfiguration.getUserManagerImpls().toString().hashCode() 126 != redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration().getUserManagerImpls().toString().hashCode() ); 127 128 boolean rbacManagerChanged = redbackRuntimeConfiguration.getRbacManagerImpls().size() 129 != redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration().getRbacManagerImpls().size(); 130 131 rbacManagerChanged = 132 rbacManagerChanged || ( redbackRuntimeConfiguration.getRbacManagerImpls().toString().hashCode() 133 != redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration().getRbacManagerImpls().toString().hashCode() ); 134 135 boolean ldapConfigured = false; 136 for (String um : redbackRuntimeConfiguration.getUserManagerImpls()) { 137 if (um.contains("ldap")) { 138 ldapConfigured=true; 139 } 140 } 141 if (!ldapConfigured) { 142 for (String rbm : redbackRuntimeConfiguration.getRbacManagerImpls()) { 143 if (rbm.contains("ldap")) { 144 ldapConfigured = true; 145 } 146 } 147 } 148 149 redbackRuntimeConfigurationAdmin.updateRedbackRuntimeConfiguration( redbackRuntimeConfiguration ); 150 151 if ( userManagerChanged ) 152 { 153 log.info( "user managerImpls changed to {} so reload it", 154 redbackRuntimeConfiguration.getUserManagerImpls() ); 155 userManager.initialize(); 156 } 157 158 if ( rbacManagerChanged ) 159 { 160 log.info( "rbac manager changed to {} so reload it", 161 redbackRuntimeConfiguration.getRbacManagerImpls() ); 162 rbacManager.initialize(); 163 roleManager.initialize(); 164 } 165 166 if (ldapConfigured) { 167 try { 168 ldapConnectionFactory.initialize(); 169 } catch (Exception e) { 170 ArchivaRestServiceException newEx = new ArchivaRestServiceException(e.getMessage(), e); 171 newEx.setErrorKey("error.ldap.connectionFactory.init.failed"); 172 throw newEx; 173 } 174 } 175 Collection<PasswordRule> passwordRules = applicationContext.getBeansOfType( PasswordRule.class ).values(); 176 177 for ( PasswordRule passwordRule : passwordRules ) 178 { 179 passwordRule.initialize(); 180 } 181 182 Collection<CookieSettings> cookieSettingsList = 183 applicationContext.getBeansOfType( CookieSettings.class ).values(); 184 185 for ( CookieSettings cookieSettings : cookieSettingsList ) 186 { 187 cookieSettings.initialize(); 188 } 189 190 Collection<Authenticator> authenticators = 191 applicationContext.getBeansOfType( Authenticator.class ).values(); 192 193 for ( Authenticator authenticator : authenticators ) 194 { 195 try { 196 log.debug("Initializing authenticatior "+authenticator.getId()); 197 authenticator.initialize(); 198 } catch (Exception e) { 199 log.error("Initialization of authenticator failed "+authenticator.getId(),e); 200 } 201 } 202 203 // users cache 204 usersCache.setTimeToIdleSeconds( 205 redbackRuntimeConfiguration.getUsersCacheConfiguration().getTimeToIdleSeconds() ); 206 usersCache.setTimeToLiveSeconds( 207 redbackRuntimeConfiguration.getUsersCacheConfiguration().getTimeToLiveSeconds() ); 208 usersCache.setMaxElementsInMemory( 209 redbackRuntimeConfiguration.getUsersCacheConfiguration().getMaxElementsInMemory() ); 210 usersCache.setMaxElementsOnDisk( 211 redbackRuntimeConfiguration.getUsersCacheConfiguration().getMaxElementsOnDisk() ); 212 213 if (ldapConfigured) { 214 try { 215 ldapUserMapper.initialize(); 216 } catch (Exception e) { 217 ArchivaRestServiceException newEx = new ArchivaRestServiceException(e.getMessage(), e); 218 newEx.setErrorKey("error.ldap.userMapper.init.failed"); 219 throw newEx; 220 } 221 } 222 223 224 225 226 return Boolean.TRUE; 227 } 228 catch (ArchivaRestServiceException e) { 229 log.error(e.getMessage(), e); 230 throw e; 231 } catch ( Exception e ) 232 { 233 log.error( e.getMessage(), e ); 234 throw new ArchivaRestServiceException(e.getMessage(), e); 235 } 236 } 237 238 @Override 239 public List<UserManagerImplementationInformation> getUserManagerImplementationInformations() 240 throws ArchivaRestServiceException 241 { 242 243 Map<String, UserManager> beans = applicationContext.getBeansOfType( UserManager.class ); 244 245 if ( beans.isEmpty() ) 246 { 247 return Collections.emptyList(); 248 } 249 250 List<UserManagerImplementationInformation> informations = new ArrayList<>( beans.size() ); 251 252 for ( Map.Entry<String, UserManager> entry : beans.entrySet() ) 253 { 254 UserManager userManager = applicationContext.getBean( entry.getKey(), UserManager.class ); 255 if ( userManager.isFinalImplementation() ) 256 { 257 UserManagerImplementationInformation information = new UserManagerImplementationInformation(); 258 information.setBeanId( StringUtils.substringAfter( entry.getKey(), "#" ) ); 259 information.setDescriptionKey( userManager.getDescriptionKey() ); 260 information.setReadOnly( userManager.isReadOnly() ); 261 informations.add( information ); 262 } 263 } 264 265 return informations; 266 } 267 268 @Override 269 public List<RBACManagerImplementationInformation> getRbacManagerImplementationInformations() 270 throws ArchivaRestServiceException 271 { 272 Map<String, RBACManager> beans = applicationContext.getBeansOfType( RBACManager.class ); 273 274 if ( beans.isEmpty() ) 275 { 276 return Collections.emptyList(); 277 } 278 279 List<RBACManagerImplementationInformation> informations = new ArrayList<>( beans.size() ); 280 281 for ( Map.Entry<String, RBACManager> entry : beans.entrySet() ) 282 { 283 RBACManager rbacManager = applicationContext.getBean( entry.getKey(), RBACManager.class ); 284 if ( rbacManager.isFinalImplementation() ) 285 { 286 RBACManagerImplementationInformation information = new RBACManagerImplementationInformation(); 287 information.setBeanId( StringUtils.substringAfter( entry.getKey(), "#" ) ); 288 information.setDescriptionKey( rbacManager.getDescriptionKey() ); 289 information.setReadOnly( rbacManager.isReadOnly() ); 290 informations.add( information ); 291 } 292 } 293 294 return informations; 295 } 296 297 @Override 298 public RedbackImplementationsInformations getRedbackImplementationsInformations() 299 throws ArchivaRestServiceException 300 { 301 return new RedbackImplementationsInformations( getUserManagerImplementationInformations(), 302 getRbacManagerImplementationInformations() ); 303 } 304 305 @Override 306 public Boolean checkLdapConnection() 307 throws ArchivaRestServiceException 308 { 309 LdapConnection ldapConnection = null; 310 try 311 { 312 ldapConnection = ldapConnectionFactory.getConnection(); 313 } 314 catch ( LdapException e ) 315 { 316 log.warn( "fail to get ldapConnection: {}", e.getMessage(), e ); 317 throw new ArchivaRestServiceException( e.getMessage(), e ); 318 } 319 finally 320 { 321 322 if ( ldapConnection != null ) 323 { 324 ldapConnection.close(); 325 } 326 } 327 328 return Boolean.TRUE; 329 } 330 331 @Override 332 public Boolean checkLdapConnection( LdapConfiguration ldapConfiguration ) 333 throws ArchivaRestServiceException 334 { 335 LdapConnection ldapConnection = null; 336 try 337 { 338 LdapConnectionConfiguration ldapConnectionConfiguration = 339 new LdapConnectionConfiguration( ldapConfiguration.getHostName(), ldapConfiguration.getPort(), 340 ldapConfiguration.getBaseDn(), ldapConfiguration.getContextFactory(), 341 ldapConfiguration.getBindDn(), ldapConfiguration.getPassword(), 342 ldapConfiguration.getAuthenticationMethod(), 343 toProperties( ldapConfiguration.getExtraProperties() ) ); 344 ldapConnectionConfiguration.setSsl( ldapConfiguration.isSsl() ); 345 346 ldapConnection = ldapConnectionFactory.getConnection( ldapConnectionConfiguration ); 347 348 ldapConnection.close(); 349 350 // verify groups dn value too 351 352 ldapConnectionConfiguration = 353 new LdapConnectionConfiguration( ldapConfiguration.getHostName(), ldapConfiguration.getPort(), 354 ldapConfiguration.getBaseGroupsDn(), 355 ldapConfiguration.getContextFactory(), ldapConfiguration.getBindDn(), 356 ldapConfiguration.getPassword(), 357 ldapConfiguration.getAuthenticationMethod(), 358 toProperties( ldapConfiguration.getExtraProperties() ) ); 359 360 ldapConnectionConfiguration.setSsl( ldapConfiguration.isSsl() ); 361 362 ldapConnection = ldapConnectionFactory.getConnection( ldapConnectionConfiguration ); 363 } 364 catch ( InvalidNameException e ) 365 { 366 log.warn( "fail to get ldapConnection: {}", e.getMessage(), e ); 367 throw new ArchivaRestServiceException( e.getMessage(), e ); 368 } 369 catch ( LdapException e ) 370 { 371 log.warn( "fail to get ldapConnection: {}", e.getMessage(), e ); 372 throw new ArchivaRestServiceException( e.getMessage(), e ); 373 } 374 finally 375 { 376 377 if ( ldapConnection != null ) 378 { 379 ldapConnection.close(); 380 } 381 } 382 383 return Boolean.TRUE; 384 } 385 386 private Properties toProperties( Map<String, String> map ) 387 { 388 Properties properties = new Properties(); 389 if ( map == null || map.isEmpty() ) 390 { 391 return properties; 392 } 393 for ( Map.Entry<String, String> entry : map.entrySet() ) 394 { 395 properties.put( entry.getKey(), entry.getValue() ); 396 } 397 return properties; 398 } 399 400} 401 402