001/* 002 * Copyright 2016 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.core.user; 017 018import java.util.ArrayList; 019import java.util.Collection; 020import java.util.Collections; 021import java.util.List; 022import java.util.Map; 023import java.util.Set; 024import java.util.stream.Collectors; 025 026import org.apache.avalon.framework.component.Component; 027import org.apache.avalon.framework.service.ServiceException; 028import org.apache.avalon.framework.service.ServiceManager; 029import org.apache.avalon.framework.service.Serviceable; 030 031import org.ametys.core.user.directory.NotUniqueUserException; 032import org.ametys.core.user.directory.UserDirectory; 033import org.ametys.core.user.population.PopulationContextHelper; 034import org.ametys.core.user.population.UserPopulation; 035import org.ametys.core.user.population.UserPopulationDAO; 036import org.ametys.runtime.plugin.component.AbstractLogEnabled; 037 038/** 039 * Component for getting user list and verify the presence of a particular user on a context or for user directory(ies). 040 */ 041public class UserManager extends AbstractLogEnabled implements Component, Serviceable 042{ 043 /** Avalon Role */ 044 public static final String ROLE = UserManager.class.getName(); 045 046 /** The DAO for User Population */ 047 protected UserPopulationDAO _userPopulationDAO; 048 /** The helper for the associations population/context */ 049 protected PopulationContextHelper _populationContextHelper; 050 051 @Override 052 public void service(ServiceManager manager) throws ServiceException 053 { 054 _userPopulationDAO = (UserPopulationDAO) manager.lookup(UserPopulationDAO.ROLE); 055 _populationContextHelper = (PopulationContextHelper) manager.lookup(PopulationContextHelper.ROLE); 056 } 057 058 /** 059 * Get the list of users on some given contexts 060 * @param contexts The contexts 061 * @param checkRight True to check that current user belongs to one of populations on theses contexts or he's an administrator user 062 * @return the collection of users 063 */ 064 public Collection<User> getUsersByContext(Set<String> contexts, boolean checkRight) 065 { 066 List<UserPopulation> userPopulations = _populationContextHelper.getUserPopulationsOnContexts(contexts, false, checkRight).stream() 067 .map(upId -> _userPopulationDAO.getUserPopulation(upId)) 068 .collect(Collectors.toList()); 069 070 return getUsersByPopulations(userPopulations); 071 } 072 073 /** 074 * Get the users for given users' populations 075 * @param userPopulationIds the id of population of users 076 * @return the collection of users 077 */ 078 public Collection<User> getUsersByPopulationIds(List<String> userPopulationIds) 079 { 080 List<User> users = new ArrayList<>(); 081 for (String id : userPopulationIds) 082 { 083 UserPopulation userPopulation = _userPopulationDAO.getUserPopulation(id); 084 if (userPopulation != null) 085 { 086 for (User user : getUsers(userPopulation)) 087 { 088 if (!users.contains(user)) 089 { 090 users.add(user); 091 } 092 } 093 } 094 } 095 return users; 096 } 097 098 /** 099 * Get the users for given users' populations 100 * @param userPopulations the population of users 101 * @return the collection of users 102 */ 103 public Collection<User> getUsersByPopulations(List<UserPopulation> userPopulations) 104 { 105 List<User> users = new ArrayList<>(); 106 for (UserPopulation userPopulation : userPopulations) 107 { 108 for (User user : getUsers(userPopulation)) 109 { 110 if (!users.contains(user)) 111 { 112 users.add(user); 113 } 114 } 115 } 116 return users; 117 } 118 119 /** 120 * Gets all the users of a {@link UserPopulation} 121 * @param userPopulationId The ID of user population 122 * @return list of users as Collection of {@link User}s, empty if a problem occurs. 123 */ 124 public Collection<User> getUsers(String userPopulationId) 125 { 126 UserPopulation userPopulation = _userPopulationDAO.getUserPopulation(userPopulationId); 127 if (userPopulation != null) 128 { 129 return getUsers(userPopulation); 130 } 131 else 132 { 133 return Collections.EMPTY_LIST; 134 } 135 } 136 137 /** 138 * Gets all the users of a {@link UserPopulation} 139 * @param userPopulation The user population 140 * @return list of users as Collection of {@link User}s, empty if a problem occurs. 141 */ 142 public Collection<User> getUsers(UserPopulation userPopulation) 143 { 144 List<User> users = new ArrayList<>(); 145 146 for (UserDirectory ud : userPopulation.getUserDirectories()) 147 { 148 for (User user : ud.getUsers()) 149 { 150 if (!users.contains(user)) 151 { 152 users.add(user); 153 } 154 } 155 } 156 157 return users; 158 } 159 160 /** 161 * Get a list of users given the parameters 162 * @param contexts The contexts 163 * @param count The limit of users to retrieve 164 * @param offset The number of result to ignore before starting to collect users. 165 * @param parameters A map of additional parameters, see implementation. 166 * @param checkRight True to check that current user belongs to one of populations on theses contexts or he's an administrator user 167 * @return The list of retrieved {@link User} 168 */ 169 public List<User> getUsersByContext(Set<String> contexts, int count, int offset, Map<String, Object> parameters, boolean checkRight) 170 { 171 List<UserPopulation> userPopulations = _populationContextHelper.getUserPopulationsOnContexts(contexts, false, checkRight).stream() 172 .map(upId -> _userPopulationDAO.getUserPopulation(upId)) 173 .collect(Collectors.toList()); 174 175 return getUsers(userPopulations, count, offset, parameters); 176 } 177 178 /** 179 * Get a list of users given the parameters 180 * @param userPopulations the population of users 181 * @param count The limit of users to retrieve 182 * @param offset The number of result to ignore before starting to collect users. 183 * @param parameters A map of additional parameters, see implementation. 184 * @return The list of retrieved {@link User} 185 */ 186 public List<User> getUsers(List<UserPopulation> userPopulations, int count, int offset, Map<String, Object> parameters) 187 { 188 List<User> users = new ArrayList<>(); 189 for (UserPopulation userPopulation : userPopulations) 190 { 191 for (User user : getUsers(userPopulation, count + offset, 0, parameters)) 192 { 193 if (!users.contains(user)) 194 { 195 users.add(user); 196 } 197 } 198 } 199 200 int boundedCount = count >= 0 ? count : Integer.MAX_VALUE; 201 int boundedOffset = offset >= 0 ? offset : 0; 202 int toIndex; 203 if (boundedOffset + boundedCount >= 0) 204 { 205 toIndex = Math.min(boundedOffset + boundedCount, users.size()); 206 } 207 else 208 { 209 // particular case where count was initially negative (to say "no limit") and we set it to Integer.MAX_VALUE 210 // so if the offset is strictly positive, the sum overflows 211 toIndex = users.size(); 212 } 213 return users.subList(boundedOffset, toIndex); 214 } 215 216 /** 217 * Gets all the users of a {@link UserPopulation} 218 * @param userPopulationId The ID of user population 219 * @param count The limit of users to retrieve 220 * @param offset The number of result to ignore before starting to collect users. 221 * @param parameters A map of additional parameters, see implementation. 222 * @return list of users as Collection of {@link User}s, empty if a problem occurs. 223 */ 224 public Collection<User> getUsers(String userPopulationId, int count, int offset, Map<String, Object> parameters) 225 { 226 UserPopulation userPopulation = _userPopulationDAO.getUserPopulation(userPopulationId); 227 if (userPopulation != null) 228 { 229 return getUsers(userPopulation, count, offset, parameters); 230 } 231 else 232 { 233 return Collections.EMPTY_LIST; 234 } 235 } 236 237 /** 238 * Gets all the users of a given {@link UserPopulation} and {@link UserDirectory} 239 * @param userPopulationId The ID of user population 240 * @param userDirectoryId The id of the user directory 241 * @param count The limit of users to retrieve 242 * @param offset The number of result to ignore before starting to collect users. 243 * @param parameters A map of additional parameters, see implementation. 244 * @return list of users as Collection of {@link User}s, empty if a problem occurs. 245 */ 246 public Collection<User> getUsersByDirectory(String userPopulationId, String userDirectoryId, int count, int offset, Map<String, Object> parameters) 247 { 248 UserPopulation userPopulation = _userPopulationDAO.getUserPopulation(userPopulationId); 249 250 if (userPopulation == null) 251 { 252 return Collections.EMPTY_LIST; 253 } 254 255 UserDirectory ud = userPopulation.getUserDirectory(userDirectoryId); 256 if (ud == null) 257 { 258 throw new IllegalArgumentException("In the population '" + userPopulationId + "' the directory '" + userDirectoryId + "' was referenced but does not exists"); 259 } 260 return ud.getUsers(count, offset, parameters); 261 } 262 263 /** 264 * Gets all the users of a {@link UserPopulation} 265 * @param userPopulation The users population 266 * @param count The limit of users to retrieve 267 * @param offset The number of result to ignore before starting to collect users. 268 * @param parameters A map of additional parameters, see implementation. 269 * @return list of users as Collection of {@link User}s, empty if a problem occurs. 270 */ 271 public Collection<User> getUsers(UserPopulation userPopulation, int count, int offset, Map<String, Object> parameters) 272 { 273 List<User> users = new ArrayList<>(); 274 275 for (UserDirectory ud : userPopulation.getUserDirectories()) 276 { 277 for (User user : ud.getUsers(-1, 0, parameters)) 278 { 279 if (!users.contains(user)) 280 { 281 users.add(user); 282 } 283 } 284 } 285 286 int boundedCount = count >= 0 ? count : Integer.MAX_VALUE; 287 int boundedOffset = offset >= 0 ? offset : 0; 288 int toIndex; 289 if (boundedOffset + boundedCount >= 0) 290 { 291 toIndex = Math.min(boundedOffset + boundedCount, users.size()); 292 } 293 else 294 { 295 // particular case where count was initially negative (to say "no limit") and we set it to Integer.MAX_VALUE 296 // so if the offset is strictly positive, the sum overflows 297 toIndex = users.size(); 298 } 299 return users.subList(boundedOffset, toIndex); 300 } 301 302 /** 303 * Gets all the users of a {@link UserPopulation} 304 * @param userPopulation The users population 305 * @param userDirectoryId The id of the user directory 306 * @param count The limit of users to retrieve 307 * @param offset The number of result to ignore before starting to collect users. 308 * @param parameters A map of additional parameters, see implementation. 309 * @return list of users as Collection of {@link User}s, empty if a problem occurs. 310 */ 311 public Collection<User> getUsersByDirectory(UserPopulation userPopulation, String userDirectoryId, int count, int offset, Map<String, Object> parameters) 312 { 313 UserDirectory ud = userPopulation.getUserDirectory(userDirectoryId); 314 return ud.getUsers(count, offset, parameters); 315 } 316 317 /** 318 * Get a user by his login on some given contexts 319 * @param contexts The contexts 320 * @param login Login of the user to get. Cannot be null. 321 * @param checkRight True to check that current user is authorized to retrieve this user (true if he belongs to one of populations on theses contexts or he's an administrator user) 322 * @return User's information as a {@link User} instance or null if the user login does not exist. 323 */ 324 public User getUserByContext(Set<String> contexts, String login, boolean checkRight) 325 { 326 Set<String> upIds = _populationContextHelper.getUserPopulationsOnContexts(contexts, false, checkRight); 327 for (String upId : upIds) 328 { 329 UserPopulation userPopulation = _userPopulationDAO.getUserPopulation(upId); 330 User user = getUser(userPopulation, login); 331 if (user != null) 332 { 333 return user; 334 } 335 } 336 return null; 337 } 338 339 /** 340 * Get the user from its user identity 341 * @param userIdentity The user identity 342 * @return The User or null if the user login does not exist. 343 */ 344 public User getUser (UserIdentity userIdentity) 345 { 346 return getUser(userIdentity.getPopulationId(), userIdentity.getLogin()); 347 } 348 349 /** 350 * Get a particular user of the given users population by his login. 351 * @param userPopulationId The ID of user population 352 * @param login Login of the user to get. Cannot be null. 353 * @return User's information as a {@link User} instance or null if the user login does not exist. 354 */ 355 public User getUser(String userPopulationId, String login) 356 { 357 UserPopulation userPopulation = _userPopulationDAO.getUserPopulation(userPopulationId); 358 if (userPopulation != null) 359 { 360 return getUser(userPopulation, login); 361 } 362 else 363 { 364 return null; 365 } 366 } 367 368 /** 369 * Get a particular user of the given users population by his email. 370 * @param userPopulationId The ID of user population 371 * @param email Email of the user to get. Cannot be null. 372 * @return User's information as a {@link User} instance or null if the user login does not exist. 373 * @throws NotUniqueUserException if many users match the given email 374 */ 375 public User getUserByEmail(String userPopulationId, String email) throws NotUniqueUserException 376 { 377 UserPopulation userPopulation = _userPopulationDAO.getUserPopulation(userPopulationId); 378 if (userPopulation != null) 379 { 380 return getUserByEmail(userPopulation, email); 381 } 382 else 383 { 384 return null; 385 } 386 } 387 388 /** 389 * Get a particular user of the given user population and given user directory by his login. 390 * @param userPopulationId The ID of user population 391 * @param userDirectoryId The id of the user directory 392 * @param login Login of the user to get. Cannot be null. 393 * @return User's information as a {@link User} instance or null if the user login does not exist. 394 */ 395 public User getUserByDirectory(String userPopulationId, String userDirectoryId, String login) 396 { 397 UserPopulation userPopulation = _userPopulationDAO.getUserPopulation(userPopulationId); 398 if (userPopulation != null) 399 { 400 return getUserByDirectory(userPopulation, userDirectoryId, login); 401 } 402 else 403 { 404 return null; 405 } 406 } 407 408 /** 409 * Get a particular user of the given user population by his login. 410 * @param userPopulation The user population 411 * @param login Login of the user to get. Cannot be null. 412 * @return User's information as a {@link User} instance or null if the user login does not exist. 413 */ 414 public User getUser(UserPopulation userPopulation, String login) 415 { 416 for (UserDirectory ud : userPopulation.getUserDirectories()) 417 { 418 User user = ud.getUser(login); 419 if (user != null) 420 { 421 return user; 422 } 423 } 424 return null; 425 } 426 427 /** 428 * Get a particular user of the given user population by his email. 429 * @param userPopulation The user population 430 * @param email Email of the user to get. Cannot be null. 431 * @return User's information as a {@link User} instance or null if the user login does not exist. 432 * @throws NotUniqueUserException if many users match the given email 433 */ 434 public User getUserByEmail(UserPopulation userPopulation, String email) throws NotUniqueUserException 435 { 436 for (UserDirectory ud : userPopulation.getUserDirectories()) 437 { 438 User user = ud.getUserByEmail(email); 439 if (user != null) 440 { 441 return user; 442 } 443 } 444 return null; 445 } 446 447 /** 448 * Get a particular user of the given user population and given user directory by his login. 449 * @param userPopulation The user population 450 * @param userDirectoryId The id of the user directory 451 * @param login Login of the user to get. Cannot be null. 452 * @return User's information as a {@link User} instance or null if the user login does not exist. 453 */ 454 public User getUserByDirectory(UserPopulation userPopulation, String userDirectoryId, String login) 455 { 456 UserDirectory ud = userPopulation.getUserDirectory(userDirectoryId); 457 458 User user = ud.getUser(login); 459 if (user != null) 460 { 461 return user; 462 } 463 464 return null; 465 } 466 467 /** 468 * Get the user directory the given user belongs to 469 * @param userPopulationId The id of the user population 470 * @param login Login of the user to get. Cannot be null. 471 * @return The user directory the user belongs to. 472 */ 473 public UserDirectory getUserDirectory(String userPopulationId, String login) 474 { 475 UserPopulation userPopulation = _userPopulationDAO.getUserPopulation(userPopulationId); 476 if (userPopulation == null) 477 { 478 return null; 479 } 480 481 for (UserDirectory ud : userPopulation.getUserDirectories()) 482 { 483 User user = ud.getUser(login); 484 if (user != null) 485 { 486 return ud; 487 } 488 } 489 return null; 490 } 491}