AuthService.java 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. package com.danielbohry.authservice.service.auth;
  2. import com.danielbohry.authservice.api.dto.AuthenticationRequest;
  3. import com.danielbohry.authservice.api.dto.AuthenticationResponse;
  4. import com.danielbohry.authservice.client.MailClient;
  5. import com.danielbohry.authservice.domain.ApplicationUser;
  6. import com.danielbohry.authservice.service.user.UserService;
  7. import lombok.RequiredArgsConstructor;
  8. import lombok.extern.slf4j.Slf4j;
  9. import org.springframework.beans.factory.annotation.Value;
  10. import org.springframework.security.authentication.AuthenticationManager;
  11. import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
  12. import org.springframework.security.core.authority.SimpleGrantedAuthority;
  13. import org.springframework.security.core.context.SecurityContext;
  14. import org.springframework.security.core.context.SecurityContextHolder;
  15. import org.springframework.security.core.userdetails.User;
  16. import org.springframework.security.core.userdetails.UserDetails;
  17. import org.springframework.security.core.userdetails.UserDetailsService;
  18. import org.springframework.security.core.userdetails.UsernameNotFoundException;
  19. import org.springframework.security.crypto.password.PasswordEncoder;
  20. import org.springframework.stereotype.Service;
  21. import static com.danielbohry.authservice.service.auth.UserConverter.convert;
  22. import static java.time.Instant.now;
  23. @Slf4j
  24. @Service
  25. @RequiredArgsConstructor
  26. public class AuthService implements UserDetailsService {
  27. private final UserService service;
  28. private final JwtService jwtService;
  29. private final AuthenticationManager authenticationManager;
  30. private final PasswordEncoder passwordEncoder;
  31. private final MailClient mailClient;
  32. @Value("${host.name:localhost}")
  33. private String host;
  34. @Override
  35. public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
  36. var user = service.findByUsername(username);
  37. var authorities = user.getRoles().stream().map(role -> new SimpleGrantedAuthority("ROLE_" + role)).toList();
  38. return new User(user.getUsername(), user.getPassword(), authorities);
  39. }
  40. public AuthenticationResponse register(AuthenticationRequest request) {
  41. UserDetails user = buildUserDetails(request);
  42. ApplicationUser toSave = convert(user, request.getEmail());
  43. toSave.setCreatedAt(now());
  44. toSave.setUpdatedAt(now());
  45. toSave.setLastLoginAt(now());
  46. ApplicationUser saved = service.create(toSave);
  47. Authentication authentication = jwtService.generateToken(saved);
  48. log.info("Username [{}] registered", request.getUsername());
  49. return buildResponse(saved, authentication);
  50. }
  51. public AuthenticationResponse authenticate(AuthenticationRequest request) {
  52. authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(
  53. request.getUsername(), request.getPassword())
  54. );
  55. ApplicationUser user = service.findByUsername(request.getUsername());
  56. Authentication authentication = jwtService.generateToken(user);
  57. log.info("Username [{}] authenticated", request.getUsername());
  58. user.setLastLoginAt(now());
  59. service.update(user.getId(), user);
  60. return buildResponse(user, authentication);
  61. }
  62. public AuthenticationResponse refresh(ApplicationUser applicationUser) {
  63. if (!applicationUser.isActive()) {
  64. return null;
  65. }
  66. ApplicationUser user = service.findByUsername(applicationUser.getUsername());
  67. Authentication authentication = jwtService.generateToken(user);
  68. user.setLastLoginAt(now());
  69. service.update(user.getId(), user);
  70. return buildResponse(user, authentication);
  71. }
  72. public AuthenticationResponse changePassword(String userId, String currentPassword, String newPassword) {
  73. ApplicationUser user = service.changePassword(userId, currentPassword, newPassword, passwordEncoder);
  74. Authentication authentication = jwtService.generateToken(user);
  75. return buildResponse(user, authentication);
  76. }
  77. public AuthenticationResponse resetPassword(String userId, String newPassword) {
  78. ApplicationUser user = service.resetPassword(userId, newPassword, passwordEncoder);
  79. Authentication authentication = jwtService.generateToken(user);
  80. return buildResponse(user, authentication);
  81. }
  82. public AuthenticationResponse updateProfile(String userId, String currentPassword, String newPassword, String email) {
  83. ApplicationUser user = service.updateProfile(userId, currentPassword, newPassword, email, passwordEncoder);
  84. Authentication authentication = jwtService.generateToken(user);
  85. return buildResponse(user, authentication);
  86. }
  87. public void sendResetPasswordEmail(String username) {
  88. try {
  89. ApplicationUser user = service.findByUsername(username);
  90. Authentication systemAuth = jwtService.generateSystemToken();
  91. Authentication userAuth = jwtService.generateToken(user, 10);
  92. if (user.getEmail() != null && !user.getEmail().isEmpty()) {
  93. String resetUrl = host + "/?reset-password&token=" + userAuth.token();
  94. String emailContent = buildContent(user.getUsername(), resetUrl);
  95. mailClient.sendMail(user.getEmail(), "Password Reset Request - Auth Service", emailContent, "Bearer " + systemAuth.token());
  96. }
  97. } catch (Exception ignored) {
  98. }
  99. }
  100. private UserDetails buildUserDetails(AuthenticationRequest request) {
  101. return User.builder()
  102. .username(request.getUsername())
  103. .password(passwordEncoder.encode(request.getPassword()))
  104. .build();
  105. }
  106. private static AuthenticationResponse buildResponse(ApplicationUser user, Authentication authentication) {
  107. return AuthenticationResponse.builder()
  108. .id(user.getId())
  109. .username(authentication.username())
  110. .email(user.getEmail())
  111. .token(authentication.token())
  112. .expirationDate(authentication.expirationDate())
  113. .roles(authentication.authorities())
  114. .build();
  115. }
  116. private String buildContent(String username, String resetUrl) {
  117. return String.format("""
  118. Hello %s,
  119. You requested a password reset for your account.
  120. Click here to reset your password: %s
  121. This link expires in 10 minutes.
  122. If you didn't request this, please ignore this email.
  123. Auth Service Team
  124. """, username, resetUrl);
  125. }
  126. }