diff --git a/src/main/java/ru/ulstu/core/controller/AdviceController.java b/src/main/java/ru/ulstu/core/controller/AdviceController.java index 18c25dc..d826aed 100644 --- a/src/main/java/ru/ulstu/core/controller/AdviceController.java +++ b/src/main/java/ru/ulstu/core/controller/AdviceController.java @@ -1,100 +1,118 @@ -package ru.ulstu.core.controller; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.validation.FieldError; -import org.springframework.web.bind.MethodArgumentNotValidException; -import org.springframework.web.bind.annotation.ControllerAdvice; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.RestController; -import ru.ulstu.core.error.EntityIdIsNullException; -import ru.ulstu.core.model.ErrorConstants; -import ru.ulstu.core.model.response.Response; -import ru.ulstu.core.model.response.ResponseExtended; -import ru.ulstu.user.error.UserActivationError; -import ru.ulstu.user.error.UserEmailExistsException; -import ru.ulstu.user.error.UserIdExistsException; -import ru.ulstu.user.error.UserIsUndeadException; -import ru.ulstu.user.error.UserLoginExistsException; -import ru.ulstu.user.error.UserNotActivatedException; -import ru.ulstu.user.error.UserNotFoundException; -import ru.ulstu.user.error.UserPasswordsNotValidOrNotMatchException; -import ru.ulstu.user.error.UserResetKeyError; - -import java.util.Set; -import java.util.stream.Collectors; - -@RestController -@ControllerAdvice -public class AdviceController { - private final Logger log = LoggerFactory.getLogger(AdviceController.class); - - private Response handleException(ErrorConstants error) { - log.warn(error.toString()); - return new Response<>(error); - } - - private ResponseExtended handleException(ErrorConstants error, E errorData) { - log.warn(error.toString()); - return new ResponseExtended<>(error, errorData); - } - - @ExceptionHandler(EntityIdIsNullException.class) - public Response handleEntityIdIsNullException(Throwable e) { - return handleException(ErrorConstants.ID_IS_NULL); - } - - @ExceptionHandler(MethodArgumentNotValidException.class) - public ResponseExtended> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { - final Set errors = e.getBindingResult().getAllErrors().stream() - .filter(error -> error instanceof FieldError) - .map(error -> ((FieldError) error).getField()) - .collect(Collectors.toSet()); - return handleException(ErrorConstants.VALIDATION_ERROR, errors); - } - - @ExceptionHandler(UserIdExistsException.class) - public Response handleUserIdExistsException(Throwable e) { - return handleException(ErrorConstants.USER_ID_EXISTS); - } - - @ExceptionHandler(UserActivationError.class) - public ResponseExtended handleUserActivationError(Throwable e) { - return handleException(ErrorConstants.USER_ACTIVATION_ERROR, e.getMessage()); - } - - @ExceptionHandler(UserLoginExistsException.class) - public ResponseExtended handleUserLoginExistsException(Throwable e) { - return handleException(ErrorConstants.USER_LOGIN_EXISTS, e.getMessage()); - } - - @ExceptionHandler(UserEmailExistsException.class) - public ResponseExtended handleUserEmailExistsException(Throwable e) { - return handleException(ErrorConstants.USER_EMAIL_EXISTS, e.getMessage()); - } - - @ExceptionHandler(UserPasswordsNotValidOrNotMatchException.class) - public Response handleUserPasswordsNotValidOrNotMatchException(Throwable e) { - return handleException(ErrorConstants.USER_PASSWORDS_NOT_VALID_OR_NOT_MATCH); - } - - @ExceptionHandler(UserNotFoundException.class) - public ResponseExtended handleUserNotFoundException(Throwable e) { - return handleException(ErrorConstants.USER_NOT_FOUND, e.getMessage()); - } - - @ExceptionHandler(UserNotActivatedException.class) - public Response handleUserNotActivatedException(Throwable e) { - return handleException(ErrorConstants.USER_NOT_ACTIVATED); - } - - @ExceptionHandler(UserResetKeyError.class) - public ResponseExtended handleUserResetKeyError(Throwable e) { - return handleException(ErrorConstants.USER_RESET_ERROR, e.getMessage()); - } - - @ExceptionHandler(UserIsUndeadException.class) - public ResponseExtended handleUserIsUndeadException(Throwable e) { - return handleException(ErrorConstants.USER_UNDEAD_ERROR, e.getMessage()); - } -} +package ru.ulstu.core.controller; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestController; +import ru.ulstu.core.error.EntityIdIsNullException; +import ru.ulstu.core.model.ErrorConstants; +import ru.ulstu.core.model.response.Response; +import ru.ulstu.core.model.response.ResponseExtended; +import ru.ulstu.user.error.UserActivationError; +import ru.ulstu.user.error.UserEmailExistsException; +import ru.ulstu.user.error.UserIdExistsException; +import ru.ulstu.user.error.UserIsUndeadException; +import ru.ulstu.user.error.UserLoginExistsException; +import ru.ulstu.user.error.UserNotActivatedException; +import ru.ulstu.user.error.UserNotFoundException; +import ru.ulstu.user.error.UserPasswordsNotValidOrNotMatchException; +import ru.ulstu.user.error.UserResetKeyError; + +import java.util.Set; +import java.util.stream.Collectors; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.ModelAttribute; +import ru.ulstu.user.service.UserService; + +@RestController +@ControllerAdvice +public class AdviceController { + private final static String USER_NAME_TEMPLATE = "%s %s %s"; + private final Logger log = LoggerFactory.getLogger(AdviceController.class); + private final UserService userService; + + + public AdviceController(UserService userService) { + this.userService = userService; + } + + @ModelAttribute + public void globalAttributes(Model model) { + model.addAttribute("currentUser", String.format(USER_NAME_TEMPLATE, + userService.getCurrentUser().getLastName(), + userService.getCurrentUser().getFirstName().substring(0, 1), + userService.getCurrentUser().getFirstName().substring(0, 1))); + } + + private Response handleException(ErrorConstants error) { + log.warn(error.toString()); + return new Response<>(error); + } + + private ResponseExtended handleException(ErrorConstants error, E errorData) { + log.warn(error.toString()); + return new ResponseExtended<>(error, errorData); + } + + @ExceptionHandler(EntityIdIsNullException.class) + public Response handleEntityIdIsNullException(Throwable e) { + return handleException(ErrorConstants.ID_IS_NULL); + } + + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseExtended> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { + final Set errors = e.getBindingResult().getAllErrors().stream() + .filter(error -> error instanceof FieldError) + .map(error -> ((FieldError) error).getField()) + .collect(Collectors.toSet()); + return handleException(ErrorConstants.VALIDATION_ERROR, errors); + } + + @ExceptionHandler(UserIdExistsException.class) + public Response handleUserIdExistsException(Throwable e) { + return handleException(ErrorConstants.USER_ID_EXISTS); + } + + @ExceptionHandler(UserActivationError.class) + public ResponseExtended handleUserActivationError(Throwable e) { + return handleException(ErrorConstants.USER_ACTIVATION_ERROR, e.getMessage()); + } + + @ExceptionHandler(UserLoginExistsException.class) + public ResponseExtended handleUserLoginExistsException(Throwable e) { + return handleException(ErrorConstants.USER_LOGIN_EXISTS, e.getMessage()); + } + + @ExceptionHandler(UserEmailExistsException.class) + public ResponseExtended handleUserEmailExistsException(Throwable e) { + return handleException(ErrorConstants.USER_EMAIL_EXISTS, e.getMessage()); + } + + @ExceptionHandler(UserPasswordsNotValidOrNotMatchException.class) + public Response handleUserPasswordsNotValidOrNotMatchException(Throwable e) { + return handleException(ErrorConstants.USER_PASSWORDS_NOT_VALID_OR_NOT_MATCH); + } + + @ExceptionHandler(UserNotFoundException.class) + public ResponseExtended handleUserNotFoundException(Throwable e) { + return handleException(ErrorConstants.USER_NOT_FOUND, e.getMessage()); + } + + @ExceptionHandler(UserNotActivatedException.class) + public Response handleUserNotActivatedException(Throwable e) { + return handleException(ErrorConstants.USER_NOT_ACTIVATED); + } + + @ExceptionHandler(UserResetKeyError.class) + public ResponseExtended handleUserResetKeyError(Throwable e) { + return handleException(ErrorConstants.USER_RESET_ERROR, e.getMessage()); + } + + @ExceptionHandler(UserIsUndeadException.class) + public ResponseExtended handleUserIsUndeadException(Throwable e) { + return handleException(ErrorConstants.USER_UNDEAD_ERROR, e.getMessage()); + } +} diff --git a/src/main/java/ru/ulstu/user/service/UserService.java b/src/main/java/ru/ulstu/user/service/UserService.java index d8d29a5..14d7f3c 100644 --- a/src/main/java/ru/ulstu/user/service/UserService.java +++ b/src/main/java/ru/ulstu/user/service/UserService.java @@ -1,318 +1,327 @@ -package ru.ulstu.user.service; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Sort; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.StringUtils; -import ru.ulstu.configuration.ApplicationProperties; -import ru.ulstu.core.error.EntityIdIsNullException; -import ru.ulstu.core.jpa.OffsetablePageRequest; -import ru.ulstu.core.model.BaseEntity; -import ru.ulstu.core.model.response.PageableItems; -import ru.ulstu.user.error.UserActivationError; -import ru.ulstu.user.error.UserEmailExistsException; -import ru.ulstu.user.error.UserIdExistsException; -import ru.ulstu.user.error.UserIsUndeadException; -import ru.ulstu.user.error.UserLoginExistsException; -import ru.ulstu.user.error.UserNotActivatedException; -import ru.ulstu.user.error.UserNotFoundException; -import ru.ulstu.user.error.UserPasswordsNotValidOrNotMatchException; -import ru.ulstu.user.error.UserResetKeyError; -import ru.ulstu.user.model.User; -import ru.ulstu.user.model.UserDto; -import ru.ulstu.user.model.UserListDto; -import ru.ulstu.user.model.UserResetPasswordDto; -import ru.ulstu.user.model.UserRole; -import ru.ulstu.user.model.UserRoleConstants; -import ru.ulstu.user.model.UserRoleDto; -import ru.ulstu.user.repository.UserRepository; -import ru.ulstu.user.repository.UserRoleRepository; -import ru.ulstu.user.util.UserUtils; - -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; - -@Service -@Transactional -public class UserService implements UserDetailsService { - private final Logger log = LoggerFactory.getLogger(UserService.class); - private final UserRepository userRepository; - private final PasswordEncoder passwordEncoder; - private final UserRoleRepository userRoleRepository; - private final UserMapper userMapper; - private final MailService mailService; - private final ApplicationProperties applicationProperties; - - public UserService(UserRepository userRepository, - PasswordEncoder passwordEncoder, - UserRoleRepository userRoleRepository, - UserMapper userMapper, - MailService mailService, - ApplicationProperties applicationProperties) { - this.userRepository = userRepository; - this.passwordEncoder = passwordEncoder; - this.userRoleRepository = userRoleRepository; - this.userMapper = userMapper; - this.mailService = mailService; - this.applicationProperties = applicationProperties; - } - - private User getUserByEmail(String email) { - return userRepository.findOneByEmailIgnoreCase(email); - } - - private User getUserByActivationKey(String activationKey) { - return userRepository.findOneByActivationKey(activationKey); - } - - public User getUserByLogin(String login) { - return userRepository.findOneByLoginIgnoreCase(login); - } - - @Transactional(readOnly = true) - public UserDto getUserWithRolesById(Integer userId) { - final User userEntity = userRepository.findOneWithRolesById(userId); - if (userEntity == null) { - throw new UserNotFoundException(userId.toString()); - } - return userMapper.userEntityToUserDto(userEntity); - } - - @Transactional(readOnly = true) - public PageableItems getAllUsers(int offset, int count) { - final Page page = userRepository.findAll(new OffsetablePageRequest(offset, count, new Sort("id"))); - return new PageableItems<>(page.getTotalElements(), userMapper.userEntitiesToUserListDtos(page.getContent())); - } - - // TODO: read only active users - public List findAll() { - return userRepository.findAll(); - } - - @Transactional(readOnly = true) - public PageableItems getUserRoles() { - final List roles = userRoleRepository.findAll().stream() - .map(UserRoleDto::new) - .sorted(Comparator.comparing(UserRoleDto::getViewValue)) - .collect(Collectors.toList()); - return new PageableItems<>(roles.size(), roles); - } - - public UserDto createUser(UserDto userDto) { - if (userDto.getId() != null) { - throw new UserIdExistsException(); - } - if (getUserByLogin(userDto.getLogin()) != null) { - throw new UserLoginExistsException(userDto.getLogin()); - } - if (getUserByEmail(userDto.getEmail()) != null) { - throw new UserEmailExistsException(userDto.getEmail()); - } - if (!userDto.isPasswordsValid()) { - throw new UserPasswordsNotValidOrNotMatchException(); - } - User user = userMapper.userDtoToUserEntity(userDto); - user.setActivated(false); - user.setActivationKey(UserUtils.generateActivationKey()); - user.setRoles(Collections.singleton(new UserRole(UserRoleConstants.USER))); - user.setPassword(passwordEncoder.encode(userDto.getPassword())); - user = userRepository.save(user); - mailService.sendActivationEmail(user); - log.debug("Created Information for User: {}", user.getLogin()); - return userMapper.userEntityToUserDto(user); - } - - public UserDto activateUser(String activationKey) { - final User user = getUserByActivationKey(activationKey); - if (user == null) { - throw new UserActivationError(activationKey); - } - user.setActivated(true); - user.setActivationKey(null); - user.setActivationDate(null); - log.debug("Activated user: {}", user.getLogin()); - return userMapper.userEntityToUserDto(userRepository.save(user)); - } - - public UserDto updateUser(UserDto userDto) { - if (userDto.getId() == null) { - throw new EntityIdIsNullException(); - } - if (!Objects.equals( - Optional.ofNullable(getUserByEmail(userDto.getEmail())) - .map(BaseEntity::getId).orElse(userDto.getId()), - userDto.getId())) { - throw new UserEmailExistsException(userDto.getEmail()); - } - if (!Objects.equals( - Optional.ofNullable(getUserByLogin(userDto.getLogin())) - .map(BaseEntity::getId).orElse(userDto.getId()), - userDto.getId())) { - throw new UserLoginExistsException(userDto.getLogin()); - } - User user = userRepository.findOne(userDto.getId()); - if (user == null) { - throw new UserNotFoundException(userDto.getId().toString()); - } - if (applicationProperties.getUndeadUserLogin().equalsIgnoreCase(user.getLogin())) { - userDto.setLogin(applicationProperties.getUndeadUserLogin()); - userDto.setActivated(true); - userDto.setRoles(Collections.singletonList(new UserRoleDto(UserRoleConstants.ADMIN))); - } - user.setLogin(userDto.getLogin()); - user.setFirstName(userDto.getFirstName()); - user.setLastName(userDto.getLastName()); - user.setEmail(userDto.getEmail()); - if (userDto.isActivated() != user.getActivated()) { - if (userDto.isActivated()) { - user.setActivationKey(null); - user.setActivationDate(null); - } else { - user.setActivationKey(UserUtils.generateActivationKey()); - user.setActivationDate(new Date()); - } - } - user.setActivated(userDto.isActivated()); - final Set roles = userMapper.rolesFromDto(userDto.getRoles()); - user.setRoles(roles.isEmpty() - ? Collections.singleton(new UserRole(UserRoleConstants.USER)) - : roles); - if (!StringUtils.isEmpty(userDto.getOldPassword())) { - if (!userDto.isPasswordsValid() || !userDto.isOldPasswordValid()) { - throw new UserPasswordsNotValidOrNotMatchException(); - } - if (!passwordEncoder.matches(userDto.getOldPassword(), user.getPassword())) { - throw new UserPasswordsNotValidOrNotMatchException(); - } - user.setPassword(passwordEncoder.encode(userDto.getPassword())); - log.debug("Changed password for User: {}", user.getLogin()); - } - user = userRepository.save(user); - log.debug("Changed Information for User: {}", user.getLogin()); - return userMapper.userEntityToUserDto(user); - } - - public UserDto updateUserInformation(UserDto userDto) { - if (userDto.getId() == null) { - throw new EntityIdIsNullException(); - } - if (!Objects.equals( - Optional.ofNullable(getUserByEmail(userDto.getEmail())) - .map(BaseEntity::getId).orElse(userDto.getId()), - userDto.getId())) { - throw new UserEmailExistsException(userDto.getEmail()); - } - User user = userRepository.findOne(userDto.getId()); - if (user == null) { - throw new UserNotFoundException(userDto.getId().toString()); - } - user.setFirstName(userDto.getFirstName()); - user.setLastName(userDto.getLastName()); - user.setEmail(userDto.getEmail()); - user = userRepository.save(user); - log.debug("Updated Information for User: {}", user.getLogin()); - return userMapper.userEntityToUserDto(user); - } - - public UserDto changeUserPassword(UserDto userDto) { - if (userDto.getId() == null) { - throw new EntityIdIsNullException(); - } - if (!userDto.isPasswordsValid() || !userDto.isOldPasswordValid()) { - throw new UserPasswordsNotValidOrNotMatchException(); - } - final String login = UserUtils.getCurrentUserLogin(); - final User user = userRepository.findOneByLoginIgnoreCase(login); - if (user == null) { - throw new UserNotFoundException(login); - } - if (!passwordEncoder.matches(userDto.getOldPassword(), user.getPassword())) { - throw new UserPasswordsNotValidOrNotMatchException(); - } - user.setPassword(passwordEncoder.encode(userDto.getPassword())); - log.debug("Changed password for User: {}", user.getLogin()); - return userMapper.userEntityToUserDto(userRepository.save(user)); - } - - public boolean requestUserPasswordReset(String email) { - User user = userRepository.findOneByEmailIgnoreCase(email); - if (user == null) { - throw new UserNotFoundException(email); - } - if (!user.getActivated()) { - throw new UserNotActivatedException(); - } - user.setResetKey(UserUtils.generateResetKey()); - user.setResetDate(new Date()); - user = userRepository.save(user); - mailService.sendPasswordResetMail(user); - log.debug("Created Reset Password Request for User: {}", user.getLogin()); - return true; - } - - public boolean completeUserPasswordReset(String key, UserResetPasswordDto userResetPasswordDto) { - if (!userResetPasswordDto.isPasswordsValid()) { - throw new UserPasswordsNotValidOrNotMatchException(); - } - User user = userRepository.findOneByResetKey(key); - if (user == null) { - throw new UserResetKeyError(key); - } - user.setPassword(passwordEncoder.encode(userResetPasswordDto.getPassword())); - user.setResetKey(null); - user.setResetDate(null); - user = userRepository.save(user); - log.debug("Reset Password for User: {}", user.getLogin()); - return true; - } - - public UserDto deleteUser(Integer userId) { - final User user = userRepository.findOne(userId); - if (user == null) { - throw new UserNotFoundException(userId.toString()); - } - if (applicationProperties.getUndeadUserLogin().equalsIgnoreCase(user.getLogin())) { - throw new UserIsUndeadException(user.getLogin()); - } - userRepository.delete(user); - log.debug("Deleted User: {}", user.getLogin()); - return userMapper.userEntityToUserDto(user); - } - - @Override - public UserDetails loadUserByUsername(String username) { - final User user = userRepository.findOneByLoginIgnoreCase(username); - if (user == null) { - throw new UserNotFoundException(username); - } - if (!user.getActivated()) { - throw new UserNotActivatedException(); - } - return new org.springframework.security.core.userdetails.User(user.getLogin(), - user.getPassword(), - Optional.ofNullable(user.getRoles()).orElse(Collections.emptySet()).stream() - .map(role -> new SimpleGrantedAuthority(role.getName())) - .collect(Collectors.toList())); - } - - public List findByIds(List ids) { - return userRepository.findAll(ids); - } - - public User findById(Integer id) { - return userRepository.findOne(id); - } -} +package ru.ulstu.user.service; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Sort; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; +import ru.ulstu.configuration.ApplicationProperties; +import ru.ulstu.core.error.EntityIdIsNullException; +import ru.ulstu.core.jpa.OffsetablePageRequest; +import ru.ulstu.core.model.BaseEntity; +import ru.ulstu.core.model.response.PageableItems; +import ru.ulstu.user.error.UserActivationError; +import ru.ulstu.user.error.UserEmailExistsException; +import ru.ulstu.user.error.UserIdExistsException; +import ru.ulstu.user.error.UserIsUndeadException; +import ru.ulstu.user.error.UserLoginExistsException; +import ru.ulstu.user.error.UserNotActivatedException; +import ru.ulstu.user.error.UserNotFoundException; +import ru.ulstu.user.error.UserPasswordsNotValidOrNotMatchException; +import ru.ulstu.user.error.UserResetKeyError; +import ru.ulstu.user.model.User; +import ru.ulstu.user.model.UserDto; +import ru.ulstu.user.model.UserListDto; +import ru.ulstu.user.model.UserResetPasswordDto; +import ru.ulstu.user.model.UserRole; +import ru.ulstu.user.model.UserRoleConstants; +import ru.ulstu.user.model.UserRoleDto; +import ru.ulstu.user.repository.UserRepository; +import ru.ulstu.user.repository.UserRoleRepository; +import ru.ulstu.user.util.UserUtils; + +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +@Service +@Transactional +public class UserService implements UserDetailsService { + private final Logger log = LoggerFactory.getLogger(UserService.class); + private final UserRepository userRepository; + private final PasswordEncoder passwordEncoder; + private final UserRoleRepository userRoleRepository; + private final UserMapper userMapper; + private final MailService mailService; + private final ApplicationProperties applicationProperties; + + public UserService(UserRepository userRepository, + PasswordEncoder passwordEncoder, + UserRoleRepository userRoleRepository, + UserMapper userMapper, + MailService mailService, + ApplicationProperties applicationProperties) { + this.userRepository = userRepository; + this.passwordEncoder = passwordEncoder; + this.userRoleRepository = userRoleRepository; + this.userMapper = userMapper; + this.mailService = mailService; + this.applicationProperties = applicationProperties; + } + + private User getUserByEmail(String email) { + return userRepository.findOneByEmailIgnoreCase(email); + } + + private User getUserByActivationKey(String activationKey) { + return userRepository.findOneByActivationKey(activationKey); + } + + public User getUserByLogin(String login) { + return userRepository.findOneByLoginIgnoreCase(login); + } + + @Transactional(readOnly = true) + public UserDto getUserWithRolesById(Integer userId) { + final User userEntity = userRepository.findOneWithRolesById(userId); + if (userEntity == null) { + throw new UserNotFoundException(userId.toString()); + } + return userMapper.userEntityToUserDto(userEntity); + } + + @Transactional(readOnly = true) + public PageableItems getAllUsers(int offset, int count) { + final Page page = userRepository.findAll(new OffsetablePageRequest(offset, count, new Sort("id"))); + return new PageableItems<>(page.getTotalElements(), userMapper.userEntitiesToUserListDtos(page.getContent())); + } + + // TODO: read only active users + public List findAll() { + return userRepository.findAll(); + } + + @Transactional(readOnly = true) + public PageableItems getUserRoles() { + final List roles = userRoleRepository.findAll().stream() + .map(UserRoleDto::new) + .sorted(Comparator.comparing(UserRoleDto::getViewValue)) + .collect(Collectors.toList()); + return new PageableItems<>(roles.size(), roles); + } + + public UserDto createUser(UserDto userDto) { + if (userDto.getId() != null) { + throw new UserIdExistsException(); + } + if (getUserByLogin(userDto.getLogin()) != null) { + throw new UserLoginExistsException(userDto.getLogin()); + } + if (getUserByEmail(userDto.getEmail()) != null) { + throw new UserEmailExistsException(userDto.getEmail()); + } + if (!userDto.isPasswordsValid()) { + throw new UserPasswordsNotValidOrNotMatchException(); + } + User user = userMapper.userDtoToUserEntity(userDto); + user.setActivated(false); + user.setActivationKey(UserUtils.generateActivationKey()); + user.setRoles(Collections.singleton(new UserRole(UserRoleConstants.USER))); + user.setPassword(passwordEncoder.encode(userDto.getPassword())); + user = userRepository.save(user); + mailService.sendActivationEmail(user); + log.debug("Created Information for User: {}", user.getLogin()); + return userMapper.userEntityToUserDto(user); + } + + public UserDto activateUser(String activationKey) { + final User user = getUserByActivationKey(activationKey); + if (user == null) { + throw new UserActivationError(activationKey); + } + user.setActivated(true); + user.setActivationKey(null); + user.setActivationDate(null); + log.debug("Activated user: {}", user.getLogin()); + return userMapper.userEntityToUserDto(userRepository.save(user)); + } + + public UserDto updateUser(UserDto userDto) { + if (userDto.getId() == null) { + throw new EntityIdIsNullException(); + } + if (!Objects.equals( + Optional.ofNullable(getUserByEmail(userDto.getEmail())) + .map(BaseEntity::getId).orElse(userDto.getId()), + userDto.getId())) { + throw new UserEmailExistsException(userDto.getEmail()); + } + if (!Objects.equals( + Optional.ofNullable(getUserByLogin(userDto.getLogin())) + .map(BaseEntity::getId).orElse(userDto.getId()), + userDto.getId())) { + throw new UserLoginExistsException(userDto.getLogin()); + } + User user = userRepository.findOne(userDto.getId()); + if (user == null) { + throw new UserNotFoundException(userDto.getId().toString()); + } + if (applicationProperties.getUndeadUserLogin().equalsIgnoreCase(user.getLogin())) { + userDto.setLogin(applicationProperties.getUndeadUserLogin()); + userDto.setActivated(true); + userDto.setRoles(Collections.singletonList(new UserRoleDto(UserRoleConstants.ADMIN))); + } + user.setLogin(userDto.getLogin()); + user.setFirstName(userDto.getFirstName()); + user.setLastName(userDto.getLastName()); + user.setEmail(userDto.getEmail()); + if (userDto.isActivated() != user.getActivated()) { + if (userDto.isActivated()) { + user.setActivationKey(null); + user.setActivationDate(null); + } else { + user.setActivationKey(UserUtils.generateActivationKey()); + user.setActivationDate(new Date()); + } + } + user.setActivated(userDto.isActivated()); + final Set roles = userMapper.rolesFromDto(userDto.getRoles()); + user.setRoles(roles.isEmpty() + ? Collections.singleton(new UserRole(UserRoleConstants.USER)) + : roles); + if (!StringUtils.isEmpty(userDto.getOldPassword())) { + if (!userDto.isPasswordsValid() || !userDto.isOldPasswordValid()) { + throw new UserPasswordsNotValidOrNotMatchException(); + } + if (!passwordEncoder.matches(userDto.getOldPassword(), user.getPassword())) { + throw new UserPasswordsNotValidOrNotMatchException(); + } + user.setPassword(passwordEncoder.encode(userDto.getPassword())); + log.debug("Changed password for User: {}", user.getLogin()); + } + user = userRepository.save(user); + log.debug("Changed Information for User: {}", user.getLogin()); + return userMapper.userEntityToUserDto(user); + } + + public UserDto updateUserInformation(UserDto userDto) { + if (userDto.getId() == null) { + throw new EntityIdIsNullException(); + } + if (!Objects.equals( + Optional.ofNullable(getUserByEmail(userDto.getEmail())) + .map(BaseEntity::getId).orElse(userDto.getId()), + userDto.getId())) { + throw new UserEmailExistsException(userDto.getEmail()); + } + User user = userRepository.findOne(userDto.getId()); + if (user == null) { + throw new UserNotFoundException(userDto.getId().toString()); + } + user.setFirstName(userDto.getFirstName()); + user.setLastName(userDto.getLastName()); + user.setEmail(userDto.getEmail()); + user = userRepository.save(user); + log.debug("Updated Information for User: {}", user.getLogin()); + return userMapper.userEntityToUserDto(user); + } + + public UserDto changeUserPassword(UserDto userDto) { + if (userDto.getId() == null) { + throw new EntityIdIsNullException(); + } + if (!userDto.isPasswordsValid() || !userDto.isOldPasswordValid()) { + throw new UserPasswordsNotValidOrNotMatchException(); + } + final String login = UserUtils.getCurrentUserLogin(); + final User user = userRepository.findOneByLoginIgnoreCase(login); + if (user == null) { + throw new UserNotFoundException(login); + } + if (!passwordEncoder.matches(userDto.getOldPassword(), user.getPassword())) { + throw new UserPasswordsNotValidOrNotMatchException(); + } + user.setPassword(passwordEncoder.encode(userDto.getPassword())); + log.debug("Changed password for User: {}", user.getLogin()); + return userMapper.userEntityToUserDto(userRepository.save(user)); + } + + public boolean requestUserPasswordReset(String email) { + User user = userRepository.findOneByEmailIgnoreCase(email); + if (user == null) { + throw new UserNotFoundException(email); + } + if (!user.getActivated()) { + throw new UserNotActivatedException(); + } + user.setResetKey(UserUtils.generateResetKey()); + user.setResetDate(new Date()); + user = userRepository.save(user); + mailService.sendPasswordResetMail(user); + log.debug("Created Reset Password Request for User: {}", user.getLogin()); + return true; + } + + public boolean completeUserPasswordReset(String key, UserResetPasswordDto userResetPasswordDto) { + if (!userResetPasswordDto.isPasswordsValid()) { + throw new UserPasswordsNotValidOrNotMatchException(); + } + User user = userRepository.findOneByResetKey(key); + if (user == null) { + throw new UserResetKeyError(key); + } + user.setPassword(passwordEncoder.encode(userResetPasswordDto.getPassword())); + user.setResetKey(null); + user.setResetDate(null); + user = userRepository.save(user); + log.debug("Reset Password for User: {}", user.getLogin()); + return true; + } + + public UserDto deleteUser(Integer userId) { + final User user = userRepository.findOne(userId); + if (user == null) { + throw new UserNotFoundException(userId.toString()); + } + if (applicationProperties.getUndeadUserLogin().equalsIgnoreCase(user.getLogin())) { + throw new UserIsUndeadException(user.getLogin()); + } + userRepository.delete(user); + log.debug("Deleted User: {}", user.getLogin()); + return userMapper.userEntityToUserDto(user); + } + + @Override + public UserDetails loadUserByUsername(String username) { + final User user = userRepository.findOneByLoginIgnoreCase(username); + if (user == null) { + throw new UserNotFoundException(username); + } + if (!user.getActivated()) { + throw new UserNotActivatedException(); + } + return new org.springframework.security.core.userdetails.User(user.getLogin(), + user.getPassword(), + Optional.ofNullable(user.getRoles()).orElse(Collections.emptySet()).stream() + .map(role -> new SimpleGrantedAuthority(role.getName())) + .collect(Collectors.toList())); + } + + public List findByIds(List ids) { + return userRepository.findAll(ids); + } + + public User findById(Integer id) { + return userRepository.findOne(id); + } + + public User getCurrentUser() { + String login = UserUtils.getCurrentUserLogin(); + User user = userRepository.findOneByLoginIgnoreCase(login); + if (user == null) { + throw new UserNotFoundException(login); + } + return user; + } +} diff --git a/src/main/java/ru/ulstu/user/service/UserUtils.java b/src/main/java/ru/ulstu/user/service/UserUtils.java new file mode 100644 index 0000000..0314479 --- /dev/null +++ b/src/main/java/ru/ulstu/user/service/UserUtils.java @@ -0,0 +1,34 @@ +package ru.ulstu.user.service; +import org.apache.commons.lang3.RandomStringUtils; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; + +public class UserUtils { + private static final int DEF_COUNT = 20; + + public static String generateActivationKey() { + return RandomStringUtils.randomNumeric(DEF_COUNT); + } + + public static String generateResetKey() { + return RandomStringUtils.randomNumeric(DEF_COUNT); + } + + public static String getCurrentUserLogin() { + final SecurityContext securityContext = SecurityContextHolder.getContext(); + if (securityContext == null) { + return null; + } + final Authentication authentication = securityContext.getAuthentication(); + if (authentication.getPrincipal() instanceof UserDetails) { + final UserDetails springSecurityUser = (UserDetails) authentication.getPrincipal(); + return springSecurityUser.getUsername(); + } + if (authentication.getPrincipal() instanceof String) { + return (String) authentication.getPrincipal(); + } + return null; + } +}