Search in sources :

Example 1 with UserPasswordResetToken

use of org.haiku.haikudepotserver.dataobjects.UserPasswordResetToken in project haikudepotserver by haiku.

the class PasswordResetServiceImpl method createTokenAndInvite.

/**
 * <p>This method will create a user password reset token and will also email the user
 * about it so that they are able to click on a link in the email, visit the application
 * server and get their password changed.</p>
 */
private void createTokenAndInvite(User user) throws PasswordResetException {
    Preconditions.checkArgument(null != user, "the user must be provided");
    Preconditions.checkState(!Strings.isNullOrEmpty(user.getEmail()), "the user must have an email configured");
    ObjectContext contextLocal = serverRuntime.newContext();
    User userLocal = User.getByObjectId(contextLocal, user.getObjectId());
    UserPasswordResetToken userPasswordResetToken = contextLocal.newObject(UserPasswordResetToken.class);
    userPasswordResetToken.setUser(userLocal);
    userPasswordResetToken.setCode(UUID.randomUUID().toString());
    userPasswordResetToken.setCreateTimestamp(new java.sql.Timestamp(Clock.systemUTC().millis()));
    PasswordResetMail mailModel = new PasswordResetMail();
    mailModel.setPasswordResetBaseUrl(baseUrl + "/" + URL_SEGMENT_PASSWORDRESET + "/");
    mailModel.setUserNickname(user.getNickname());
    mailModel.setUserPasswordResetTokenCode(userPasswordResetToken.getCode());
    SimpleMailMessage message = new SimpleMailMessage();
    message.setFrom(from);
    message.setTo(user.getEmail());
    message.setSubject(fillFreemarkerTemplate(mailModel, MAIL_SUBJECT, user.getNaturalLanguage()));
    message.setText(fillFreemarkerTemplate(mailModel, MAIL_PLAINTEXT, user.getNaturalLanguage()));
    contextLocal.commitChanges();
    try {
        this.mailSender.send(message);
    } catch (MailException me) {
        throw new PasswordResetException("the password reset email to " + user.toString() + " was not able to be sent", me);
    }
}
Also used : User(org.haiku.haikudepotserver.dataobjects.User) UserPasswordResetToken(org.haiku.haikudepotserver.dataobjects.UserPasswordResetToken) SimpleMailMessage(org.springframework.mail.SimpleMailMessage) PasswordResetMail(org.haiku.haikudepotserver.passwordreset.model.PasswordResetMail) ObjectContext(org.apache.cayenne.ObjectContext) MailException(org.springframework.mail.MailException)

Example 2 with UserPasswordResetToken

use of org.haiku.haikudepotserver.dataobjects.UserPasswordResetToken in project haikudepotserver by haiku.

the class UserApiIT method getOnlyPasswordResetTokenCodeForTestUser.

private String getOnlyPasswordResetTokenCodeForTestUser() {
    ObjectContext context = serverRuntime.newContext();
    List<UserPasswordResetToken> tokens = UserPasswordResetToken.findByUser(context, User.tryGetByNickname(context, "testuser").get());
    switch(tokens.size()) {
        case 0:
            return null;
        case 1:
            return tokens.get(0).getCode();
        default:
            throw new IllegalStateException("more than one password reset token for the user 'testuser'");
    }
}
Also used : UserPasswordResetToken(org.haiku.haikudepotserver.dataobjects.UserPasswordResetToken) ObjectContext(org.apache.cayenne.ObjectContext)

Example 3 with UserPasswordResetToken

use of org.haiku.haikudepotserver.dataobjects.UserPasswordResetToken in project haikudepotserver by haiku.

the class PasswordResetServiceImpl method complete.

@Override
public void complete(String tokenCode, String passwordClear) {
    Preconditions.checkArgument(!Strings.isNullOrEmpty(tokenCode), "the token code must be provided");
    Preconditions.checkArgument(!Strings.isNullOrEmpty(passwordClear), "the pssword clear must be provided");
    Instant now = Instant.now();
    try {
        if (!Strings.isNullOrEmpty(tokenCode)) {
            ObjectContext context = serverRuntime.newContext();
            Optional<UserPasswordResetToken> tokenOptional = UserPasswordResetToken.getByCode(context, tokenCode);
            if (tokenOptional.isPresent()) {
                try {
                    UserPasswordResetToken token = tokenOptional.get();
                    if (token.getCreateTimestamp().getTime() > now.minus(timeToLiveHours, ChronoUnit.HOURS).toEpochMilli()) {
                        User user = token.getUser();
                        if (user.getActive()) {
                            if (!Strings.isNullOrEmpty(passwordClear) && userAuthenticationService.validatePassword(passwordClear)) {
                                userAuthenticationService.setPassword(user, passwordClear);
                                context.deleteObjects(token);
                                context.commitChanges();
                                LOGGER.info("did reset the password for; {}", user.toString());
                            } else {
                                LOGGER.warn("the password has been supplied as invalid; will ignore");
                            }
                        } else {
                            LOGGER.warn("the user having their password reset is inactive; will ignore");
                        }
                    } else {
                        LOGGER.warn("the token used to reset the password is expired; will ignore");
                    }
                } finally {
                    // open a new context so that just in case something goes wrong / invalid in the other context,
                    // that the deletion of the token can still proceed.
                    ObjectContext deleteContext = serverRuntime.newContext();
                    Optional<UserPasswordResetToken> deleteTokenOptional = UserPasswordResetToken.getByCode(deleteContext, tokenCode);
                    if (deleteTokenOptional.isPresent()) {
                        deleteContext.deleteObjects(deleteTokenOptional.get());
                        deleteContext.commitChanges();
                        LOGGER.info("did delete user password reset token {} after having processed it", tokenCode);
                    }
                }
            } else {
                LOGGER.warn("unable to find the user password reset token {}; will ignore", tokenCode);
            }
        } else {
            LOGGER.warn("the code has been supplied as null when attempting to reset a password; will ignore");
        }
    } catch (Throwable th) {
        LOGGER.error("unable to reset the password from a token", th);
    }
}
Also used : User(org.haiku.haikudepotserver.dataobjects.User) UserPasswordResetToken(org.haiku.haikudepotserver.dataobjects.UserPasswordResetToken) Instant(java.time.Instant) ObjectContext(org.apache.cayenne.ObjectContext)

Example 4 with UserPasswordResetToken

use of org.haiku.haikudepotserver.dataobjects.UserPasswordResetToken in project haikudepotserver by haiku.

the class PasswordResetServiceImpl method deleteExpiredPasswordResetTokens.

@Override
public void deleteExpiredPasswordResetTokens() {
    ObjectContext context = serverRuntime.newContext();
    Instant now = Instant.now();
    List<UserPasswordResetToken> tokens = ObjectSelect.query(UserPasswordResetToken.class).where(UserPasswordResetToken.CREATE_TIMESTAMP.lt(new java.sql.Timestamp(now.minus(timeToLiveHours, ChronoUnit.HOURS).toEpochMilli()))).select(context);
    if (tokens.isEmpty()) {
        LOGGER.debug("no expired tokens to delete");
    } else {
        context.deleteObjects(tokens.toArray(new UserPasswordResetToken[tokens.size()]));
        context.commitChanges();
        LOGGER.info("did delete {} expired tokens", tokens.size());
    }
}
Also used : UserPasswordResetToken(org.haiku.haikudepotserver.dataobjects.UserPasswordResetToken) Instant(java.time.Instant) ObjectContext(org.apache.cayenne.ObjectContext)

Example 5 with UserPasswordResetToken

use of org.haiku.haikudepotserver.dataobjects.UserPasswordResetToken in project haikudepotserver by haiku.

the class UserApiIT method testInitiatePasswordReset.

/**
 * <p>This test will check the initiation of the password reset procedure.</p>
 */
@Test
public void testInitiatePasswordReset() {
    createPasswordResetTestUser();
    Captcha captcha = captchaService.generate();
    InitiatePasswordResetRequest request = new InitiatePasswordResetRequest();
    request.captchaToken = captcha.getToken();
    request.captchaResponse = captcha.getResponse();
    request.email = "integration-test-recipient@haiku-os.org";
    // ------------------------------------
    userApi.initiatePasswordReset(request);
    // ------------------------------------
    {
        ObjectContext context = serverRuntime.newContext();
        User user = User.tryGetByNickname(context, "testuser").get();
        // check for the presence of a token.
        List<UserPasswordResetToken> tokens = UserPasswordResetToken.findByUser(context, user);
        Assertions.assertThat(tokens.size()).isEqualTo(1);
        UserPasswordResetToken token = tokens.get(0);
        // check that an email did actually get sent.
        List<SimpleMailMessage> messages = mailSender.getSentMessages();
        Assertions.assertThat(messages.size()).isEqualTo(1);
        SimpleMailMessage message = messages.get(0);
        Assertions.assertThat(message.getTo()).isEqualTo(new String[] { "integration-test-recipient@haiku-os.org" });
        Assertions.assertThat(message.getFrom()).isEqualTo("integration-test-sender@haiku-os.org");
        Assertions.assertThat(message.getText()).contains(token.getCode());
    }
}
Also used : Captcha(org.haiku.haikudepotserver.captcha.model.Captcha) User(org.haiku.haikudepotserver.dataobjects.User) UserPasswordResetToken(org.haiku.haikudepotserver.dataobjects.UserPasswordResetToken) SimpleMailMessage(org.springframework.mail.SimpleMailMessage) InitiatePasswordResetRequest(org.haiku.haikudepotserver.api1.model.user.InitiatePasswordResetRequest) List(java.util.List) ObjectContext(org.apache.cayenne.ObjectContext) AbstractIntegrationTest(org.haiku.haikudepotserver.AbstractIntegrationTest) Test(org.junit.jupiter.api.Test)

Aggregations

ObjectContext (org.apache.cayenne.ObjectContext)5 UserPasswordResetToken (org.haiku.haikudepotserver.dataobjects.UserPasswordResetToken)5 User (org.haiku.haikudepotserver.dataobjects.User)3 Instant (java.time.Instant)2 SimpleMailMessage (org.springframework.mail.SimpleMailMessage)2 List (java.util.List)1 AbstractIntegrationTest (org.haiku.haikudepotserver.AbstractIntegrationTest)1 InitiatePasswordResetRequest (org.haiku.haikudepotserver.api1.model.user.InitiatePasswordResetRequest)1 Captcha (org.haiku.haikudepotserver.captcha.model.Captcha)1 PasswordResetMail (org.haiku.haikudepotserver.passwordreset.model.PasswordResetMail)1 Test (org.junit.jupiter.api.Test)1 MailException (org.springframework.mail.MailException)1