use of com.sanctionco.thunder.validation.RequestValidationException in project thunder by RohanNagar.
the class VerificationResource method resetVerified.
/**
* Resets the verification status of the user with the given email and password.
*
* @param response the async response object used to notify that the operation has completed
* @param auth the auth principal required to access the resource
* @param email the user's email address
* @param password the user's password
*/
@POST
@Path("/reset")
@Metered(name = "reset-verification-requests")
@SwaggerAnnotations.Methods.Reset
public void resetVerified(@Suspended AsyncResponse response, @Parameter(hidden = true) @Auth Principal auth, @Parameter(hidden = true) @QueryParam("email") String email, @Parameter(hidden = true) @HeaderParam("password") String password) {
requestOptions.setTimeout(response, resetTimeoutCounter);
try {
requestValidator.validate(password, email, false);
} catch (RequestValidationException e) {
response.resume(e.response(email));
return;
}
LOG.info("Attempting to reset verification status for user {}", email);
usersDao.findByEmail(email).thenApply(user -> {
// Check that the supplied password is correct for the user's account
requestValidator.verifyPasswordHeader(password, user.getPassword());
return new User(new Email(user.getEmail().getAddress(), false, null), user.getPassword(), user.getProperties());
}).thenCompose(user -> usersDao.update(null, user)).whenComplete((result, throwable) -> {
if (Objects.isNull(throwable)) {
LOG.info("Successfully reset verification status for user {}.", email);
response.resume(Response.ok(result).build());
} else {
LOG.error("Error resetting status of {}. Caused by {}", email, throwable.getMessage());
response.resume(ThunderException.responseFromThrowable(throwable, email));
}
});
}
use of com.sanctionco.thunder.validation.RequestValidationException in project thunder by RohanNagar.
the class UserResource method updateUser.
/**
* Updates the user in the database.
*
* @param response the async response object used to notify that the operation has completed
* @param auth the auth principal required to access the resource
* @param password the user's password. This should be the existing password prior to any updates.
* @param existingEmail the user's existing email. This can be {@code null} if the user's email
* will stay the same. It must be present if the email is to be changed.
* @param user the user with updated properties
*/
@PUT
@Metered(name = "update-requests")
@SwaggerAnnotations.Methods.Update
public void updateUser(@Suspended AsyncResponse response, @Parameter(hidden = true) @Auth Principal auth, @Parameter(hidden = true) @HeaderParam("password") String password, @Parameter(hidden = true) @QueryParam("email") String existingEmail, User user) {
requestOptions.setTimeout(response, updateTimeoutCounter);
try {
requestValidator.validate(password, existingEmail, user);
} catch (RequestValidationException e) {
response.resume(e.response(Optional.ofNullable(existingEmail).orElseGet(() -> Optional.ofNullable(user).map(User::getEmail).map(Email::getAddress).orElse("null"))));
return;
}
// Get the current email address for the user
String email = Optional.ofNullable(existingEmail).orElse(user.getEmail().getAddress());
LOG.info("Attempting to update user with existing email address {}.", email);
usersDao.findByEmail(email).thenApply(foundUser -> {
// Check that the password is correct for the user to update
requestValidator.verifyPasswordHeader(password, foundUser.getPassword());
// Determine what verification information to use for the updated user object.
// If it's a new email address, reset verification status.
// If it's the same, keep the existing verification status.
boolean verified = email.equals(user.getEmail().getAddress()) && foundUser.getEmail().isVerified();
String verificationToken = email.equals(user.getEmail().getAddress()) ? foundUser.getEmail().getVerificationToken() : null;
// Hash the password if it is a new password
String finalPassword = foundUser.getPassword();
if (!hashService.isMatch(user.getPassword(), foundUser.getPassword())) {
finalPassword = hashService.hash(user.getPassword());
}
LOG.info("Using verified status: {} and token: {} for the updated user.", verified, verificationToken);
return new User(new Email(user.getEmail().getAddress(), verified, verificationToken), finalPassword, user.getProperties());
}).thenCompose(updatedUser -> usersDao.update(existingEmail, updatedUser)).whenComplete((result, throwable) -> {
if (Objects.isNull(throwable)) {
LOG.info("Successfully updated user {}.", email);
response.resume(Response.ok(result).build());
} else {
LOG.error("Error updating user {}. Caused by: {}", email, throwable.getMessage());
response.resume(ThunderException.responseFromThrowable(throwable, email));
}
});
}
use of com.sanctionco.thunder.validation.RequestValidationException in project thunder by RohanNagar.
the class UserResource method postUser.
/**
* Creates a new user in the database.
*
* @param response the async response object used to notify that the operation has completed
* @param auth the auth principal required to access the resource
* @param user the user to create in the database
*/
@POST
@Metered(name = "post-requests")
@SwaggerAnnotations.Methods.Create
public void postUser(@Suspended AsyncResponse response, @Parameter(hidden = true) @Auth Principal auth, User user) {
requestOptions.setTimeout(response, createTimeoutCounter);
try {
requestValidator.validate(user);
} catch (RequestValidationException exception) {
response.resume(exception.response(Optional.ofNullable(user).map(User::getEmail).map(Email::getAddress).orElse("null")));
return;
}
String email = user.getEmail().getAddress();
LOG.info("Attempting to create new user {}.", email);
// Hash the user's password
String finalPassword = hashService.hash(user.getPassword());
// Make sure the user is not verified, as this is a new user
User userToInsert = new User(Email.unverified(email), finalPassword, user.getProperties());
usersDao.insert(userToInsert).whenComplete((result, throwable) -> {
if (Objects.isNull(throwable)) {
LOG.info("Successfully created new user {}.", result.getEmail().getAddress());
response.resume(Response.status(Response.Status.CREATED).entity(result).build());
} else {
LOG.error("Error creating new user {}. Caused by {}", email, throwable.getMessage());
response.resume(ThunderException.responseFromThrowable(throwable, email));
}
});
}
use of com.sanctionco.thunder.validation.RequestValidationException in project thunder by RohanNagar.
the class VerificationResource method sendEmail.
/**
* Sends an email message to the given email address. The email message will contain
* a custom URL that can be called to verify the email address. This method will update the user
* in the database to include the generated verification token.
*
* @param uriInfo the HTTP metadata of the incoming request
* @param response the async response object used to notify that the operation has completed
* @param auth the auth principal required to access the resource
* @param email the message recipient's email address
* @param password the user's password
*
* @see VerificationResource#verifyEmail(AsyncResponse, String, String, ResponseType)
*/
@POST
@Metered(name = "send-email-requests")
@SwaggerAnnotations.Methods.Email
public void sendEmail(@Context UriInfo uriInfo, @Suspended AsyncResponse response, @Parameter(hidden = true) @Auth Principal auth, @Parameter(hidden = true) @QueryParam("email") String email, @Parameter(hidden = true) @HeaderParam("password") String password) {
requestOptions.setTimeout(response, sendEmailTimeoutCounter);
try {
requestValidator.validate(password, email, false);
} catch (RequestValidationException e) {
response.resume(e.response(email));
return;
}
LOG.info("Attempting to send verification email to user {}", email);
usersDao.findByEmail(email).thenApply(user -> {
// Check that the supplied password is correct for the user's account
requestValidator.verifyPasswordHeader(password, user.getPassword());
// Generate the unique verification token
String token = generateVerificationToken();
// Update the user's verification token
return new User(new Email(user.getEmail().getAddress(), false, token), user.getPassword(), user.getProperties());
}).thenCompose(user -> usersDao.update(user.getEmail().getAddress(), user)).thenCompose(result -> {
// Build the verification URL
String verificationUrl = uriInfo.getBaseUriBuilder().path("/verify").queryParam("email", result.getEmail().getAddress()).queryParam("token", result.getEmail().getVerificationToken()).queryParam("response_type", "html").build().toString();
LOG.info("Built verification URL {}", verificationUrl);
// Send the email to the user's email address
return emailService.sendVerificationEmail(result.getEmail(), verificationUrl).thenApply(success -> {
if (!success) {
LOG.error("Error sending email to address {}", result.getEmail().getAddress());
throw new ThunderException("An error occurred while attempting to send email.");
}
return result;
});
}).whenComplete((result, throwable) -> {
if (Objects.isNull(throwable)) {
LOG.info("Successfully sent verification email to user {}.", email);
response.resume(Response.ok(result).build());
} else {
LOG.error("Error sending email to {}. Caused by: {}", email, throwable.getMessage());
response.resume(ThunderException.responseFromThrowable(throwable, email));
}
});
}
use of com.sanctionco.thunder.validation.RequestValidationException in project thunder by RohanNagar.
the class VerificationResource method verifyEmail.
/**
* Verifies the given email, marking it as verified in the database if the token matches the
* stored verification token. Depending on the given response type, the method will either return
* a response that contains the updated verified user or will redirect to an HTML success page.
*
* @param response the async response object used to notify that the operation has completed
* @param email the email to verify
* @param token the verification token associated with the email
* @param responseType the type of object to include in the HTTP response. Either JSON or HTML.
*
* @see VerificationResource#sendEmail(UriInfo, AsyncResponse, Principal, String, String)
* @see VerificationResource#getSuccessHtml()
*/
@GET
@Metered(name = "verify-email-requests")
@SwaggerAnnotations.Methods.Verify
public void verifyEmail(@Suspended AsyncResponse response, @Parameter(hidden = true) @QueryParam("email") String email, @Parameter(hidden = true) @QueryParam("token") String token, @Parameter(hidden = true) @QueryParam("response_type") @DefaultValue("json") ResponseType responseType) {
requestOptions.setTimeout(response, verifyTimeoutCounter);
try {
requestValidator.validate(token, email, true);
} catch (RequestValidationException e) {
response.resume(e.response(email));
return;
}
LOG.info("Attempting to verify email {}", email);
usersDao.findByEmail(email).thenApply(user -> {
String verificationToken = user.getEmail().getVerificationToken();
if (verificationToken == null || verificationToken.isEmpty()) {
LOG.warn("Tried to read null or empty verification token");
throw RequestValidationException.tokenNotSet("Bad value found for user verification token.");
}
if (!token.equals(verificationToken)) {
LOG.warn("User provided verification token does not match DB verification token.");
throw RequestValidationException.incorrectToken("Incorrect verification token.");
}
// Create the verified user
return new User(user.getEmail().verifiedCopy(), user.getPassword(), user.getProperties());
}).thenCompose(updatedUser -> usersDao.update(email, updatedUser)).whenComplete((result, throwable) -> {
if (Objects.isNull(throwable)) {
LOG.info("Successfully verified email {}.", email);
if (responseType.equals(ResponseType.JSON)) {
LOG.info("Returning JSON in the response.");
response.resume(Response.ok(result).build());
} else {
LOG.info("Redirecting to /verify/success in order to return HTML.");
URI uri = UriBuilder.fromUri("/verify/success").build();
response.resume(Response.seeOther(uri).build());
}
} else {
LOG.error("Error verifying email {}. Caused by: {}", email, throwable.getMessage());
response.resume(ThunderException.responseFromThrowable(throwable, email));
}
});
}
Aggregations