From 569321ffa871195c4f7755704d1f6d48ed325d82 Mon Sep 17 00:00:00 2001 From: Art Date: Tue, 7 Sep 2021 14:00:06 +0300 Subject: [PATCH] 48. User registration - Implementation (#4) --- .../backend/repository/UserRepository.java | 6 +- .../backend/service/UserServiceImpl.java | 107 ++++++++++++++++++ 2 files changed, 112 insertions(+), 1 deletion(-) diff --git a/support-portal-backend/src/main/java/net/shyshkin/study/fullstack/supportportal/backend/repository/UserRepository.java b/support-portal-backend/src/main/java/net/shyshkin/study/fullstack/supportportal/backend/repository/UserRepository.java index 9224fe4..a7cf38c 100644 --- a/support-portal-backend/src/main/java/net/shyshkin/study/fullstack/supportportal/backend/repository/UserRepository.java +++ b/support-portal-backend/src/main/java/net/shyshkin/study/fullstack/supportportal/backend/repository/UserRepository.java @@ -9,6 +9,10 @@ public interface UserRepository extends JpaRepository { Optional findByUsername(String username); - Optional findAllByEmail(String email); + Optional findByEmail(String email); + + Boolean existsByUsername(String username); + + Boolean existsByEmail(String email); } diff --git a/support-portal-backend/src/main/java/net/shyshkin/study/fullstack/supportportal/backend/service/UserServiceImpl.java b/support-portal-backend/src/main/java/net/shyshkin/study/fullstack/supportportal/backend/service/UserServiceImpl.java index 9cff75c..5311ead 100644 --- a/support-portal-backend/src/main/java/net/shyshkin/study/fullstack/supportportal/backend/service/UserServiceImpl.java +++ b/support-portal-backend/src/main/java/net/shyshkin/study/fullstack/supportportal/backend/service/UserServiceImpl.java @@ -1,21 +1,35 @@ package net.shyshkin.study.fullstack.supportportal.backend.service; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import net.shyshkin.study.fullstack.supportportal.backend.domain.Role; import net.shyshkin.study.fullstack.supportportal.backend.domain.User; import net.shyshkin.study.fullstack.supportportal.backend.domain.UserPrincipal; +import net.shyshkin.study.fullstack.supportportal.backend.exception.domain.EmailExistsException; +import net.shyshkin.study.fullstack.supportportal.backend.exception.domain.EmailNotFoundException; +import net.shyshkin.study.fullstack.supportportal.backend.exception.domain.UserNotFoundException; +import net.shyshkin.study.fullstack.supportportal.backend.exception.domain.UsernameExistsException; import net.shyshkin.study.fullstack.supportportal.backend.repository.UserRepository; +import org.apache.commons.lang3.RandomStringUtils; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import javax.transaction.Transactional; import java.time.LocalDateTime; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +@Slf4j @Service @RequiredArgsConstructor public class UserServiceImpl implements UserService { private final UserRepository userRepository; + private final PasswordEncoder passwordEncoder; @Override @Transactional @@ -27,4 +41,97 @@ public class UserServiceImpl implements UserService { user.setLastLoginDate(LocalDateTime.now()); return new UserPrincipal(user); } + + @Override + public User register(String firstName, String lastName, String username, String email) { + + validateNewUsernameAndEmail(username, email); + + Role defaultRole = Role.ROLE_USER; + + String rawPassword = generatePassword(); + String encodedPassword = passwordEncoder.encode(rawPassword); + log.debug("Raw password: {}. Encoded password: {}", rawPassword, encodedPassword); + + User newUser = User.builder() + .email(email) + .firstName(firstName) + .lastName(lastName) + .username(username) + .password(encodedPassword) + .userId(generateUserId()) + .isActive(true) + .isNotLocked(true) + .joinDate(LocalDateTime.now()) + .profileImageUrl(getTemporaryProfileImageUrl()) + .lastLoginDate(null) + .lastLoginDateDisplay(null) + .role(defaultRole.name()) + .authorities(defaultRole.getAuthorities()) + .build(); + return userRepository.save(newUser); + } + + private String getTemporaryProfileImageUrl() { + return ServletUriComponentsBuilder.fromCurrentContextPath().path("/user/image/profile/temp").build().toString(); + } + + private String generatePassword() { + return RandomStringUtils.randomAscii(10); + } + + private String generateUserId() { + return UUID.randomUUID().toString(); + } + + @Override + public List findAll() { + return userRepository.findAll(); + } + + @Override + public User findByUsername(String username) { + return userRepository + .findByUsername(username) + .orElseThrow(() -> new UserNotFoundException("User with username `" + username + "` not found")); + } + + @Override + public User findByEmail(String email) { + return userRepository + .findByEmail(email) + .orElseThrow(() -> new EmailNotFoundException("User with email `" + email + "` not found")); + } + + private void validateNewUsernameAndEmail(String username, String email) { + + if (userRepository.existsByUsername(username)) + throwUsernameExistsException(username); + + if (userRepository.existsByEmail(email)) + throwEmailExistsException(email); + } + + private User validateUpdateUsernameAndEmail(String currentUsername, String username, String email) { + + Objects.requireNonNull(currentUsername); + + User currentUser = findByUsername(currentUsername); + + if (!Objects.equals(currentUsername, username) && userRepository.existsByUsername(username)) + throwUsernameExistsException(username); + + if (!Objects.equals(currentUser.getEmail(), email) && userRepository.existsByEmail(email)) + throwEmailExistsException(email); + + return currentUser; + } + + private void throwEmailExistsException(String email) { + throw new EmailExistsException("User with email `" + email + "` is already registered"); + } + + private void throwUsernameExistsException(String username) { + throw new UsernameExistsException("Username `" + username + "` is already taken. Please select another one"); + } }