161 lines
6.7 KiB
Java
161 lines
6.7 KiB
Java
package com.faf223.expensetrackerfaf.service;
|
|
|
|
import com.faf223.expensetrackerfaf.config.JwtService;
|
|
import com.faf223.expensetrackerfaf.controller.auth.AuthenticationRequest;
|
|
import com.faf223.expensetrackerfaf.controller.auth.AuthenticationResponse;
|
|
import com.faf223.expensetrackerfaf.controller.auth.RegisterRequest;
|
|
import com.faf223.expensetrackerfaf.controller.auth.TokenRefreshRequest;
|
|
import com.faf223.expensetrackerfaf.model.Credential;
|
|
import com.faf223.expensetrackerfaf.model.User;
|
|
import com.faf223.expensetrackerfaf.repository.CredentialRepository;
|
|
import com.faf223.expensetrackerfaf.repository.UserRepository;
|
|
import com.faf223.expensetrackerfaf.security.PersonDetails;
|
|
import com.faf223.expensetrackerfaf.util.exceptions.UserNotAuthenticatedException;
|
|
import com.faf223.expensetrackerfaf.util.exceptions.UserNotFoundException;
|
|
import lombok.RequiredArgsConstructor;
|
|
import org.springframework.security.authentication.AuthenticationManager;
|
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
|
import org.springframework.security.core.Authentication;
|
|
import org.springframework.security.core.context.SecurityContextHolder;
|
|
import org.springframework.security.core.userdetails.UserDetails;
|
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
|
import org.springframework.security.oauth2.core.user.OAuth2User;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
import java.util.Optional;
|
|
|
|
@Service
|
|
@RequiredArgsConstructor
|
|
public class AuthenticationService {
|
|
|
|
private final UserRepository userRepository;
|
|
private final UserService userService;
|
|
private final CredentialRepository credentialRepository;
|
|
private final PasswordEncoder passwordEncoder;
|
|
private final JwtService jwtService;
|
|
private final AuthenticationManager authenticationManager;
|
|
private final PasswordGenerator passwordGenerator;
|
|
|
|
public AuthenticationResponse register(RegisterRequest request) {
|
|
|
|
User user = User.builder()
|
|
.firstName(request.getFirstname())
|
|
.lastName(request.getLastname())
|
|
.username(request.getUsername())
|
|
.build();
|
|
|
|
userRepository.save(user);
|
|
Credential credential = new Credential(user, request.getEmail(), passwordEncoder.encode(request.getPassword()));
|
|
credentialRepository.save(credential);
|
|
|
|
UserDetails userDetails = new PersonDetails(credential);
|
|
String jwtToken = jwtService.generateToken(userDetails);
|
|
String refreshToken = jwtService.generateRefreshToken(userDetails);
|
|
|
|
return AuthenticationResponse.builder()
|
|
.accessToken(jwtToken)
|
|
.refreshToken(refreshToken)
|
|
.build();
|
|
}
|
|
|
|
public AuthenticationResponse register(OAuth2User oAuth2User) {
|
|
String userEmail = oAuth2User.getAttribute("email");
|
|
|
|
// Check if the user is already registered
|
|
Optional<Credential> existingCredential = credentialRepository.findByEmail(userEmail);
|
|
if (existingCredential.isPresent()) {
|
|
UserDetails userDetails = new PersonDetails(existingCredential.get());
|
|
String jwtToken = jwtService.generateToken(userDetails);
|
|
String refreshToken = jwtService.generateRefreshToken(userDetails);
|
|
|
|
return AuthenticationResponse.builder()
|
|
.accessToken(jwtToken)
|
|
.refreshToken(refreshToken)
|
|
.build();
|
|
}
|
|
|
|
|
|
String givenName = oAuth2User.getAttribute("given_name");
|
|
String familyName = oAuth2User.getAttribute("family_name");
|
|
String email = oAuth2User.getAttribute("email");
|
|
|
|
User user = User.builder()
|
|
.firstName(givenName)
|
|
.lastName(familyName)
|
|
.username(email)
|
|
.build();
|
|
|
|
String randomPassword = passwordGenerator.generateRandomPassword(8);
|
|
|
|
user.setPassword(passwordEncoder.encode(randomPassword));
|
|
|
|
userRepository.save(user);
|
|
Credential credential = new Credential(user, email, passwordEncoder.encode(randomPassword));
|
|
credentialRepository.save(credential);
|
|
|
|
UserDetails userDetails = new PersonDetails(credential);
|
|
String jwtToken = jwtService.generateToken(userDetails);
|
|
String refreshToken = jwtService.generateRefreshToken(userDetails);
|
|
|
|
System.out.println("New user: " + user);
|
|
System.out.println("New credentials: " + credential);
|
|
|
|
return AuthenticationResponse.builder()
|
|
.accessToken(jwtToken)
|
|
.refreshToken(refreshToken)
|
|
.build();
|
|
}
|
|
|
|
|
|
|
|
public AuthenticationResponse authenticate(AuthenticationRequest request) {
|
|
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(request.getEmail(), request.getPassword()));
|
|
|
|
Credential credential = credentialRepository.findByEmail(request.getEmail()).orElseThrow((() -> new UserNotFoundException("User not found")));
|
|
|
|
UserDetails userDetails = new PersonDetails(credential);
|
|
String jwtToken = jwtService.generateToken(userDetails);
|
|
String refreshToken = jwtService.generateRefreshToken(userDetails);
|
|
return AuthenticationResponse.builder()
|
|
.accessToken(jwtToken)
|
|
.refreshToken(refreshToken)
|
|
.build();
|
|
}
|
|
|
|
public AuthenticationResponse refreshAccessToken(TokenRefreshRequest refreshRequest) {
|
|
String refreshToken = refreshRequest.getRefreshToken();
|
|
|
|
Optional<Credential> credential = credentialRepository.findByEmail(jwtService.extractUsername(refreshToken));
|
|
if (credential.isPresent()) {
|
|
UserDetails userDetails = new PersonDetails(credential.get());
|
|
|
|
String jwtToken = jwtService.generateToken(userDetails);
|
|
return AuthenticationResponse.builder()
|
|
.accessToken(jwtToken)
|
|
.refreshToken(refreshToken)
|
|
.build();
|
|
} else {
|
|
throw new UserNotAuthenticatedException("Invalid or expired refresh token");
|
|
}
|
|
}
|
|
|
|
public void updatePassword(String newPassword) {
|
|
|
|
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
|
|
|
if (authentication != null && authentication.getPrincipal() instanceof UserDetails userDetails) {
|
|
User user = userService.getUserByEmail(userDetails.getUsername());
|
|
Optional<Credential> credential = credentialRepository.findByUser(user);
|
|
|
|
if (credential.isPresent()) {
|
|
|
|
Credential updatedCredential = credential.get();
|
|
updatedCredential.setPassword(passwordEncoder.encode(newPassword));
|
|
credentialRepository.save(updatedCredential);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|