001/* 002 * Copyright 2012 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.web.usermanagement; 017 018import java.io.IOException; 019import java.sql.Timestamp; 020import java.time.LocalDate; 021import java.time.ZoneId; 022import java.time.ZonedDateTime; 023import java.util.Arrays; 024import java.util.Date; 025import java.util.HashMap; 026import java.util.Iterator; 027import java.util.List; 028import java.util.Map; 029import java.util.Optional; 030import java.util.Set; 031import java.util.UUID; 032 033import org.apache.avalon.framework.configuration.Configuration; 034import org.apache.avalon.framework.configuration.ConfigurationException; 035import org.apache.avalon.framework.service.ServiceException; 036import org.apache.avalon.framework.service.ServiceManager; 037import org.apache.commons.lang.StringUtils; 038import org.apache.commons.lang3.RandomStringUtils; 039import org.apache.ibatis.session.SqlSession; 040 041import org.ametys.cms.repository.Content; 042import org.ametys.cms.transformation.URIResolver; 043import org.ametys.cms.transformation.URIResolverExtensionPoint; 044import org.ametys.core.datasource.AbstractMyBatisDAO; 045import org.ametys.core.user.InvalidModificationException; 046import org.ametys.core.user.User; 047import org.ametys.core.user.UserManager; 048import org.ametys.core.user.directory.ModifiableUserDirectory; 049import org.ametys.core.user.directory.NotUniqueUserException; 050import org.ametys.core.user.directory.UserDirectory; 051import org.ametys.core.user.population.PopulationContextHelper; 052import org.ametys.core.user.population.UserPopulation; 053import org.ametys.core.user.population.UserPopulationDAO; 054import org.ametys.core.util.I18nUtils; 055import org.ametys.core.util.URIUtils; 056import org.ametys.core.util.mail.SendMailHelper; 057import org.ametys.plugins.repository.AmetysObjectIterable; 058import org.ametys.plugins.repository.AmetysObjectResolver; 059import org.ametys.plugins.repository.AmetysRepositoryException; 060import org.ametys.plugins.repository.query.expression.Expression; 061import org.ametys.plugins.repository.query.expression.Expression.Operator; 062import org.ametys.runtime.i18n.I18nizableText; 063import org.ametys.runtime.i18n.I18nizableTextParameter; 064import org.ametys.runtime.parameter.Errors; 065import org.ametys.web.repository.page.Page; 066import org.ametys.web.repository.page.PageQueryHelper; 067import org.ametys.web.repository.page.ZoneItem; 068import org.ametys.web.repository.site.Site; 069import org.ametys.web.repository.site.SiteManager; 070import org.ametys.web.site.SiteConfigurationExtensionPoint; 071import org.ametys.web.tags.TagExpression; 072 073import com.google.common.collect.Multimap; 074 075import jakarta.mail.MessagingException; 076 077/** 078 * Manages registration and password recovery of users. 079 */ 080public class UserSignupManager extends AbstractMyBatisDAO 081{ 082 083 /** The component role. */ 084 public static final String ROLE = UserSignupManager.class.getName(); 085 086 /** Return code which indicates no error. */ 087 public static final int SIGNUP_NO_ERROR = 0; 088 089 /** Temporary signup return code: a user tried to sign-up but the e-mail already exists in the temporary table. */ 090 public static final int SIGNUP_ERROR_TEMP_EMAIL_ALREADY_EXISTS = 1; 091 092 /** Temporary signup return code: a user tried to sign-up but the FO UsersManager already possesses a user with this e-mail as login. */ 093 public static final int SIGNUP_ERROR_USER_ALREADY_EXISTS = 2; 094 095 /** Token return code: a user provided a token, but it doesn't exist. */ 096 public static final int SIGNUP_TOKEN_UNKNOWN = 3; 097 098 /** Token return code: a user provided a token, but it isn't valid anymore. */ 099 public static final int SIGNUP_TOKEN_EXPIRED = 4; 100 101 /** Token return code: undefined error. */ 102 public static final int SIGNUP_ERROR = 5; 103 104 /** Reset token return code: a user asked for a new token, but no subscription request can be found with this e-mail. */ 105 public static final int SIGNUP_RESET_ERROR_EMAIL_UNKNOWN = 5; 106 107 /** The user manager. */ 108 protected UserManager _userManager; 109 110 /** The DAO for user populations */ 111 protected UserPopulationDAO _userPopulationDAO; 112 113 /** The site manager. */ 114 protected SiteManager _siteManager; 115 116 /** The site configuration extension point. */ 117 protected SiteConfigurationExtensionPoint _siteConf; 118 119 /** The ametys object resolver. */ 120 protected AmetysObjectResolver _resolver; 121 122 /** The ametys object resolver. */ 123 protected URIResolverExtensionPoint _uriResolverEP; 124 125 /** The page URI resolver. */ 126 protected URIResolver _pageUriResolver; 127 128 /** The i18n utils. */ 129 protected I18nUtils _i18nUtils; 130 131 /** The user sign up configuration */ 132 protected UserSignUpConfiguration _userSignUpConfiguration; 133 134 /** The temporary users table. */ 135 protected String _tempUsersTable; 136 137 /** The password change table. */ 138 protected String _pwdChangeTable; 139 140 /** The population context helper. */ 141 protected PopulationContextHelper _populationContextHelper; 142 143 /** Enumeration for different cases of lost password errors */ 144 public enum LostPasswordError 145 { 146 /** User not connected */ 147 NOT_CONNECTED, 148 /** Lost password return code: the login or e-mail the user provided doesn't correspond to a population. */ 149 USER_UNKNOWN, 150 /** Lost password return code: the population the user provided doesn't correspond to a user. */ 151 POPULATION_UNKNOWN, 152 /** Lost password return code: the user provided belongs to an unmodifiable user directory */ 153 UNMODIFIABLE_USER_DIRECTORY, 154 /** Lost password return code: the user provided have an empty email */ 155 EMPTY_EMAIL, 156 /** Lost password return code: the informations the user provided match several users */ 157 SEVERAL_USERS, 158 /** Token return code: a user provided a token, but it doesn't exist. */ 159 TOKEN_UNKNOWN, 160 /** Token return code: a user provided a token, but it isn't valid anymore. */ 161 TOKEN_EXPIRED; 162 } 163 164 @Override 165 public void service(ServiceManager serviceManager) throws ServiceException 166 { 167 super.service(serviceManager); 168 169 _userManager = (UserManager) serviceManager.lookup(UserManager.ROLE); 170 _userPopulationDAO = (UserPopulationDAO) serviceManager.lookup(UserPopulationDAO.ROLE); 171 _siteManager = (SiteManager) serviceManager.lookup(SiteManager.ROLE); 172 _siteConf = (SiteConfigurationExtensionPoint) serviceManager.lookup(SiteConfigurationExtensionPoint.ROLE); 173 _resolver = (AmetysObjectResolver) serviceManager.lookup(AmetysObjectResolver.ROLE); 174 _uriResolverEP = (URIResolverExtensionPoint) serviceManager.lookup(URIResolverExtensionPoint.ROLE); 175 _i18nUtils = (I18nUtils) serviceManager.lookup(I18nUtils.ROLE); 176 _userSignUpConfiguration = (UserSignUpConfiguration) serviceManager.lookup(UserSignUpConfiguration.ROLE); 177 _populationContextHelper = (PopulationContextHelper) serviceManager.lookup(PopulationContextHelper.ROLE); 178 } 179 180 @Override 181 public void configure(Configuration configuration) throws ConfigurationException 182 { 183 super.configure(configuration); 184 185 // Configure pool and tables. 186 _tempUsersTable = configuration.getChild("temp-users-table").getValue(); 187 _pwdChangeTable = configuration.getChild("pwd-change-table").getValue(); 188 } 189 190 /** 191 * Test if public signup is allowed in a site. 192 * @param siteName the site to test. 193 * @return true if public signup is allowed, false otherwise. 194 */ 195 public boolean isPublicSignupAllowed(String siteName) 196 { 197 Site site = _siteManager.getSite(siteName); 198 return site.getValue("public-signup", false, false); 199 } 200 201 /** 202 * Get the sign-up page in a given site and sitemap.<br> 203 * If more than one page are tagged "sign-up", return the first. 204 * @param siteName the site name. 205 * @param language the sitemap name. 206 * @return the sign-up page or null if not found. 207 */ 208 public Page getSignupPage(String siteName, String language) 209 { 210 Page page = null; 211 212 try (AmetysObjectIterable<Page> pages = getSignupPages(siteName, language);) 213 { 214 Iterator<Page> it = pages.iterator(); 215 if (it.hasNext()) 216 { 217 page = it.next(); 218 } 219 } 220 221 return page; 222 } 223 224 /** 225 * Get all the pages tagged "sign-up". 226 * @param siteName the site name. 227 * @param language the sitemap name. 228 * @return an iterable on all the pages tagged "sign-up". 229 */ 230 public AmetysObjectIterable<Page> getSignupPages(String siteName, String language) 231 { 232 Expression expression = new TagExpression(Operator.EQ, "USER_SIGNUP"); 233 String query = PageQueryHelper.getPageXPathQuery(siteName, language, null, expression, null); 234 235 return _resolver.query(query); 236 } 237 238 /** 239 * Get the password change page in a given site and sitemap. 240 * If more than one page are tagged "password change", return the first. 241 * @param siteName the site name. 242 * @param language the sitemap name. 243 * @return the password change page or null if not found. 244 */ 245 public Page getPwdChangePage(String siteName, String language) 246 { 247 Page page = null; 248 249 try (AmetysObjectIterable<Page> pages = getPwdChangePages(siteName, language);) 250 { 251 Iterator<Page> it = pages.iterator(); 252 if (it.hasNext()) 253 { 254 page = it.next(); 255 } 256 } 257 258 return page; 259 } 260 261 /** 262 * Get the GTU page 263 * Returns null if not found or empty 264 * @param zoneItem the zone item 265 * @return the GTU page or null. 266 */ 267 public Page getGTUPage(ZoneItem zoneItem) 268 { 269 Page page = null; 270 271 try 272 { 273 String tosMode = zoneItem.getServiceParameters().getValue("terms-of-service-mode"); 274 if ("PAGE".equals(tosMode)) 275 { 276 String tosPageId = zoneItem.getServiceParameters().getValue("terms-of-service-page"); 277 if (StringUtils.isNotEmpty(tosPageId)) 278 { 279 page = _resolver.resolveById(tosPageId); 280 } 281 } 282 } 283 catch (AmetysRepositoryException e) 284 { 285 // Nothing 286 } 287 288 return page; 289 } 290 291 /** 292 * Get the GTU content 293 * Returns null if not found or empty 294 * @param zoneItem the zone item 295 * @return the GTU content or null. 296 */ 297 public Content getGTUContent(ZoneItem zoneItem) 298 { 299 Content content = null; 300 301 try 302 { 303 String tosMode = zoneItem.getServiceParameters().getValue("terms-of-service-mode"); 304 if ("CONTENT".equals(tosMode)) 305 { 306 String tosContentId = zoneItem.getServiceParameters().getValue("terms-of-service-content"); 307 if (StringUtils.isNotEmpty(tosContentId)) 308 { 309 content = _resolver.resolveById(tosContentId); 310 } 311 } 312 313 } 314 catch (AmetysRepositoryException e) 315 { 316 // Nothing 317 } 318 319 return content; 320 } 321 322 /** 323 * Get the GTU page 324 * Returns null if not found or empty 325 * @param zoneItem the zone item 326 * @return the success page or null. 327 */ 328 public Page getSuccessPage(ZoneItem zoneItem) 329 { 330 Page page = null; 331 332 try 333 { 334 String successMode = zoneItem.getServiceParameters().getValue("success-mode"); 335 if ("PAGE".equals(successMode)) 336 { 337 String successPageId = zoneItem.getServiceParameters().getValue("success-page"); 338 if (StringUtils.isNotEmpty(successPageId)) 339 { 340 page = _resolver.resolveById(successPageId); 341 } 342 } 343 } 344 catch (AmetysRepositoryException e) 345 { 346 // Nothing 347 } 348 349 return page; 350 } 351 352 /** 353 * Get the success content 354 * Returns null if not found or empty 355 * @param zoneItem the zone item 356 * @return the success content or null. 357 */ 358 public Content getSuccessContent(ZoneItem zoneItem) 359 { 360 Content content = null; 361 362 try 363 { 364 String successMode = zoneItem.getServiceParameters().getValue("success-mode"); 365 if ("CONTENT".equals(successMode)) 366 { 367 String successContentId = zoneItem.getServiceParameters().getValue("success-content"); 368 if (StringUtils.isNotEmpty(successContentId)) 369 { 370 content = _resolver.resolveById(successContentId); 371 } 372 } 373 } 374 catch (AmetysRepositoryException e) 375 { 376 // Nothing 377 } 378 379 return content; 380 } 381 382 /** 383 * Get all the pages tagged "password change". 384 * @param siteName the site name. 385 * @param language the sitemap name. 386 * @return an iterable on all the pages tagged "password change". 387 */ 388 public AmetysObjectIterable<Page> getPwdChangePages(String siteName, String language) 389 { 390 Expression expression = new TagExpression(Operator.EQ, "USER_PASSWORD_CHANGE"); 391 String query = PageQueryHelper.getPageXPathQuery(siteName, language, null, expression, null); 392 393 return _resolver.query(query); 394 } 395 396 /** 397 * Get the user from email if he/she exists in the populations 398 * @param email the e-mail to test. 399 * @param siteName The site name 400 * @return the user if the user exists, empty otherwise. 401 * @throws UserManagementException if an error occurs. 402 * @throws NotUniqueUserException if several user respond to the email 403 */ 404 public Optional<User> getUserIfHeExists(String email, String siteName) throws UserManagementException, NotUniqueUserException 405 { 406 Set<String> populationIds = _populationContextHelper.getUserPopulationsOnContexts(Arrays.asList("/sites/" + siteName, "/sites-fo/" + siteName), false, false); 407 for (String population : populationIds) 408 { 409 User user = _userManager.getUser(population, email); 410 if (user != null) 411 { 412 return Optional.of(user); 413 } 414 else 415 { 416 User userByEmail = _userManager.getUserByEmail(population, email); 417 if (userByEmail != null) 418 { 419 return Optional.of(userByEmail); 420 } 421 } 422 } 423 424 return Optional.empty(); 425 } 426 427 /** 428 * Tests if the user already exists in the populations 429 * @param email the e-mail to test. 430 * @param siteName The site name 431 * @return true if the user exists, false otherwise. 432 * @throws UserManagementException if an error occurs. 433 */ 434 public boolean userExists(String email, String siteName) throws UserManagementException 435 { 436 try 437 { 438 return getUserIfHeExists(email, siteName).isPresent(); 439 } 440 catch (NotUniqueUserException e) 441 { 442 return true; 443 } 444 } 445 446 /** 447 * Validate the user subscription data. 448 * @param siteName the site name. 449 * @param email the user e-mail. 450 * @param additionalValues the additional user values. 451 * @return a Map of the Errors by field. 452 * @throws UserManagementException if an error occurs. 453 */ 454 public Map<String, Errors> validate(String siteName, String email, Map<String, String> additionalValues) throws UserManagementException 455 { 456 Map<String, String> userInfos = new HashMap<>(); 457 458 userInfos.putAll(additionalValues); 459 460 // Standard info for user (provide a dummy password, as we do not know it yet). 461 userInfos.put("login", email); 462 userInfos.put("email", email); 463 userInfos.put("password", "password"); 464 465 Map<String, Errors> usersManagerErrors = new HashMap<>(); //foUsersManager.validate(userInfos); 466 Map<String, Errors> errors = new HashMap<>(usersManagerErrors); 467 468 // If there are errors on the login, do not return it except if 469 if (errors.containsKey("login")) 470 { 471 if (!errors.containsKey("email")) 472 { 473 errors.put("email", errors.get("login")); 474 } 475 errors.remove("login"); 476 } 477 478 return errors; 479 } 480 481 /** 482 * Validate the user password. 483 * @param siteName the site name. 484 * @param password the password to validate. 485 * @param login the login of the user 486 * @param population The id of the population 487 * @return a Map of the Errors by field. 488 * @throws UserManagementException if an error occurs. 489 */ 490 public Map<String, Errors> validatePassword(String siteName, String password, String login, String population) throws UserManagementException 491 { 492 Map<String, String> userInfos = new HashMap<>(); 493 494 userInfos.put("password", password); 495 496 UserDirectory userDirectory = _userManager.getUserDirectory(population, login); 497 if (!(userDirectory instanceof ModifiableUserDirectory)) 498 { 499 throw new UserManagementException("The user subscription feature can't be used, as the UserDirectory is not modifiable."); 500 } 501 Map<String, Errors> usersManagerErrors = ((ModifiableUserDirectory) userDirectory).validate(userInfos); 502 Map<String, Errors> errors = new HashMap<>(); 503 504 // Keep only errors related to the password field. 505 if (usersManagerErrors.containsKey("password")) 506 { 507 errors.put("password", usersManagerErrors.get("password")); 508 } 509 510 return errors; 511 } 512 513 /** 514 * Validate and store a sign-up request and send a confirmation e-mail. 515 * @param siteName the site name. 516 * @param language the sitemap name. 517 * @param email the user e-mail address. 518 * @param population the population 519 * @param userDirectoryId the id of the user directory of the population 520 * @return a status code indicating success or error. 521 * @throws UserManagementException if an error occurs. 522 */ 523 public int temporarySignup(String siteName, String language, String email, String population, String userDirectoryId) throws UserManagementException 524 { 525 return temporarySignup(siteName, language, email, population, userDirectoryId, true); 526 } 527 528 /** 529 * Validate and store a sign-up request and send a confirmation e-mail. 530 * @param siteName the site name. 531 * @param language the sitemap name. 532 * @param email the user e-mail address. 533 * @param population the population 534 * @param userDirectoryId the id of the user directory of the population 535 * @param sendMail Set to false to not send mail at end of process 536 * @return a status code indicating success or error. 537 * @throws UserManagementException if an error occurs. 538 */ 539 public int temporarySignup(String siteName, String language, String email, String population, String userDirectoryId, boolean sendMail) throws UserManagementException 540 { 541 // Verify that public sign-up is allowed and throw an exception otherwise. 542 checkPublicSignup(siteName); 543 544 if (getLogger().isDebugEnabled()) 545 { 546 getLogger().debug("A user is requesting a sign-up: " + email); 547 } 548 549 // Generate unique token. 550 String token = UUID.randomUUID().toString().replace("-", ""); 551 552 int status = addTemporaryUser(siteName, email, token, population, userDirectoryId); 553 554 // Send validation e-mail with token. 555 if (status == SIGNUP_NO_ERROR && sendMail) 556 { 557 sendSignupConfirmMail(siteName, language, email, token); 558 } 559 560 return status; 561 } 562 563 /** 564 * Get a token for temp user 565 * @param siteName the site name. 566 * @param email the user e-mail address. 567 * @param population The id of the population 568 * @param userDirectoryId The id of the user directory of the population 569 * @return the user token or null if not found 570 * @throws UserManagementException if an error occurs. 571 */ 572 public String getToken(String siteName, String email, String population, String userDirectoryId) throws UserManagementException 573 { 574 TempUser tempUser = getTempUser(siteName, email, population, userDirectoryId); 575 if (tempUser != null) 576 { 577 return tempUser.getToken(); 578 } 579 580 return null; 581 } 582 583 /** 584 * Reset a sign-up request: generate a new token and re-send the confirmation e-mail. 585 * @param siteName the site name. 586 * @param language the sitemap name. 587 * @param email the user e-mail address. 588 * @param population The id of the population 589 * @param userDirectoryId The id of the user directory of the population 590 * @return a status code indicating success or error. 591 * @throws UserManagementException if an error occurs. 592 */ 593 public int resetTempSignup(String siteName, String language, String email, String population, String userDirectoryId) throws UserManagementException 594 { 595 // Verify that public sign-up is allowed and throw an exception otherwise. 596 checkPublicSignup(siteName); 597 598 if (getLogger().isDebugEnabled()) 599 { 600 getLogger().debug("Resetting temporary signup for email: " + email + " in site " + siteName); 601 } 602 603 // Generate a new token. 604 String newToken = UUID.randomUUID().toString().replace("-", ""); 605 606 // Test if the subscription request really exists. 607 TempUser tempUser = getTempUser(siteName, email, population, userDirectoryId); 608 609 if (tempUser == null) 610 { 611 // No subscription request with this e-mail. 612 return SIGNUP_RESET_ERROR_EMAIL_UNKNOWN; 613 } 614 615 updateTempToken(siteName, email, newToken, population, userDirectoryId); 616 617 sendSignupConfirmMail(siteName, language, email, newToken); 618 619 return SIGNUP_NO_ERROR; 620 } 621 622 623 /** 624 * Create the user in the FO UsersManager from his temporary request. 625 * @param siteName the site name. 626 * @param language the current language 627 * @param firstname the user firstname 628 * @param lastname the user lastname 629 * @param email the user e-mail address. 630 * @param token the request token. 631 * @param password the user password. 632 * @param population The id of the population 633 * @param userDirectoryId The id of the user directory of the population 634 * @param errors the errors 635 * @return a status code indicating success or error. 636 * @throws UserManagementException if an error occurs. 637 */ 638 public int signup(String siteName, String language, String firstname, String lastname, String email, String token, String password, String population, String userDirectoryId, Multimap<String, I18nizableText> errors) throws UserManagementException 639 { 640 // Verify that public sign-up is allowed and throw an exception otherwise. 641 checkPublicSignup(siteName); 642 643 Map<String, String> userInfos = new HashMap<>(); 644 645 TempUser tempUser = getTempUser(siteName, email, token, population, userDirectoryId); 646 647 if (tempUser == null) 648 { 649 return SIGNUP_TOKEN_UNKNOWN; 650 } 651 652 // Generate login 653 String login = RandomStringUtils.randomNumeric(10); 654 655 // Standard info for user. 656 userInfos.put("login", login); 657 userInfos.put("email", email); 658 userInfos.put("firstname", firstname); 659 userInfos.put("lastname", lastname); 660 userInfos.put("password", password); 661 662 try 663 { 664 validationBeforeSignup(errors); 665 666 if (errors.isEmpty()) 667 { 668 // Add the user. 669 ModifiableUserDirectory userDirectory = (ModifiableUserDirectory) _userPopulationDAO.getUserPopulation(population).getUserDirectory(userDirectoryId); 670 userDirectory.add(userInfos); 671 672 // Remove the temporary user. 673 removeTempUser(siteName, email, token, population, userDirectoryId); 674 675 User createdUser = userDirectory.getUser(login); 676 677 // Do additional operations after signup 678 additionalSignupOperations(createdUser, errors); 679 680 if (errors.isEmpty()) 681 { 682 sendSignupValidatedMail(siteName, language, createdUser); 683 return SIGNUP_NO_ERROR; 684 } 685 } 686 687 return SIGNUP_ERROR; 688 } 689 catch (InvalidModificationException e) 690 { 691 throw new UserManagementException("An error occurred signing up the user.", e); 692 } 693 } 694 695 /** 696 * Do some validation before signup 697 * @param errors the map of errors to fill in cause of errors during validation 698 */ 699 public void validationBeforeSignup(Multimap<String, I18nizableText> errors) 700 { 701 // Nothing 702 } 703 704 /** 705 * Process additional operations after creation of user 706 * @param createdUser the created user 707 * @param errors the map of errors to fill in case of errors during additional operations 708 * @throws UserManagementException if an error occurs. 709 */ 710 public void additionalSignupOperations(User createdUser, Multimap<String, I18nizableText> errors) throws UserManagementException 711 { 712 // Nothing 713 } 714 715 716 /** 717 * Create a reset password request and send a confirmation e-mail. 718 * @param siteName the site name. 719 * @param language the sitemap name. 720 * @param loginOrEmail the user login or email. 721 * @param populationId the population 722 * @return a status code indicating success or error. 723 * @throws UserManagementException if an error occurs. 724 */ 725 public LostPasswordError resetPassword(String siteName, String language, String loginOrEmail, String populationId) throws UserManagementException 726 { 727 // Check if the population exists 728 UserPopulation population = _userPopulationDAO.getUserPopulation(populationId); 729 if (population == null) 730 { 731 return LostPasswordError.POPULATION_UNKNOWN; 732 } 733 734 // Check if the user exists and get it 735 User user = _userManager.getUser(populationId, loginOrEmail); 736 if (user == null) 737 { 738 try 739 { 740 user = _userManager.getUserByEmail(populationId, loginOrEmail); 741 if (user == null) 742 { 743 // No user with this e-mail or login. 744 return LostPasswordError.USER_UNKNOWN; 745 } 746 } 747 catch (NotUniqueUserException e) 748 { 749 return LostPasswordError.SEVERAL_USERS; 750 } 751 } 752 753 // Check if the user directory is modifiable 754 if (!(user.getUserDirectory() instanceof ModifiableUserDirectory)) 755 { 756 return LostPasswordError.UNMODIFIABLE_USER_DIRECTORY; 757 } 758 759 if (StringUtils.isEmpty(user.getEmail())) 760 { 761 return LostPasswordError.EMPTY_EMAIL; 762 } 763 764 // Generate a new token. 765 String token = UUID.randomUUID().toString().replace("-", ""); 766 767 // Insert the token in the database. 768 addPasswordToken(siteName, user.getIdentity().getLogin(), token, populationId); 769 770 // Send the e-mail. 771 sendResetPasswordMail(siteName, language, user, token); 772 773 return null; 774 } 775 776 /** 777 * Change the user password. 778 * @param siteName the site name. 779 * @param login the user login. 780 * @param token the password change request token. 781 * @param newPassword the new password. 782 * @param population the population 783 * @return a status code indicating success or error. 784 * @throws UserManagementException if an error occurs. 785 */ 786 public int changeUserPassword(String siteName, String login, String token, String newPassword, String population) throws UserManagementException 787 { 788 int tokenStatus = checkPasswordToken(siteName, login, token, population); 789 790 if (tokenStatus != SIGNUP_NO_ERROR) 791 { 792 return tokenStatus; 793 } 794 795 Map<String, String> userInfos = new HashMap<>(); 796 797 userInfos.put("login", login); 798 userInfos.put("password", newPassword); 799 800 try 801 { 802 UserDirectory userDirectory = _userManager.getUserDirectory(population, login); 803 if (!(userDirectory instanceof ModifiableUserDirectory)) 804 { 805 throw new UserManagementException("The user's password can't be changed, as the UserDirectory is not modifiable."); 806 } 807 ((ModifiableUserDirectory) userDirectory).update(userInfos); 808 809 removePasswordToken(siteName, login, token, population); 810 811 return SIGNUP_NO_ERROR; 812 } 813 catch (InvalidModificationException e) 814 { 815 throw new UserManagementException("An error occurred signing up the user.", e); 816 } 817 } 818 819 /** 820 * Check the sign-up request token. 821 * @param siteName the site name. 822 * @param email the user e-mail. 823 * @param token the sign-up request token. 824 * @param population The id of the population 825 * @param userDirectoryId The id of the user directory of the population 826 * @return a status code indicating success or error. 827 * @throws UserManagementException if an error occurs. 828 */ 829 public int checkToken(String siteName, String email, String token, String population, String userDirectoryId) throws UserManagementException 830 { 831 removeExpiredTokens(); 832 833 try (SqlSession sqlSession = getSession()) 834 { 835 String stmtId = "UserSignupManager.getSubscriptionDate"; 836 837 Map<String, Object> params = new HashMap<>(); 838 params.put("tempUsersTable", _tempUsersTable); 839 840 params.put("site", siteName); 841 params.put("email", email); 842 params.put("token", token); 843 params.put("population", population); 844 params.put("userDirectory", userDirectoryId); 845 846 Date rawSubscriptionDate = sqlSession.selectOne(stmtId, params); 847 848 // Date verification. 849 if (rawSubscriptionDate == null) 850 { 851 return SIGNUP_TOKEN_UNKNOWN; 852 } 853 854 // The validity limit 855 ZonedDateTime limit = LocalDate.now().atStartOfDay(ZoneId.systemDefault()).minusDays(_userSignUpConfiguration.getTokenValidity()); 856 ZonedDateTime subscriptionDate = rawSubscriptionDate.toInstant().atZone(ZoneId.systemDefault()); 857 858 if (subscriptionDate.isBefore(limit)) 859 { 860 return SIGNUP_TOKEN_EXPIRED; 861 } 862 863 return SIGNUP_NO_ERROR; 864 } 865 catch (Exception e) 866 { 867 throw new UserManagementException("Database error while testing the token for user [" + email + "]", e); 868 } 869 } 870 871 /** 872 * Check the password change request token. 873 * @param siteName the site name. 874 * @param login the user login. 875 * @param token the password change request token. 876 * @param population the population 877 * @return a status code indicating success or error. 878 * @throws UserManagementException if an error occurs. 879 */ 880 public int checkPasswordToken(String siteName, String login, String token, String population) throws UserManagementException 881 { 882 removeExpiredPasswordTokens(); 883 884 try (SqlSession sqlSession = getSession()) 885 { 886 String stmtId = "UserSignupManager.getRequestDate"; 887 888 Map<String, Object> params = new HashMap<>(); 889 params.put("pwdChangeTable", _pwdChangeTable); 890 891 params.put("site", siteName); 892 params.put("login", login); 893 params.put("token", token); 894 params.put("population", population); 895 896 Date rawRequestDate = sqlSession.selectOne(stmtId, params); 897 898 // Date verification. 899 if (rawRequestDate == null) 900 { 901 return SIGNUP_TOKEN_UNKNOWN; 902 } 903 904 // Check the validity. 905 ZonedDateTime limit = LocalDate.now().atStartOfDay(ZoneId.systemDefault()).minusDays(_userSignUpConfiguration.getTokenValidity()); 906 ZonedDateTime requestDate = rawRequestDate.toInstant().atZone(ZoneId.systemDefault()); 907 908 if (requestDate.isBefore(limit)) 909 { 910 return SIGNUP_TOKEN_EXPIRED; 911 } 912 913 return SIGNUP_NO_ERROR; 914 } 915 catch (Exception e) 916 { 917 throw new UserManagementException("Database error while testing the password token for user " + login, e); 918 } 919 } 920 921 /** 922 * Remove the expired sign-up request tokens. 923 * @throws UserManagementException if an error occurs. 924 */ 925 public void removeExpiredTokens() throws UserManagementException 926 { 927 try (SqlSession sqlSession = getSession()) 928 { 929 String stmtId = "UserSignupManager.deleteExpiredTokens"; 930 931 Map<String, Object> params = new HashMap<>(); 932 params.put("tempUsersTable", _tempUsersTable); 933 934 ZonedDateTime limit = LocalDate.now().atStartOfDay(ZoneId.systemDefault()).minusDays(_userSignUpConfiguration.getTokenValidity()); 935 Timestamp limitTimestamp = Timestamp.from(limit.toInstant()); 936 params.put("threshold", limitTimestamp); 937 938 sqlSession.delete(stmtId, params); 939 sqlSession.commit(); 940 } 941 catch (Exception e) 942 { 943 throw new UserManagementException("Database error while removing the expired tokens.", e); 944 } 945 } 946 947 /** 948 * Remove the expired change password request tokens. 949 * @throws UserManagementException if an error occurs. 950 */ 951 public void removeExpiredPasswordTokens() throws UserManagementException 952 { 953 try (SqlSession sqlSession = getSession()) 954 { 955 String stmtId = "UserSignupManager.deleteExpiredPasswordTokens"; 956 957 Map<String, Object> params = new HashMap<>(); 958 params.put("pwdChangeTable", _pwdChangeTable); 959 960 ZonedDateTime limit = LocalDate.now().atStartOfDay(ZoneId.systemDefault()).minusDays(_userSignUpConfiguration.getTokenValidity()); 961 Timestamp limitTimestamp = Timestamp.from(limit.toInstant()); 962 params.put("threshold", limitTimestamp); 963 964 sqlSession.delete(stmtId, params); 965 sqlSession.commit(); 966 } 967 catch (Exception e) 968 { 969 throw new UserManagementException("Database error while removing the expired tokens.", e); 970 } 971 } 972 973 /** 974 * Verify that public sign-up is allowed. If not, throw an exception. 975 * @param siteName the site name. 976 * @throws UserManagementException if public sign-up is not enabled. 977 */ 978 protected void checkPublicSignup(String siteName) throws UserManagementException 979 { 980 if (!isPublicSignupAllowed(siteName)) 981 { 982 throw new UserManagementException("Public signup is disabled for this site."); 983 } 984 } 985 986 /** 987 * Create a user sign-up request ("temporary" user) in the database. 988 * @param siteName the site name. 989 * @param email the user e-mail. 990 * @param token the generated token. 991 * @param population the population 992 * @param userDirectoryId the id of the user directory of the population 993 * @return a status code indicating success or error. 994 * @throws UserManagementException if an error occurs. 995 */ 996 protected int addTemporaryUser(String siteName, String email, String token, String population, String userDirectoryId) throws UserManagementException 997 { 998 try (SqlSession sqlSession = getSession()) 999 { 1000 // Does this email already exists 1001 String stmtId = "UserSignupManager.tempEmailExists"; 1002 1003 Map<String, Object> params = new HashMap<>(); 1004 params.put("tempUsersTable", _tempUsersTable); 1005 1006 params.put("site", siteName); 1007 params.put("email", email); 1008 params.put("population", population); 1009 params.put("userDirectory", userDirectoryId); 1010 1011 List<String> emails = sqlSession.selectList(stmtId, params); 1012 1013 if (!emails.isEmpty()) 1014 { 1015 return SIGNUP_ERROR_TEMP_EMAIL_ALREADY_EXISTS; 1016 } 1017 1018 // Add temp user 1019 stmtId = "UserSignupManager.addTempUser"; 1020 params = new HashMap<>(); 1021 params.put("tempUsersTable", _tempUsersTable); 1022 1023 Timestamp now = new Timestamp(System.currentTimeMillis()); 1024 1025 params.put("site", siteName); 1026 params.put("email", email); 1027 params.put("population", population); 1028 params.put("userDirectory", userDirectoryId); 1029 params.put("subscription_date", now); 1030 params.put("token", token); 1031 1032 sqlSession.insert(stmtId, params); 1033 sqlSession.commit(); 1034 1035 return SIGNUP_NO_ERROR; 1036 } 1037 catch (Exception e) 1038 { 1039 throw new UserManagementException("Database error while signing up a new user [" + email + "]", e); 1040 } 1041 } 1042 1043 /** 1044 * Send a sign-up confirmation link by e-mail. 1045 * @param siteName the site name. 1046 * @param language the e-mail language. 1047 * @param email the user e-mail. 1048 * @param token the generated token. 1049 * @throws UserManagementException if an error occurs. 1050 */ 1051 protected void sendSignupConfirmMail(String siteName, String language, String email, String token) throws UserManagementException 1052 { 1053 if (getLogger().isDebugEnabled()) 1054 { 1055 getLogger().debug("Sending signup confirmation e-mail to " + email); 1056 } 1057 1058 Site site = _siteManager.getSite(siteName); 1059 String from = site.getValue("site-mail-from"); 1060 1061 // Prepare mail. 1062 Map<String, I18nizableTextParameter> i18nParams = new HashMap<>(); 1063 i18nParams.put("siteName", new I18nizableText(siteName)); 1064 i18nParams.put("email", new I18nizableText(email)); 1065 i18nParams.put("token", new I18nizableText(token)); 1066 1067 Page signupPage = getSignupPage(siteName, language); 1068 if (signupPage != null) 1069 { 1070 if (_pageUriResolver == null) 1071 { 1072 _pageUriResolver = _uriResolverEP.getResolverForType("page"); 1073 } 1074 1075 String encodedEmail = URIUtils.encodeParameter(email); 1076 1077 // Compute the confirmation URI and add it to the parameters. 1078 String confirmUri = _pageUriResolver.resolve(signupPage.getId(), false, true, false); 1079 confirmUri = confirmUri + "?email=" + encodedEmail + "&token=" + token; 1080 1081 i18nParams.put("confirmUri", new I18nizableText(confirmUri)); 1082 } 1083 1084 // Add site information in the parameters. 1085 i18nParams.put("siteTitle", new I18nizableText(site.getTitle())); 1086 i18nParams.put("siteUrl", new I18nizableText(site.getUrl())); 1087 1088 String subject = _userSignUpConfiguration.getSubjectForSignUpEmail(i18nParams, language); 1089 String textBody = _userSignUpConfiguration.getTextBodyForSignUpEmail(i18nParams, language); 1090 String htmlBody = _userSignUpConfiguration.getHtmlBodyForSignUpEmail(i18nParams, language); 1091 1092 try 1093 { 1094 // Send the e-mail. 1095 SendMailHelper.newMail() 1096 .withSubject(subject) 1097 .withHTMLBody(htmlBody) 1098 .withTextBody(textBody) 1099 .withSender(from) 1100 .withRecipient(email) 1101 .sendMail(); 1102 } 1103 catch (MessagingException | IOException e) 1104 { 1105 throw new UserManagementException("Error sending the sign-up confirmation mail.", e); 1106 } 1107 } 1108 1109 /** 1110 * Send a sign-up confirmation link by e-mail. 1111 * @param siteName the site name. 1112 * @param language the e-mail language. 1113 * @param user the created user 1114 * @throws UserManagementException if an error occurs. 1115 */ 1116 protected void sendSignupValidatedMail(String siteName, String language, User user) throws UserManagementException 1117 { 1118 Site site = _siteManager.getSite(siteName); 1119 String from = site.getValue("site-mail-from"); 1120 String email = user.getEmail(); 1121 1122 if (getLogger().isDebugEnabled()) 1123 { 1124 getLogger().debug("Sending signup validation e-mail to " + email); 1125 } 1126 1127 // Prepare mail. 1128 Map<String, I18nizableTextParameter> i18nParams = new HashMap<>(); 1129 i18nParams.put("siteName", new I18nizableText(siteName)); 1130 i18nParams.put("fullName", new I18nizableText(user.getFullName())); 1131 i18nParams.put("email", new I18nizableText(user.getEmail())); 1132 i18nParams.put("login", new I18nizableText(user.getIdentity().getLogin())); 1133 1134 // Add site information in the parameters. 1135 i18nParams.put("siteTitle", new I18nizableText(site.getTitle())); 1136 i18nParams.put("siteUrl", new I18nizableText(site.getUrl())); 1137 1138 String subject = _userSignUpConfiguration.getSubjectForSignUpValidatedEmail(i18nParams, language); 1139 String textBody = _userSignUpConfiguration.getTextBodyForSignUpValidatedEmail(i18nParams, language); 1140 String htmlBody = _userSignUpConfiguration.getHtmlBodyForSignUpValidatedEmail(i18nParams, language); 1141 1142 try 1143 { 1144 // Send the e-mail. 1145 SendMailHelper.newMail() 1146 .withSubject(subject) 1147 .withHTMLBody(htmlBody) 1148 .withTextBody(textBody) 1149 .withSender(from) 1150 .withRecipient(email) 1151 .sendMail(); 1152 } 1153 catch (MessagingException | IOException e) 1154 { 1155 throw new UserManagementException("Error sending the sign-up validation mail.", e); 1156 } 1157 } 1158 1159 /** 1160 * Update the sign-up request token: reset the date and set a new token. 1161 * @param siteName the site name. 1162 * @param email the user e-mail. 1163 * @param newToken the new token. 1164 * @param population The id of the population 1165 * @param userDirectoryId The id of the user directory of the population 1166 * @throws UserManagementException if an error occurs. 1167 */ 1168 protected void updateTempToken(String siteName, String email, String newToken, String population, String userDirectoryId) throws UserManagementException 1169 { 1170 try (SqlSession sqlSession = getSession()) 1171 { 1172 String stmtId = "UserSignupManager.updateTempToken"; 1173 1174 Map<String, Object> params = new HashMap<>(); 1175 params.put("tempUsersTable", _tempUsersTable); 1176 1177 Timestamp now = new Timestamp(System.currentTimeMillis()); 1178 params.put("subscription_date", now); 1179 params.put("token", newToken); 1180 params.put("site", siteName); 1181 params.put("email", email); 1182 params.put("population", population); 1183 params.put("userDirectory", userDirectoryId); 1184 1185 sqlSession.update(stmtId, params); 1186 sqlSession.commit(); 1187 } 1188 catch (Exception e) 1189 { 1190 throw new UserManagementException("Database error while resetting the subscription for user [" + email + "]", e); 1191 } 1192 } 1193 1194 /** 1195 * Create a user password change request in the database. 1196 * @param siteName the site name. 1197 * @param login the user login. 1198 * @param token the generated token. 1199 * @param population the population 1200 * @throws UserManagementException if an error occurs. 1201 */ 1202 protected void addPasswordToken(String siteName, String login, String token, String population) throws UserManagementException 1203 { 1204 try (SqlSession sqlSession = getSession()) 1205 { 1206 String stmtId = "UserSignupManager.hasToken"; 1207 1208 Map<String, Object> params = new HashMap<>(); 1209 params.put("pwdChangeTable", _pwdChangeTable); 1210 1211 params.put("site", siteName); 1212 params.put("login", login); 1213 params.put("population", population); 1214 1215 List<Object> pwdEntries = sqlSession.selectList(stmtId, params); 1216 1217 if (pwdEntries.isEmpty()) 1218 { 1219 // Insert a new token. 1220 stmtId = "UserSignupManager.addPasswordToken"; 1221 params = new HashMap<>(); 1222 params.put("pwdChangeTable", _pwdChangeTable); 1223 1224 Timestamp now = new Timestamp(System.currentTimeMillis()); 1225 params.put("site", siteName); 1226 params.put("login", login); 1227 params.put("request_date", now); 1228 params.put("token", token); 1229 params.put("population", population); 1230 1231 sqlSession.insert(stmtId, params); 1232 } 1233 else 1234 { 1235 // Update the existing token. 1236 stmtId = "UserSignupManager.updatePasswordToken"; 1237 params = new HashMap<>(); 1238 params.put("pwdChangeTable", _pwdChangeTable); 1239 1240 Timestamp now = new Timestamp(System.currentTimeMillis()); 1241 params.put("request_date", now); 1242 params.put("token", token); 1243 params.put("site", siteName); 1244 params.put("login", login); 1245 params.put("population", population); 1246 1247 sqlSession.update(stmtId, params); 1248 } 1249 1250 // commit insert or update 1251 sqlSession.commit(); 1252 } 1253 catch (Exception e) 1254 { 1255 throw new UserManagementException("Database error while inserting a password change token for " + login, e); 1256 } 1257 } 1258 1259 /** 1260 * Get a temporary user from his site name and e-mail. 1261 * @param siteName the site name. 1262 * @param email The temporary user e-mail. Cannot be null. 1263 * @param population the population 1264 * @param userDirectoryId the id of the user directory of the population 1265 * @return the temporary user or null if not found. 1266 * @throws UserManagementException if an error occurs. 1267 */ 1268 protected TempUser getTempUser(String siteName, String email, String population, String userDirectoryId) throws UserManagementException 1269 { 1270 return getTempUser(siteName, email, null, population, userDirectoryId); 1271 } 1272 1273 /** 1274 * Get a temporary user from his site name, e-mail and/or token. 1275 * At least one of e-mail and token must be provided. 1276 * @param siteName the site name. 1277 * @param email The temporary user e-mail. Can be null. 1278 * @param token The temporary user token. Can be null. 1279 * @param population the population. Must be not null if email is not null 1280 * @param userDirectoryId the id of the user directory of the population. Must be not null if email is not null 1281 * @return the temporary user or null if not found. 1282 * @throws UserManagementException if an error occurs. 1283 */ 1284 protected TempUser getTempUser(String siteName, String email, String token, String population, String userDirectoryId) throws UserManagementException 1285 { 1286 if (StringUtils.isEmpty(email) && StringUtils.isEmpty(token)) 1287 { 1288 throw new UserManagementException("Either e-mail or token must be provided."); 1289 } 1290 1291 try (SqlSession sqlSession = getSession()) 1292 { 1293 // Does this email already exists 1294 String stmtId = "UserSignupManager.getTempUser"; 1295 1296 Map<String, Object> params = new HashMap<>(); 1297 params.put("tempUsersTable", _tempUsersTable); 1298 1299 params.put("site", siteName); 1300 if (StringUtils.isNotEmpty(email)) 1301 { 1302 params.put("email", email); 1303 params.put("population", population); 1304 params.put("userDirectory", userDirectoryId); 1305 } 1306 if (StringUtils.isNotEmpty(token)) 1307 { 1308 params.put("token", token); 1309 } 1310 1311 return sqlSession.selectOne(stmtId, params); 1312 } 1313 catch (Exception e) 1314 { 1315 throw new UserManagementException("Database error while getting the request for user [" + email + "] and token [" + token + "]", e); 1316 } 1317 } 1318 1319 /** 1320 * Remove the temporary . 1321 * @param siteName the site name. 1322 * @param email the user e-mail address. 1323 * @param token the request token. 1324 * @param population the population 1325 * @param userDirectoryId the id of the user directory of the population 1326 * @throws UserManagementException if an error occurs. 1327 */ 1328 protected void removeTempUser(String siteName, String email, String token, String population, String userDirectoryId) throws UserManagementException 1329 { 1330 try (SqlSession sqlSession = getSession()) 1331 { 1332 String stmtId = "UserSignupManager.removeTempUser"; 1333 1334 Map<String, Object> params = new HashMap<>(); 1335 params.put("tempUsersTable", _tempUsersTable); 1336 1337 params.put("site", siteName); 1338 params.put("email", email); 1339 params.put("token", token); 1340 params.put("population", population); 1341 params.put("userDirectory", userDirectoryId); 1342 1343 sqlSession.delete(stmtId, params); 1344 sqlSession.commit(); 1345 } 1346 catch (Exception e) 1347 { 1348 throw new UserManagementException("Database error while removing the token of user " + email, e); 1349 } 1350 } 1351 1352 /** 1353 * Remove the password change request. 1354 * @param siteName the site name. 1355 * @param login the user login. 1356 * @param token the request token. 1357 * @param population the population 1358 * @throws UserManagementException if an error occurs. 1359 */ 1360 protected void removePasswordToken(String siteName, String login, String token, String population) throws UserManagementException 1361 { 1362 try (SqlSession sqlSession = getSession()) 1363 { 1364 String stmtId = "UserSignupManager.removePasswordToken"; 1365 1366 Map<String, Object> params = new HashMap<>(); 1367 params.put("pwdChangeTable", _pwdChangeTable); 1368 1369 params.put("site", siteName); 1370 params.put("login", login); 1371 params.put("token", token); 1372 params.put("population", population); 1373 1374 sqlSession.delete(stmtId, params); 1375 sqlSession.commit(); 1376 } 1377 catch (Exception e) 1378 { 1379 throw new UserManagementException("Database error while removing the token of user " + login, e); 1380 } 1381 } 1382 1383 /** 1384 * Send a sign-up confirmation link by e-mail. 1385 * @param siteName the site name. 1386 * @param language the e-mail language. 1387 * @param user the user object. 1388 * @param token the generated token. 1389 * @throws UserManagementException if an error occurs. 1390 */ 1391 protected void sendResetPasswordMail(String siteName, String language, User user, String token) throws UserManagementException 1392 { 1393 String login = user.getIdentity().getLogin(); 1394 String population = user.getIdentity().getPopulationId(); 1395 1396 if (getLogger().isDebugEnabled()) 1397 { 1398 getLogger().debug("Sending reset password e-mail to " + login); 1399 } 1400 1401 Site site = _siteManager.getSite(siteName); 1402 String from = site.getValue("site-mail-from"); 1403 1404 // Prepare mail 1405 Map<String, I18nizableTextParameter> i18nParams = new HashMap<>(); 1406 i18nParams.put("siteName", new I18nizableText(siteName)); 1407 i18nParams.put("login", new I18nizableText(login)); 1408 i18nParams.put("email", new I18nizableText(user.getEmail())); 1409 i18nParams.put("fullName", new I18nizableText(user.getFullName())); 1410 i18nParams.put("token", new I18nizableText(token)); 1411 1412 Page passwordPage = getPwdChangePage(siteName, language); 1413 if (passwordPage != null) 1414 { 1415 if (_pageUriResolver == null) 1416 { 1417 _pageUriResolver = _uriResolverEP.getResolverForType("page"); 1418 } 1419 1420 String encodedLogin = URIUtils.encodeParameter(login); 1421 String encodedPopulation = URIUtils.encodeParameter(population); 1422 1423 // Compute the confirmation URI and add it to the parameters. 1424 String confirmUri = _pageUriResolver.resolve(passwordPage.getId(), false, true, false); 1425 confirmUri = confirmUri + "?login=" + encodedLogin + "&population=" + encodedPopulation + "&token=" + token; 1426 1427 i18nParams.put("confirmUri", new I18nizableText(confirmUri)); 1428 } 1429 1430 // Add site information in the parameters. 1431 i18nParams.put("siteTitle", new I18nizableText(site.getTitle())); 1432 i18nParams.put("siteUrl", new I18nizableText(site.getUrl())); 1433 1434 String subject = _userSignUpConfiguration.getSubjectForResetPwdEmail(i18nParams, language); 1435 String textBody = _userSignUpConfiguration.getTextBodyForResetPwdEmail(i18nParams, language); 1436 String htmlBody = _userSignUpConfiguration.getHtmlBodyForResetPwdEmail(i18nParams, language); 1437 1438 try 1439 { 1440 // Send the e-mail. 1441 SendMailHelper.newMail() 1442 .withSubject(subject) 1443 .withHTMLBody(htmlBody) 1444 .withTextBody(textBody) 1445 .withSender(from) 1446 .withRecipient(user.getEmail()) 1447 .sendMail(); 1448 } 1449 catch (MessagingException | IOException e) 1450 { 1451 throw new UserManagementException("Error sending a password reset e-mail.", e); 1452 } 1453 } 1454 1455 /** 1456 * Bean representing a user sign-up request. 1457 */ 1458 public static class TempUser 1459 { 1460 /** The site name. */ 1461 protected String _site; 1462 1463 /** The user e-mail. */ 1464 protected String _email; 1465 1466 /** The user subscription date. */ 1467 protected Date _subscriptionDate; 1468 1469 /** The request token. */ 1470 protected String _token; 1471 1472 /** The id of the population */ 1473 protected String _population; 1474 1475 /** The id of the user directory of the population */ 1476 protected String _userDirectoryId; 1477 1478 /** 1479 * Constructor. 1480 * @param site the site 1481 * @param email the user's email 1482 * @param subscriptionDate the date of subscription 1483 * @param token the user's token 1484 * @param population The id of the population 1485 * @param userDirectoryId The id of the user directory of the population 1486 */ 1487 public TempUser(String site, String email, Date subscriptionDate, String token, String population, String userDirectoryId) 1488 { 1489 this._site = site; 1490 this._email = email; 1491 this._subscriptionDate = subscriptionDate; 1492 this._token = token; 1493 this._population = population; 1494 this._userDirectoryId = userDirectoryId; 1495 } 1496 /** 1497 * Get the site. 1498 * @return the site 1499 */ 1500 public String getSite() 1501 { 1502 return _site; 1503 } 1504 /** 1505 * Set the site. 1506 * @param site the site to set 1507 */ 1508 public void setSite(String site) 1509 { 1510 this._site = site; 1511 } 1512 /** 1513 * Get the email. 1514 * @return _the email 1515 */ 1516 public String getEmail() 1517 { 1518 return _email; 1519 } 1520 /** 1521 * Set the email. 1522 * @param email the email to set 1523 */ 1524 public void setEmail(String email) 1525 { 1526 this._email = email; 1527 } 1528 /** 1529 * Get the subscriptionDate. 1530 * @return _the subscriptionDate 1531 */ 1532 public Date getSubscriptionDate() 1533 { 1534 return _subscriptionDate; 1535 } 1536 /** 1537 * Set the subscriptionDate. 1538 * @param subscriptionDate the subscriptionDate to set 1539 */ 1540 public void setSubscriptionDate(Date subscriptionDate) 1541 { 1542 this._subscriptionDate = subscriptionDate; 1543 } 1544 /** 1545 * Get the token. 1546 * @return _the token 1547 */ 1548 public String getToken() 1549 { 1550 return _token; 1551 } 1552 /** 1553 * Set the token. 1554 * @param token the token to set 1555 */ 1556 public void setToken(String token) 1557 { 1558 this._token = token; 1559 } 1560 /** 1561 * Get the population. 1562 * @return the population 1563 */ 1564 public String getPopulation() 1565 { 1566 return _population; 1567 } 1568 /** 1569 * Set the population. 1570 * @param population the population to set 1571 */ 1572 public void setPopulation(String population) 1573 { 1574 this._population = population; 1575 } 1576 /** 1577 * Get the user directory id. 1578 * @return the user directory id 1579 */ 1580 public String getUserDirectoryId() 1581 { 1582 return _userDirectoryId; 1583 } 1584 /** 1585 * Set the user directory index. 1586 * @param userDirectoryId the user directory id to set 1587 */ 1588 public void setUserDirectoryIndex(String userDirectoryId) 1589 { 1590 this._userDirectoryId = userDirectoryId; 1591 } 1592 1593 } 1594 1595}