Skip to content

Commit

Permalink
Refactor Registration workflow
Browse files Browse the repository at this point in the history
Signed-off-by: Mykhailo Marchuk <[email protected]>
  • Loading branch information
marchuk-engineer committed Jun 5, 2024
1 parent 13674fd commit 2dd735d
Show file tree
Hide file tree
Showing 12 changed files with 33 additions and 67 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.booking.app.controller;

import com.booking.app.annotation.GlobalApiResponses;
import com.booking.app.dto.EmailDto;
import com.booking.app.dto.RegistrationDTO;
import com.booking.app.enums.ContentLanguage;
import com.booking.app.exception.ErrorDetails;
Expand All @@ -18,7 +17,6 @@
import lombok.AllArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import static com.booking.app.constant.ApiMessagesConstants.INVALID_CONTENT_LANGUAGE_HEADER_MESSAGE;
Expand All @@ -42,7 +40,6 @@ public class RegistrationController {
*
* @param language the language of the site
* @param dto the registration data transfer object
* @return a ResponseEntity containing the email data transfer object
* @throws MessagingException if an error occurs while sending the email
*/
@PostMapping("/sign-up")
Expand All @@ -54,11 +51,10 @@ public class RegistrationController {
+ EMAIL_IS_ALREADY_TAKEN_MESSAGE),
@ApiResponse(responseCode = "400", description = INVALID_CONTENT_LANGUAGE_HEADER_MESSAGE + " OR " + "Invalid request body", content = @Content(schema = @Schema(implementation = ErrorDetails.class), mediaType = MediaType.APPLICATION_JSON_VALUE))
})
public ResponseEntity<?> signUp(@RequestHeader(HttpHeaders.CONTENT_LANGUAGE) @Parameter(required = true, description = "Content Language", schema = @Schema(type = "string", allowableValues = {"eng", "ua"})) ContentLanguage language,
@RequestBody @Valid @NotNull RegistrationDTO dto) throws
public void signUp(@RequestHeader(HttpHeaders.CONTENT_LANGUAGE) @Parameter(required = true, description = "Content Language", schema = @Schema(type = "string", allowableValues = {"eng", "ua"})) ContentLanguage language,
@RequestBody @Valid @NotNull RegistrationDTO dto) throws
MessagingException {
EmailDto register = registrationService.register(dto, language.getLanguage());
return ResponseEntity.ok().body(register);
registrationService.register(dto, language.getLanguage());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public class UserVerifierController {
})
public void sendResetCode(@RequestBody @NotNull @Valid EmailDto dto,
@RequestHeader(HttpHeaders.CONTENT_LANGUAGE) @Parameter(required = true, description = "Content Language", schema = @Schema(type = "string", allowableValues = {"eng", "ua"})) ContentLanguage language) {
mailSenderService.sendResetPasswordCode(dto.getEmail(), language.getLanguage());
mailSenderService.sendResetCode(dto.getEmail(), language.getLanguage());
}

@PostMapping("/verification-code/send")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,19 +101,6 @@ public ResponseEntity<ErrorDetails> passwordMatches(PasswordNotMatchesException
return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
}

@ResponseStatus(HttpStatus.CONFLICT)
@ExceptionHandler(UserNotConfirmedException.class)
public ResponseEntity<ErrorDetails> passwordMatches(UserNotConfirmedException exception, WebRequest webRequest) {

ErrorDetails errorDetails = new ErrorDetails(
LocalDateTime.now(),
exception.getMessage(),
webRequest.getDescription(false),
HttpStatus.CONFLICT
);
return new ResponseEntity<>(errorDetails, HttpStatus.CONFLICT);
}

@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(EmailAlreadyTakenException.class)
public ResponseEntity<ErrorDetails> emailExists(EmailAlreadyTakenException exception, WebRequest webRequest) {
Expand Down Expand Up @@ -180,8 +167,8 @@ public ResponseEntity<ErrorDetails> invalidConfirmationCode(InvalidConfirmationC
}

@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(UserIsDisabledException.class)
public ResponseEntity<ErrorDetails> userIsDisabled(UserIsDisabledException exception, WebRequest webRequest) {
@ExceptionHandler(UserNotConfirmedException.class)
public ResponseEntity<ErrorDetails> userIsDisabled(UserNotConfirmedException exception, WebRequest webRequest) {
ErrorDetails errorDetails = new ErrorDetails(
LocalDateTime.now(),
exception.getMessage(),
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.booking.app.exception.exception;

public class UserNotConfirmedException extends RuntimeException {
private static final String MESSAGE_USER_IS_DISABLED = "User is not activated, try to sign up.";

public UserNotConfirmedException(String message) {
super(message);
public UserNotConfirmedException() {
super(MESSAGE_USER_IS_DISABLED);
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ public interface MailSenderService {
* @param email the email address to send the reset code to
* @param language the language preference for the email content
*/
void sendResetPasswordCode(String email, String language);
void sendResetCode(String email, String language);

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.booking.app.services;

import com.booking.app.dto.EmailDto;
import com.booking.app.dto.RegistrationDTO;
import jakarta.mail.MessagingException;
import org.springframework.validation.annotation.Validated;
Expand All @@ -16,9 +15,8 @@ public interface RegistrationService {
*
* @param dto the data transfer object containing user registration details
* @param language the language for the email template
* @return an EmailDTO containing the email information of the registered user
* @throws MessagingException if there is an error sending the confirmation email
*/
EmailDto register(RegistrationDTO dto, String language) throws MessagingException;
void register(RegistrationDTO dto, String language) throws MessagingException;

}
6 changes: 3 additions & 3 deletions src/main/java/com/booking/app/services/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import com.booking.app.dto.RegistrationDTO;
import com.booking.app.dto.RequestTicketsDto;
import com.booking.app.entity.User;
import com.booking.app.exception.exception.UserIsDisabledException;
import com.booking.app.exception.exception.UserNotConfirmedException;

import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -42,9 +42,9 @@ public interface UserService {
*
* @param user The user to be checked.
* @return True if user are enabled, otherwise throws UserIsDisabledException.
* @throws UserIsDisabledException If user is disabled.
* @throws UserNotConfirmedException If user is disabled.
*/
boolean isEnabled(User user) throws UserIsDisabledException;
boolean isEnabled(User user) throws UserNotConfirmedException;

/**
* Updates the password for a user.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,23 +45,24 @@ public void sendVerificationCode(String email, String language) {
user.setConfirmationCode(newCode);

confirmationCodeService.updateConfirmationCode(newCode, existingCode);
sendEmail(language, EMAIL_CONFIRMATION_SUBJECT, newCode.getCode(), user);

String templateName = HtmlTemplateUtils.getConfirmationTemplate(language);
sendEmail(templateName, EMAIL_CONFIRMATION_SUBJECT, newCode.getCode(), user);
}, () -> {
throw new UserNotFoundException();
});
}

// todo check workflow of both methods and its calling service
@Override
public void sendResetPasswordCode(String email, String language) {
public void sendResetCode(String email, String language) {
userService.findByEmail(email)
.ifPresentOrElse(user -> {
if (userService.isEnabled(user)) {
ConfirmationCode newCode = ConfirmationCode.createCode();
user.setConfirmationCode(newCode);

String htmlTemplate = HtmlTemplateUtils.getResetPasswordHtmlTemplate(language);
sendEmail(htmlTemplate, RESET_PASSWORD_SUBJECT, newCode.getCode(), user);
String templateName = HtmlTemplateUtils.getResetPasswordTemplate(language);
sendEmail(templateName, RESET_PASSWORD_SUBJECT, newCode.getCode(), user);
confirmationCodeService.save(newCode);
}
},
Expand All @@ -73,18 +74,17 @@ public void sendResetPasswordCode(String email, String language) {
/**
* Sends an email with a confirmation token to the user.
*
* @param language the language preference for the email content
* @param subject the subject of the email
* @param token the confirmation token to be included in the email
* @param user the user credentials containing the recipient's email and username
* @param templateName the HTML template name
* @param subject the subject of the email
* @param token the confirmation token to be included in the email
* @param user the user credentials containing the recipient's email and username
*/
private void sendEmail(String language, String subject, String token, User user) {
String htmlPageName = HtmlTemplateUtils.getConfirmationHtmlTemplate(language);
private void sendEmail(String templateName, String subject, String token, User user) {
Context context = new Context();
context.setVariable("token", token);
context.setVariable("nickname", user.getUsername());

String process = templateEngine.process(htmlPageName, context);
String process = templateEngine.process(templateName, context);

MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
package com.booking.app.services.impl;

import com.booking.app.dto.EmailDto;
import com.booking.app.dto.RegistrationDTO;
import com.booking.app.entity.User;
import com.booking.app.exception.exception.EmailAlreadyTakenException;
import com.booking.app.mapper.UserMapper;
import com.booking.app.services.ConfirmationCodeService;
import com.booking.app.services.MailSenderService;
import com.booking.app.services.RegistrationService;
import com.booking.app.services.UserService;
Expand All @@ -26,17 +23,14 @@
public class RegistrationServiceImpl implements RegistrationService {

private final UserService userService;
private final UserMapper mapper;
private final MailSenderService mailService;
private final ConfirmationCodeService confirmationCodeService;

@Override
@Transactional
public EmailDto register(RegistrationDTO dto, String language) throws MessagingException {
public void register(RegistrationDTO dto, String language) throws MessagingException {
User user = findOrCreateUser(dto);
mailService.sendVerificationCode(user.getEmail(), language);
log.info("User with ID: {} has successfully registered.", user.getId());
return mapper.toEmailDto(user);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import com.booking.app.enums.SocialProvider;
import com.booking.app.enums.TransportType;
import com.booking.app.exception.exception.InvalidConfirmationCodeException;
import com.booking.app.exception.exception.UserIsDisabledException;
import com.booking.app.exception.exception.UserNotConfirmedException;
import com.booking.app.exception.exception.UserNotFoundException;
import com.booking.app.mapper.HistoryMapper;
import com.booking.app.mapper.UserMapper;
Expand Down Expand Up @@ -81,11 +81,11 @@ public User save(User user) {
}

@Override
public boolean isEnabled(User user) throws UserIsDisabledException {
public boolean isEnabled(User user) throws UserNotConfirmedException {
if (user.isEnabled()) {
return true;
} else {
throw new UserIsDisabledException();
throw new UserNotConfirmedException();
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/booking/app/util/HtmlTemplateUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class HtmlTemplateUtils {
* @param language Language ua/eng
* @return HTML template name
*/
public static String getConfirmationHtmlTemplate(String language) {
public static String getConfirmationTemplate(String language) {
return switch (language) {
case ("ua") -> "confirmMailUa";
case ("eng") -> "confirmMailEng";
Expand All @@ -29,7 +29,7 @@ public static String getConfirmationHtmlTemplate(String language) {
* @param language Language ua/eng
* @return HTML template name
*/
public static String getResetPasswordHtmlTemplate(String language) {
public static String getResetPasswordTemplate(String language) {
return switch (language) {
case ("ua") -> "resetPasswordUa";
case ("eng") -> "resetPasswordEng";
Expand Down

0 comments on commit 2dd735d

Please sign in to comment.