Skip to content

Commit d6e5d6f

Browse files
committed
feat(auth): create login endpoint and handle related exceptions
1 parent 17addb9 commit d6e5d6f

File tree

8 files changed

+117
-16
lines changed

8 files changed

+117
-16
lines changed

src/main/java/fun/trackmoney/auth/controller/AuthController.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package fun.trackmoney.auth.controller;
22

3+
import fun.trackmoney.auth.dto.LoginRequestDTO;
4+
import fun.trackmoney.auth.dto.LoginResponseDTO;
35
import fun.trackmoney.auth.service.AuthService;
46
import fun.trackmoney.user.dtos.UserRequestDTO;
57
import fun.trackmoney.user.dtos.UserResponseDTO;
@@ -49,4 +51,16 @@ public ResponseEntity<ApiResponse<UserResponseDTO>> register(
4951
)
5052
);
5153
}
54+
55+
@PostMapping("login")
56+
public ResponseEntity<ApiResponse<LoginResponseDTO>> login(@RequestBody LoginRequestDTO loginDto) {
57+
return ResponseEntity.ok().body(
58+
new ApiResponse<>(
59+
true,
60+
"Login successful!",
61+
authService.login(loginDto),
62+
null
63+
)
64+
);
65+
}
5266
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package fun.trackmoney.auth.dto;
2+
3+
public record LoginRequestDTO(String email, String password){
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package fun.trackmoney.auth.dto;
2+
3+
public record LoginResponseDTO (String Token){
4+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package fun.trackmoney.auth.exception;
2+
3+
import fun.trackmoney.utils.CustomFieldError;
4+
5+
import java.util.ArrayList;
6+
import java.util.List;
7+
8+
public class LoginException extends RuntimeException {
9+
private final List<CustomFieldError> errors;
10+
11+
public LoginException(String message) {
12+
super(message);
13+
this.errors = new ArrayList<>();
14+
this.errors.add(new CustomFieldError("Email: ", message));
15+
}
16+
17+
public LoginException(List<CustomFieldError> errors) {
18+
super("Email not found!");
19+
this.errors = errors;
20+
}
21+
22+
public List<CustomFieldError> getErrors() {
23+
return errors;
24+
}
25+
}
Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,38 @@
11
package fun.trackmoney.auth.service;
22

3+
import fun.trackmoney.auth.dto.LoginRequestDTO;
4+
import fun.trackmoney.auth.dto.LoginResponseDTO;
5+
import fun.trackmoney.auth.exception.LoginException;
6+
import fun.trackmoney.auth.infra.jwt.JwtService;
37
import fun.trackmoney.user.dtos.UserRequestDTO;
48
import fun.trackmoney.user.dtos.UserResponseDTO;
9+
import fun.trackmoney.user.entity.UserEntity;
510
import fun.trackmoney.user.service.UserService;
11+
import org.springframework.security.crypto.password.PasswordEncoder;
612
import org.springframework.stereotype.Service;
713

8-
/**
9-
* Provides authentication-related services, including user registration.
10-
*/
1114
@Service
1215
public class AuthService {
1316

1417
private final UserService userService;
18+
private final PasswordEncoder passwordEncoder;
19+
private final JwtService jwtservice;
1520

16-
/**
17-
* Constructs an AuthService with the specified UserService.
18-
*
19-
* @param userService the service used to handle user-related operations
20-
*/
21-
public AuthService(UserService userService) {
21+
public AuthService(UserService userService, PasswordEncoder passwordEncoder, JwtService jwtservice) {
2222
this.userService = userService;
23+
this.passwordEncoder = passwordEncoder;
24+
this.jwtservice = jwtservice;
2325
}
2426

25-
/**
26-
* Registers a new user based on the provided user data.
27-
*
28-
* @param userDto the data transfer object containing user registration details
29-
* @return a data transfer object containing the registered user's details
30-
*/
3127
public UserResponseDTO register(UserRequestDTO userDto) {
3228
return userService.register(userDto);
3329
}
30+
31+
public LoginResponseDTO login(LoginRequestDTO loginDto) {
32+
UserEntity user = userService.findUserByEmail(loginDto);
33+
if(!passwordEncoder.matches(loginDto.password(), user.getPassword())){
34+
throw new LoginException("Password is incorrect.");
35+
}
36+
return new LoginResponseDTO(jwtservice.generateToken(user.getEmail()));
37+
}
3438
}

src/main/java/fun/trackmoney/config/exception/RestExceptionHandler.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package fun.trackmoney.config.exception;
22

3+
import fun.trackmoney.auth.exception.LoginException;
34
import fun.trackmoney.user.exception.EmailAlreadyExistsException;
5+
import fun.trackmoney.user.exception.EmailNotFoundException;
46
import fun.trackmoney.user.exception.PasswordNotValid;
57
import fun.trackmoney.utils.CustomFieldError;
68
import fun.trackmoney.utils.response.ApiResponse;
@@ -18,7 +20,7 @@ public class RestExceptionHandler {
1820
@ExceptionHandler(PasswordNotValid.class)
1921
public ResponseEntity<ApiResponse<List<String>>> passwordNotValid(PasswordNotValid ex) {
2022
return ResponseEntity.badRequest().body(
21-
new ApiResponse<>(false, ex.getMessage(), null, ex.getErrors() )
23+
new ApiResponse<>(false, ex.getMessage(), null, ex.getErrors())
2224
);
2325
}
2426

@@ -49,4 +51,18 @@ public ResponseEntity<ApiResponse<Object>> handleEmailAlreadyExists(EmailAlready
4951
.body(new ApiResponse<>(false, ex.getMessage(), null,
5052
List.of(new CustomFieldError("Email", ex.getMessage()))));
5153
}
54+
55+
@ExceptionHandler(EmailNotFoundException.class)
56+
public ResponseEntity<ApiResponse<List<String>>> emailNotFound(EmailNotFoundException ex) {
57+
return ResponseEntity.badRequest().body(
58+
new ApiResponse<>(false, ex.getMessage(), null, ex.getErrors())
59+
);
60+
}
61+
62+
@ExceptionHandler(LoginException.class)
63+
public ResponseEntity<ApiResponse<List<CustomFieldError>>> loginException(LoginException ex) {
64+
return ResponseEntity.badRequest().body(
65+
new ApiResponse<>(false, ex.getMessage(), null, ex.getErrors())
66+
);
67+
}
5268
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package fun.trackmoney.user.exception;
2+
3+
import fun.trackmoney.utils.CustomFieldError;
4+
5+
import java.util.ArrayList;
6+
import java.util.List;
7+
8+
public class EmailNotFoundException extends RuntimeException {
9+
private final List<CustomFieldError> errors;
10+
11+
public EmailNotFoundException(String message) {
12+
super(message);
13+
this.errors = new ArrayList<>();
14+
this.errors.add(new CustomFieldError("Email: ", message));
15+
}
16+
17+
public EmailNotFoundException(List<CustomFieldError> errors) {
18+
super("Email not found!");
19+
this.errors = errors;
20+
}
21+
22+
public List<CustomFieldError> getErrors() {
23+
return errors;
24+
}
25+
}

src/main/java/fun/trackmoney/user/service/UserService.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package fun.trackmoney.user.service;
22

3+
import fun.trackmoney.auth.dto.LoginRequestDTO;
34
import fun.trackmoney.user.dtos.UserRequestDTO;
45
import fun.trackmoney.user.dtos.UserResponseDTO;
56
import fun.trackmoney.user.entity.UserEntity;
67
import fun.trackmoney.user.exception.EmailAlreadyExistsException;
8+
import fun.trackmoney.user.exception.EmailNotFoundException;
79
import fun.trackmoney.user.exception.PasswordNotValid;
810
import fun.trackmoney.user.mapper.UserMapper;
911
import fun.trackmoney.user.repository.UserRepository;
@@ -41,4 +43,11 @@ public UserResponseDTO register(UserRequestDTO userRequestDTO) {
4143
throw new EmailAlreadyExistsException("Email already registered.");
4244
}
4345
}
46+
47+
public UserEntity findUserByEmail(LoginRequestDTO loginDto) {
48+
return userRepository.findByEmail(loginDto.email())
49+
.orElseThrow(() -> {
50+
throw new EmailNotFoundException("User not found");
51+
});
52+
}
4453
}

0 commit comments

Comments
 (0)