001package org.apache.archiva.web.security; 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.runtime.RedbackRuntimeConfigurationAdmin; 023import org.apache.archiva.components.cache.Cache; 024import org.apache.archiva.redback.users.AbstractUserManager; 025import org.apache.archiva.redback.users.User; 026import org.apache.archiva.redback.users.UserManager; 027import org.apache.archiva.redback.users.UserManagerException; 028import org.apache.archiva.redback.users.UserNotFoundException; 029import org.apache.archiva.redback.users.UserQuery; 030import org.springframework.context.ApplicationContext; 031import org.springframework.stereotype.Service; 032 033import javax.annotation.PostConstruct; 034import javax.inject.Inject; 035import javax.inject.Named; 036import java.util.ArrayList; 037import java.util.LinkedHashMap; 038import java.util.List; 039import java.util.Map; 040 041/** 042 * @author Olivier Lamy 043 * @since 1.4-M4 044 */ 045@Service("userManager#archiva") 046public class ArchivaConfigurableUsersManager 047 extends AbstractUserManager 048{ 049 050 @Inject 051 private RedbackRuntimeConfigurationAdmin redbackRuntimeConfigurationAdmin; 052 053 @Inject 054 private ApplicationContext applicationContext; 055 056 private Map<String, UserManager> userManagerPerId; 057 058 @Inject 059 @Named(value = "cache#users") 060 private Cache<String, User> usersCache; 061 062 private boolean useUsersCache; 063 064 @PostConstruct 065 @Override 066 public void initialize() 067 { 068 try 069 { 070 List<String> userManagerImpls = 071 redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration().getUserManagerImpls(); 072 log.info( "use userManagerImpls: '{}'", userManagerImpls ); 073 074 userManagerPerId = new LinkedHashMap<>( userManagerImpls.size() ); 075 for ( String id : userManagerImpls ) 076 { 077 UserManager userManagerImpl = applicationContext.getBean( "userManager#" + id, UserManager.class ); 078 setUserManagerImpl( userManagerImpl ); 079 userManagerPerId.put( id, userManagerImpl ); 080 } 081 this.usersCache.clear(); 082 this.useUsersCache = redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration().isUseUsersCache(); 083 } 084 catch ( RepositoryAdminException e ) 085 { 086 // revert to a default one ? 087 log.error( e.getMessage(), e ); 088 throw new RuntimeException( e.getMessage(), e ); 089 } 090 } 091 092 protected boolean useUsersCache() 093 { 094 return this.useUsersCache; 095 } 096 097 @Override 098 public User addUser( User user ) 099 throws UserManagerException 100 { 101 user = userManagerPerId.get( user.getUserManagerId() ).addUser( user ); 102 103 if ( useUsersCache() ) 104 { 105 usersCache.put( user.getUsername(), user ); 106 } 107 108 return user; 109 } 110 111 @Override 112 public void addUserUnchecked( User user ) 113 throws UserManagerException 114 { 115 userManagerPerId.get( user.getUserManagerId() ).addUserUnchecked( user ); 116 117 if ( useUsersCache() ) 118 { 119 usersCache.put( user.getUsername(), user ); 120 } 121 } 122 123 @Override 124 public User createUser( String username, String fullName, String emailAddress ) 125 throws UserManagerException 126 { 127 Exception lastException = null; 128 boolean allFailed = true; 129 User user = null; 130 for ( UserManager userManager : userManagerPerId.values() ) 131 { 132 try 133 { 134 if ( !userManager.isReadOnly() ) 135 { 136 user = userManager.createUser( username, fullName, emailAddress ); 137 allFailed = false; 138 } 139 } 140 catch ( Exception e ) 141 { 142 lastException = e; 143 } 144 } 145 if ( lastException != null && allFailed ) 146 { 147 throw new UserManagerException( lastException.getMessage(), lastException ); 148 } 149 return user; 150 } 151 152 @Override 153 public UserQuery createUserQuery() 154 { 155 return userManagerPerId.values().iterator().next().createUserQuery(); 156 } 157 158 159 @Override 160 public void deleteUser( String username ) 161 throws UserNotFoundException, UserManagerException 162 { 163 Exception lastException = null; 164 boolean allFailed = true; 165 User user = null; 166 for ( UserManager userManager : userManagerPerId.values() ) 167 { 168 try 169 { 170 if ( !userManager.isReadOnly() ) 171 { 172 userManager.deleteUser( username ); 173 allFailed = false; 174 } 175 } 176 catch ( Exception e ) 177 { 178 lastException = e; 179 } 180 } 181 if ( lastException != null && allFailed ) 182 { 183 throw new UserManagerException( lastException.getMessage(), lastException ); 184 } 185 } 186 187 @Override 188 public void eraseDatabase() 189 { 190 for ( UserManager userManager : userManagerPerId.values() ) 191 { 192 userManager.eraseDatabase(); 193 } 194 } 195 196 @Override 197 public User findUser( String username, boolean useCache ) 198 throws UserNotFoundException, UserManagerException 199 { 200 User user = null; 201 if ( useUsersCache() && useCache ) 202 { 203 user = usersCache.get( username ); 204 if ( user != null ) 205 { 206 return user; 207 } 208 209 } 210 Exception lastException = null; 211 for ( UserManager userManager : userManagerPerId.values() ) 212 { 213 try 214 { 215 user = userManager.findUser( username ); 216 if ( user != null ) 217 { 218 if ( useUsersCache() ) 219 { 220 usersCache.put( username, user ); 221 } 222 return user; 223 } 224 } 225 catch ( UserNotFoundException e ) 226 { 227 lastException = e; 228 } 229 catch ( Exception e ) 230 { 231 lastException = e; 232 } 233 } 234 235 if ( user == null ) 236 { 237 if ( lastException != null ) 238 { 239 if ( lastException instanceof UserNotFoundException ) 240 { 241 throw (UserNotFoundException) lastException; 242 } 243 throw new UserManagerException( lastException.getMessage(), lastException ); 244 } 245 } 246 247 return user; 248 } 249 250 @Override 251 public User findUser( String username ) 252 throws UserManagerException 253 { 254 return findUser( username, useUsersCache() ); 255 } 256 257 258 @Override 259 public User getGuestUser() 260 throws UserNotFoundException, UserManagerException 261 { 262 return findUser( GUEST_USERNAME ); 263 } 264 265 @Override 266 public List<User> findUsersByEmailKey( String emailKey, boolean orderAscending ) 267 throws UserManagerException 268 { 269 List<User> users = new ArrayList<>(); 270 271 for ( UserManager userManager : userManagerPerId.values() ) 272 { 273 List<? extends User> found = userManager.findUsersByEmailKey( emailKey, orderAscending ); 274 if ( found != null ) 275 { 276 users.addAll( found ); 277 } 278 } 279 return users; 280 } 281 282 @Override 283 public List<User> findUsersByFullNameKey( String fullNameKey, boolean orderAscending ) 284 throws UserManagerException 285 { 286 List<User> users = new ArrayList<>(); 287 288 for ( UserManager userManager : userManagerPerId.values() ) 289 { 290 List<? extends User> found = userManager.findUsersByFullNameKey( fullNameKey, orderAscending ); 291 if ( found != null ) 292 { 293 users.addAll( found ); 294 } 295 } 296 return users; 297 } 298 299 @Override 300 public List<User> findUsersByQuery( UserQuery query ) 301 throws UserManagerException 302 { 303 List<User> users = new ArrayList<>(); 304 305 for ( UserManager userManager : userManagerPerId.values() ) 306 { 307 List<? extends User> found = userManager.findUsersByQuery( query ); 308 if ( found != null ) 309 { 310 users.addAll( found ); 311 } 312 } 313 return users; 314 } 315 316 @Override 317 public List<User> findUsersByUsernameKey( String usernameKey, boolean orderAscending ) 318 throws UserManagerException 319 { 320 List<User> users = new ArrayList<>(); 321 322 for ( UserManager userManager : userManagerPerId.values() ) 323 { 324 List<? extends User> found = userManager.findUsersByUsernameKey( usernameKey, orderAscending ); 325 if ( found != null ) 326 { 327 users.addAll( found ); 328 } 329 } 330 return users; 331 } 332 333 @Override 334 public String getId() 335 { 336 return "archiva-configurable"; 337 } 338 339 @Override 340 public List<User> getUsers() 341 throws UserManagerException 342 { 343 List<User> users = new ArrayList<>(); 344 345 for ( UserManager userManager : userManagerPerId.values() ) 346 { 347 List<? extends User> found = userManager.getUsers(); 348 if ( found != null ) 349 { 350 users.addAll( found ); 351 } 352 } 353 return users; 354 } 355 356 @Override 357 public List<User> getUsers( boolean orderAscending ) 358 throws UserManagerException 359 { 360 List<User> users = new ArrayList<>(); 361 362 for ( UserManager userManager : userManagerPerId.values() ) 363 { 364 List<? extends User> found = userManager.getUsers( orderAscending ); 365 if ( found != null ) 366 { 367 users.addAll( found ); 368 } 369 } 370 return users; 371 } 372 373 @Override 374 public boolean isReadOnly() 375 { 376 boolean readOnly = false; 377 378 for ( UserManager userManager : userManagerPerId.values() ) 379 { 380 readOnly = readOnly || userManager.isReadOnly(); 381 } 382 return readOnly; 383 } 384 385 @Override 386 public User updateUser( User user ) 387 throws UserNotFoundException, UserManagerException 388 { 389 390 UserManager userManager = userManagerPerId.get( user.getUserManagerId() ); 391 392 user = userManager.updateUser( user ); 393 394 if ( useUsersCache() ) 395 { 396 usersCache.put( user.getUsername(), user ); 397 } 398 399 return user; 400 } 401 402 @Override 403 public User updateUser( User user, boolean passwordChangeRequired ) 404 throws UserNotFoundException, UserManagerException 405 { 406 user = userManagerPerId.get( user.getUserManagerId() ).updateUser( user, passwordChangeRequired ); 407 408 if ( useUsersCache() ) 409 { 410 usersCache.put( user.getUsername(), user ); 411 } 412 413 return user; 414 } 415 416 public void setUserManagerImpl( UserManager userManagerImpl ) 417 { 418 // not possible here but we know so no need of log.error 419 log.debug( "setUserManagerImpl cannot be used in this implementation" ); 420 } 421 422 @Override 423 public User createGuestUser() 424 throws UserManagerException 425 { 426 Exception lastException = null; 427 boolean allFailed = true; 428 User user = null; 429 for ( UserManager userManager : userManagerPerId.values() ) 430 { 431 try 432 { 433 if ( !userManager.isReadOnly() ) 434 { 435 user = userManager.createGuestUser(); 436 allFailed = false; 437 } 438 } 439 catch ( Exception e ) 440 { 441 lastException = e; 442 } 443 } 444 if ( lastException != null && allFailed ) 445 { 446 throw new UserManagerException( lastException.getMessage(), lastException ); 447 } 448 return user; 449 } 450 451 452 @Override 453 public boolean userExists( String userName ) 454 throws UserManagerException 455 { 456 Exception lastException = null; 457 boolean allFailed = true; 458 boolean exists = false; 459 for ( UserManager userManager : userManagerPerId.values() ) 460 { 461 try 462 { 463 464 if ( userManager.userExists( userName ) ) 465 { 466 exists = true; 467 } 468 allFailed = false; 469 470 } 471 catch ( Exception e ) 472 { 473 lastException = e; 474 } 475 } 476 if ( lastException != null && allFailed ) 477 { 478 throw new UserManagerException( lastException.getMessage(), lastException ); 479 } 480 return exists; 481 } 482 483 484 @Override 485 public boolean isFinalImplementation() 486 { 487 return false; 488 } 489 490 @Override 491 public String getDescriptionKey() 492 { 493 return "archiva.redback.usermanager.configurable.archiva"; 494 } 495 496 497}