feat: move auth logic to service layer

This commit is contained in:
gfxv 2025-03-12 19:37:50 +03:00
parent f1cb78339e
commit 951427e4e4
2 changed files with 102 additions and 66 deletions

View File

@ -1,95 +1,44 @@
package dev.gfxv.blps.controller;
import dev.gfxv.blps.entity.Role;
import dev.gfxv.blps.entity.User;
import dev.gfxv.blps.payload.request.LoginRequest;
import dev.gfxv.blps.payload.request.RegisterRequest;
import dev.gfxv.blps.payload.response.JwtResponse;
import dev.gfxv.blps.security.JwtUtils;
import dev.gfxv.blps.repository.RoleRepository;
import dev.gfxv.blps.repository.UserRepository;
import dev.gfxv.blps.security.UserDetailsImpl;
import dev.gfxv.blps.service.AuthService;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.experimental.FieldDefaults;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/api/auth")
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
public class AuthController {
AuthenticationManager authenticationManager;
UserRepository userRepository;
RoleRepository roleRepository;
PasswordEncoder passwordEncoder;
JwtUtils jwtUtils;
AuthService authService;
@Autowired
public AuthController(
AuthenticationManager authenticationManager,
UserRepository userRepository,
RoleRepository roleRepository,
PasswordEncoder passwordEncoder,
JwtUtils jwtUtils
) {
this.authenticationManager = authenticationManager;
this.userRepository = userRepository;
this.roleRepository = roleRepository;
this.passwordEncoder = passwordEncoder;
this.jwtUtils = jwtUtils;
public AuthController(AuthService authService) {
this.authService = authService;
}
@PostMapping("/register")
public ResponseEntity<?> registerUser(@RequestBody RegisterRequest registerRequest) {
if (userRepository.existsByUsername(registerRequest.getUsername())) {
return ResponseEntity.badRequest().body("Error: Username is already taken!");
try {
String response = authService.registerUser(registerRequest);
return ResponseEntity.ok(response);
} catch (RuntimeException e) {
return ResponseEntity.badRequest().body(e.getMessage());
}
if (userRepository.existsByEmail(registerRequest.getEmail())) {
return ResponseEntity.badRequest().body("Error: Email is already in use!");
}
User user = new User();
user.setUsername(registerRequest.getUsername());
user.setEmail(registerRequest.getEmail());
user.setPassword(passwordEncoder.encode(registerRequest.getPassword()));
Role userRole = roleRepository.findByName("ROLE_USER")
.orElseThrow(() -> new RuntimeException("Error: Role is not found."));
user.setRoles(Collections.singleton(userRole));
userRepository.save(user);
return ResponseEntity.ok("User registered successfully!");
}
@PostMapping("/login")
public ResponseEntity<?> authenticateUser(@RequestBody LoginRequest loginRequest) {
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = jwtUtils.generateJwtToken(authentication);
UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
List<String> roles = userDetails.getAuthorities().stream()
.map(GrantedAuthority::getAuthority)
.collect(Collectors.toList());
return ResponseEntity.ok(new JwtResponse(jwt, userDetails.getUsername(), roles));
try {
JwtResponse jwtResponse = authService.authenticateUser(loginRequest);
return ResponseEntity.ok(jwtResponse);
} catch (RuntimeException e) {
return ResponseEntity.badRequest().body(e.getMessage());
}
}
}

View File

@ -0,0 +1,87 @@
package dev.gfxv.blps.service;
import dev.gfxv.blps.entity.Role;
import dev.gfxv.blps.entity.User;
import dev.gfxv.blps.payload.request.LoginRequest;
import dev.gfxv.blps.payload.request.RegisterRequest;
import dev.gfxv.blps.payload.response.JwtResponse;
import dev.gfxv.blps.repository.RoleRepository;
import dev.gfxv.blps.repository.UserRepository;
import dev.gfxv.blps.security.JwtUtils;
import dev.gfxv.blps.security.UserDetailsImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class AuthService {
AuthenticationManager authenticationManager;
UserRepository userRepository;
RoleRepository roleRepository;
PasswordEncoder passwordEncoder;
JwtUtils jwtUtils;
@Autowired
public AuthService(
AuthenticationManager authenticationManager,
UserRepository userRepository,
RoleRepository roleRepository,
PasswordEncoder passwordEncoder,
JwtUtils jwtUtils
) {
this.authenticationManager = authenticationManager;
this.userRepository = userRepository;
this.roleRepository = roleRepository;
this.passwordEncoder = passwordEncoder;
this.jwtUtils = jwtUtils;
}
public String registerUser(RegisterRequest registerRequest) {
if (userRepository.existsByUsername(registerRequest.getUsername())) {
throw new RuntimeException("Error: Username is already taken!");
}
if (userRepository.existsByEmail(registerRequest.getEmail())) {
throw new RuntimeException("Error: Email is already in use!");
}
User user = new User();
user.setUsername(registerRequest.getUsername());
user.setEmail(registerRequest.getEmail());
user.setPassword(passwordEncoder.encode(registerRequest.getPassword()));
Role userRole = roleRepository.findByName("ROLE_USER")
.orElseThrow(() -> new RuntimeException("Error: Role is not found."));
user.setRoles(Collections.singleton(userRole));
userRepository.save(user);
return "User registered successfully!";
}
public JwtResponse authenticateUser(LoginRequest loginRequest) {
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = jwtUtils.generateJwtToken(authentication);
UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
List<String> roles = userDetails.getAuthorities().stream()
.map(GrantedAuthority::getAuthority)
.collect(Collectors.toList());
return new JwtResponse(jwt, userDetails.getUsername(), roles);
}
}