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.redback.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.lang.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#configurable") 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 //check repositories roles are here !!! 224 225 return Boolean.TRUE; 226 } 227 catch (ArchivaRestServiceException e) { 228 log.error(e.getMessage(), e); 229 throw e; 230 } catch ( Exception e ) 231 { 232 log.error( e.getMessage(), e ); 233 throw new ArchivaRestServiceException(e.getMessage(), e); 234 } 235 } 236 237 @Override 238 public List<UserManagerImplementationInformation> getUserManagerImplementationInformations() 239 throws ArchivaRestServiceException 240 { 241 242 Map<String, UserManager> beans = applicationContext.getBeansOfType( UserManager.class ); 243 244 if ( beans.isEmpty() ) 245 { 246 return Collections.emptyList(); 247 } 248 249 List<UserManagerImplementationInformation> informations = new ArrayList<>( beans.size() ); 250 251 for ( Map.Entry<String, UserManager> entry : beans.entrySet() ) 252 { 253 UserManager userManager = applicationContext.getBean( entry.getKey(), UserManager.class ); 254 if ( userManager.isFinalImplementation() ) 255 { 256 UserManagerImplementationInformation information = new UserManagerImplementationInformation(); 257 information.setBeanId( StringUtils.substringAfter( entry.getKey(), "#" ) ); 258 information.setDescriptionKey( userManager.getDescriptionKey() ); 259 information.setReadOnly( userManager.isReadOnly() ); 260 informations.add( information ); 261 } 262 } 263 264 return informations; 265 } 266 267 @Override 268 public List<RBACManagerImplementationInformation> getRbacManagerImplementationInformations() 269 throws ArchivaRestServiceException 270 { 271 Map<String, RBACManager> beans = applicationContext.getBeansOfType( RBACManager.class ); 272 273 if ( beans.isEmpty() ) 274 { 275 return Collections.emptyList(); 276 } 277 278 List<RBACManagerImplementationInformation> informations = new ArrayList<>( beans.size() ); 279 280 for ( Map.Entry<String, RBACManager> entry : beans.entrySet() ) 281 { 282 RBACManager rbacManager = applicationContext.getBean( entry.getKey(), RBACManager.class ); 283 if ( rbacManager.isFinalImplementation() ) 284 { 285 RBACManagerImplementationInformation information = new RBACManagerImplementationInformation(); 286 information.setBeanId( StringUtils.substringAfter( entry.getKey(), "#" ) ); 287 information.setDescriptionKey( rbacManager.getDescriptionKey() ); 288 information.setReadOnly( rbacManager.isReadOnly() ); 289 informations.add( information ); 290 } 291 } 292 293 return informations; 294 } 295 296 @Override 297 public RedbackImplementationsInformations getRedbackImplementationsInformations() 298 throws ArchivaRestServiceException 299 { 300 return new RedbackImplementationsInformations( getUserManagerImplementationInformations(), 301 getRbacManagerImplementationInformations() ); 302 } 303 304 @Override 305 public Boolean checkLdapConnection() 306 throws ArchivaRestServiceException 307 { 308 LdapConnection ldapConnection = null; 309 try 310 { 311 ldapConnection = ldapConnectionFactory.getConnection(); 312 } 313 catch ( LdapException e ) 314 { 315 log.warn( "fail to get ldapConnection: {}", e.getMessage(), e ); 316 throw new ArchivaRestServiceException( e.getMessage(), e ); 317 } 318 finally 319 { 320 321 if ( ldapConnection != null ) 322 { 323 ldapConnection.close(); 324 } 325 } 326 327 return Boolean.TRUE; 328 } 329 330 @Override 331 public Boolean checkLdapConnection( LdapConfiguration ldapConfiguration ) 332 throws ArchivaRestServiceException 333 { 334 LdapConnection ldapConnection = null; 335 try 336 { 337 LdapConnectionConfiguration ldapConnectionConfiguration = 338 new LdapConnectionConfiguration( ldapConfiguration.getHostName(), ldapConfiguration.getPort(), 339 ldapConfiguration.getBaseDn(), ldapConfiguration.getContextFactory(), 340 ldapConfiguration.getBindDn(), ldapConfiguration.getPassword(), 341 ldapConfiguration.getAuthenticationMethod(), 342 toProperties( ldapConfiguration.getExtraProperties() ) ); 343 ldapConnectionConfiguration.setSsl( ldapConfiguration.isSsl() ); 344 345 ldapConnection = ldapConnectionFactory.getConnection( ldapConnectionConfiguration ); 346 347 ldapConnection.close(); 348 349 // verify groups dn value too 350 351 ldapConnectionConfiguration = 352 new LdapConnectionConfiguration( ldapConfiguration.getHostName(), ldapConfiguration.getPort(), 353 ldapConfiguration.getBaseGroupsDn(), 354 ldapConfiguration.getContextFactory(), ldapConfiguration.getBindDn(), 355 ldapConfiguration.getPassword(), 356 ldapConfiguration.getAuthenticationMethod(), 357 toProperties( ldapConfiguration.getExtraProperties() ) ); 358 359 ldapConnectionConfiguration.setSsl( ldapConfiguration.isSsl() ); 360 361 ldapConnection = ldapConnectionFactory.getConnection( ldapConnectionConfiguration ); 362 } 363 catch ( InvalidNameException e ) 364 { 365 log.warn( "fail to get ldapConnection: {}", e.getMessage(), e ); 366 throw new ArchivaRestServiceException( e.getMessage(), e ); 367 } 368 catch ( LdapException e ) 369 { 370 log.warn( "fail to get ldapConnection: {}", e.getMessage(), e ); 371 throw new ArchivaRestServiceException( e.getMessage(), e ); 372 } 373 finally 374 { 375 376 if ( ldapConnection != null ) 377 { 378 ldapConnection.close(); 379 } 380 } 381 382 return Boolean.TRUE; 383 } 384 385 private Properties toProperties( Map<String, String> map ) 386 { 387 Properties properties = new Properties(); 388 if ( map == null || map.isEmpty() ) 389 { 390 return properties; 391 } 392 for ( Map.Entry<String, String> entry : map.entrySet() ) 393 { 394 properties.put( entry.getKey(), entry.getValue() ); 395 } 396 return properties; 397 } 398 399} 400 401