diff --git a/src/main/java/fr/lirmm/aren/model/ws/ResetPassword.java b/src/main/java/fr/lirmm/aren/model/ws/ResetPassword.java new file mode 100644 index 0000000..7ded45f --- /dev/null +++ b/src/main/java/fr/lirmm/aren/model/ws/ResetPassword.java @@ -0,0 +1,27 @@ +package fr.lirmm.aren.model.ws; + +/** + * @author ANDRIAMBOLAHARIMIHANTA Havana on 24/06/2021 + * @project aren-1 + */ +public class ResetPassword { + private String password; + public ResetPassword() { + } + + /** + * + * @return + */ + public String getPassword() { + return password; + } + + /** + * + * @param password + */ + public void setPassword(String password) { + this.password = password; + } +} diff --git a/src/main/java/fr/lirmm/aren/ws/rest/UserRESTFacade.java b/src/main/java/fr/lirmm/aren/ws/rest/UserRESTFacade.java index e2c5892..bd96169 100644 --- a/src/main/java/fr/lirmm/aren/ws/rest/UserRESTFacade.java +++ b/src/main/java/fr/lirmm/aren/ws/rest/UserRESTFacade.java @@ -7,6 +7,7 @@ import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.QueryParam; +import fr.lirmm.aren.model.ws.ResetPassword; import fr.lirmm.aren.service.InstitutionService; import fr.lirmm.aren.service.UserService; import fr.lirmm.aren.exception.AccessDeniedException; @@ -222,7 +223,6 @@ public class UserRESTFacade extends AbstractRESTFacade { * @param user * @param subject * @param body - * @param defautReturnUrl */ private void sendLink(User user, String subject, String body) throws MessagingException { Locale currentLocale = request.getLocale(); @@ -252,6 +252,34 @@ public class UserRESTFacade extends AbstractRESTFacade { mailingService.sendMail(application_config.getString("smtp.username"), user.getEmail(), localSubject, localBody); } + private void sendLinkResetPassword(User user, String subject, String body) throws MessagingException { + Locale currentLocale = request.getLocale(); + ResourceBundle messages = ResourceBundle.getBundle("messages", currentLocale); + ResourceBundle application_config = ResourceBundle.getBundle("application", currentLocale); + + + String token = authenticationTokenService.issueToken(user, 24L * 60 * 60); + System.out.println(authenticationTokenService.parseToken(token).getIssuedDate()); + String activationLink; + String localSubject; + String localBody; + + String serverRoot = this.reverseProxy; + if (serverRoot.length() == 0) { + serverRoot=request.getRequestURL().substring(0, request.getRequestURL().length() - "/ws/users/resetPasswd".length()) ; + } + + if (returnUrl != null && !returnUrl.isEmpty()) { + activationLink = serverRoot + returnUrl.replace("{token}", token); + localSubject = messages.getString(subject); + localBody = MessageFormat.format(messages.getString(body), activationLink, activationLink); + } else { + localSubject = "AREN API token"; + localBody = token; + } + mailingService.sendMail(application_config.getString("smtp.username"), user.getEmail(), localSubject, localBody); + } + /** * Mark a User as being activated after having clik in the mail link * @@ -277,7 +305,7 @@ public class UserRESTFacade extends AbstractRESTFacade { User user = getService().findByUsernameOrEmail(identifier); if (user != null && user.isActive()) { try { - sendLink(user, "mail_reset_password_subject", "mail_reset_password_body"); + sendLinkResetPassword(user, "mail_reset_password_subject", "mail_reset_password_body"); } catch (MessagingException ex) { throw new RuntimeException(); } @@ -285,6 +313,26 @@ public class UserRESTFacade extends AbstractRESTFacade { // else nothing happend, it avoids someone to bruteforce user } + @PUT + @Path("resetPswd") + @RolesAllowed({"USER"}) + public void resetPasswd(ResetPassword resetPasswd, @QueryParam("token") String token) { + // Mail token are 24h long, login token are 1 year long + // If this is a token from a mail, then it comes from a password reset requests + // so we do not check the old password + if (token != null && !token.isEmpty()) { + AuthenticationTokenDetails authToken = authenticationTokenService.parseToken(token); + if (authToken.getIssuedDate().plusSeconds(24 * 3600).isEqual(authToken.getExpirationDate())) { + userService.changePassword(getUser(), resetPasswd.getPassword()); + getService().invalidateToken(getUser()); + return; + } + } + authentificationService.validateCredentials(getUser().getUsername(), resetPasswd.getPassword()); + userService.changePassword(getUser(), resetPasswd.getPassword()); + getService().invalidateToken(getUser()); + } + /** * Mark a User as being removed without deleting its associated datas *