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);
}
}
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'");
}
}
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);
}
}
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());
}
}
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());
}
}
Aggregations