-
Notifications
You must be signed in to change notification settings - Fork 0
Implemented Authentication & Authorization #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
33 commits
Select commit
Hold shift + click to select a range
09f513a
added jjwt dependencies in pom.xml file
Semilore317 09c195d
chore: ignore secrets directory
Semilore317 b474e6b
added user entity and role-based permissions
Semilore317 2c0ae8b
added relationship between user and transactions
Semilore317 8bb695b
implemented userRepository
Semilore317 7804201
added database migration xml files
Semilore317 b29f479
created SignupRequest
Semilore317 5fae29c
created LoginRequest DTO
Semilore317 b822622
corrected LoginRequest DTO design
Semilore317 77ea0bd
added AuthResponse DTO
Semilore317 08b40b8
reformatted UserDto as a record and corrected error in User entity
Semilore317 990c75c
fixed inconsitencies in DTOs
Semilore317 636fbbd
fixed inconsistencies in DTOs
Semilore317 348dae9
Successfully implemented all security components with proper formatti…
Semilore317 17399b8
added extra exception classes
Semilore317 bdf4c5d
updated the GlobalExceptionHandler class
Semilore317 de43f43
added the EmailAlreadyExistsException class
Semilore317 4cd934f
added the UsernameAlreadyExistsException class
Semilore317 dcb7800
added the InvalidCredentialException class
Semilore317 4131830
modified the GlobalExceptionHandler
Semilore317 cfd0087
scaffolded UserService class
Semilore317 8cb0b43
implemented the userService
Semilore317 e9eb73c
removed unnecessary comments and implemented AuthController
Semilore317 28a163f
implemented auth controller and removed redudant comments
Semilore317 57a3a34
fixed bug with app not starting
Semilore317 104c1c1
fixed issue where JPA wasn't adding timestamps to base entitiy
Semilore317 175c129
modified Filter Chain to change endpoint access
Semilore317 850b6b1
added loggin to JwtAuthenticationFilter to detect the issue
Semilore317 7dc8f5c
refactored secrets file
Semilore317 a4d1350
fixed issue with system_admin credentials
Semilore317 42afa9a
removed unneeded config in application.yaml
Semilore317 190d21f
added preAuthorize annotation to /me endpoint
Semilore317 074a6fa
added JWT_SECRET to IDEA environment variables
Semilore317 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,3 +31,6 @@ build/ | |
|
|
||
| ### VS Code ### | ||
| .vscode/ | ||
|
|
||
| ### Secrets | ||
| secrets | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
66 changes: 65 additions & 1 deletion
66
src/main/java/com/SkillsForge/expensetracker/app/Config.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,67 @@ | ||
| package com.SkillsForge.expensetracker.app; | ||
|
|
||
| public class Config {} | ||
| import com.SkillsForge.expensetracker.security.JwtAuthenticationFilter; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.context.annotation.Bean; | ||
| import org.springframework.context.annotation.Configuration; | ||
| import org.springframework.security.authentication.AuthenticationManager; | ||
| import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; | ||
| import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; | ||
| import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||
| import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; | ||
| import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; | ||
| import org.springframework.security.config.http.SessionCreationPolicy; | ||
| import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | ||
| import org.springframework.security.crypto.password.PasswordEncoder; | ||
| import org.springframework.security.web.SecurityFilterChain; | ||
| import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; | ||
|
|
||
| @Configuration | ||
| @EnableWebSecurity | ||
| @EnableMethodSecurity // Enables @PreAuthorize, @PostAuthorize annotations | ||
| @RequiredArgsConstructor | ||
| public class Config { | ||
|
|
||
| private final JwtAuthenticationFilter jwtAuthenticationFilter; | ||
|
|
||
| @Bean | ||
| public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { | ||
| http | ||
| // Disable CSRF (Cross-Site Request Forgery) protection | ||
| // We use stateless JWT, so CSRF is not needed | ||
| .csrf(AbstractHttpConfigurer::disable) | ||
|
|
||
| // Configure endpoint authorization | ||
| .authorizeHttpRequests(auth -> auth | ||
| .requestMatchers( | ||
| "/api/v1/auth/signup", | ||
| "/api/v1/auth/login", | ||
| "/api/v1/auth/refresh-token" // if you have one | ||
| ).permitAll() | ||
|
|
||
| // LOCKED DOORS (Everything else, including /auth/current-user) | ||
| .anyRequest().authenticated() | ||
| ) | ||
| // Configure session management | ||
| // STATELESS = no server-side sessions, use JWT only | ||
| .sessionManagement( | ||
| session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) | ||
|
|
||
| // Add our JWT filter before Spring Security's authentication filter | ||
| // This ensures JWT validation happens before standard authentication | ||
| .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); | ||
|
|
||
| return http.build(); | ||
| } | ||
|
|
||
| @Bean | ||
| public PasswordEncoder passwordEncoder() { | ||
| return new BCryptPasswordEncoder(); | ||
| } | ||
|
|
||
| @Bean | ||
| public AuthenticationManager authenticationManager(AuthenticationConfiguration config) | ||
| throws Exception { | ||
| return config.getAuthenticationManager(); | ||
| } | ||
| } |
10 changes: 10 additions & 0 deletions
10
src/main/java/com/SkillsForge/expensetracker/app/enums/Permissions.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| package com.SkillsForge.expensetracker.app.enums; | ||
|
|
||
| public enum Permissions { | ||
| TRANSACTION_READ, | ||
| TRANSACTION_WRITE, | ||
| TRANSACTION_DELETE, | ||
| USER_READ, | ||
| USER_WRITE, | ||
| ADMIN_ACCESS | ||
| } |
20 changes: 20 additions & 0 deletions
20
src/main/java/com/SkillsForge/expensetracker/app/enums/Role.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| package com.SkillsForge.expensetracker.app.enums; | ||
|
|
||
| import java.util.Set; | ||
|
|
||
| public enum Role { | ||
| USER, | ||
| ADMIN; | ||
|
|
||
| public Set<Permissions> getPermissions() { | ||
| return switch (this) { | ||
| case ADMIN -> Set.of(Permissions.values()); // Admin has all permissions | ||
| case USER -> Set.of( | ||
| Permissions.TRANSACTION_READ, | ||
| Permissions.TRANSACTION_WRITE, | ||
| Permissions.TRANSACTION_DELETE, | ||
| Permissions.USER_READ, | ||
| Permissions.USER_WRITE); | ||
| }; | ||
| } | ||
| } |
45 changes: 45 additions & 0 deletions
45
src/main/java/com/SkillsForge/expensetracker/controller/AuthController.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| package com.SkillsForge.expensetracker.controller; | ||
|
|
||
| import com.SkillsForge.expensetracker.dto.AuthResponse; | ||
| import com.SkillsForge.expensetracker.dto.LoginRequest; | ||
| import com.SkillsForge.expensetracker.dto.SignupRequest; | ||
| import com.SkillsForge.expensetracker.dto.UserDto; | ||
| import com.SkillsForge.expensetracker.service.UserService; | ||
| import jakarta.validation.Valid; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.http.HttpStatus; | ||
| import org.springframework.http.ResponseEntity; | ||
| import org.springframework.security.access.prepost.PreAuthorize; | ||
| import org.springframework.web.bind.annotation.GetMapping; | ||
| import org.springframework.web.bind.annotation.PostMapping; | ||
| import org.springframework.web.bind.annotation.RequestBody; | ||
| import org.springframework.web.bind.annotation.RequestMapping; | ||
| import org.springframework.web.bind.annotation.RestController; | ||
|
|
||
| @RestController | ||
| @RequestMapping("/api/v1/auth") | ||
| @RequiredArgsConstructor | ||
| public class AuthController { | ||
|
|
||
| private final UserService userService; | ||
|
|
||
| @PostMapping("/signup") | ||
| public ResponseEntity<AuthResponse> signup(@Valid @RequestBody SignupRequest request) { | ||
| AuthResponse response = userService.signup(request); | ||
| return new ResponseEntity<>(response, HttpStatus.CREATED); | ||
| } | ||
|
|
||
| @PostMapping("/login") | ||
| public ResponseEntity<AuthResponse> login(@Valid @RequestBody LoginRequest request) { | ||
| AuthResponse response = userService.login(request); | ||
| return ResponseEntity.ok(response); | ||
| } | ||
|
|
||
|
|
||
| @GetMapping("/me") | ||
| @PreAuthorize("hasAuthority('USER_READ')") | ||
| public ResponseEntity<UserDto> getCurrentUser() { | ||
| UserDto user = userService.getCurrentUser(); | ||
| return ResponseEntity.ok(user); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
src/main/java/com/SkillsForge/expensetracker/dto/AuthResponse.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| package com.SkillsForge.expensetracker.dto; | ||
|
|
||
| import com.SkillsForge.expensetracker.app.enums.Role; | ||
| import lombok.AllArgsConstructor; | ||
| import lombok.Builder; | ||
| import lombok.Data; | ||
| import lombok.NoArgsConstructor; | ||
|
|
||
| @Data | ||
| @Builder | ||
| @AllArgsConstructor | ||
| @NoArgsConstructor | ||
| public class AuthResponse { | ||
| // no need for validation, this is output | ||
| private String token; // the JWT token string | ||
| private String type; // token type, always "Bearer" | ||
| private Long id; | ||
| private String username; | ||
| private String email; | ||
| private Role role; // USER or ADMIN | ||
| } |
19 changes: 19 additions & 0 deletions
19
src/main/java/com/SkillsForge/expensetracker/dto/LoginRequest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| package com.SkillsForge.expensetracker.dto; | ||
|
|
||
| import jakarta.validation.constraints.NotBlank; | ||
| import lombok.AllArgsConstructor; | ||
| import lombok.Builder; | ||
| import lombok.Data; | ||
| import lombok.NoArgsConstructor; | ||
|
|
||
| @Data | ||
| @Builder | ||
| @AllArgsConstructor | ||
| @NoArgsConstructor | ||
| public class LoginRequest { | ||
| @NotBlank(message = "Username cannot be blank") | ||
| private String username; | ||
|
|
||
| @NotBlank(message = "Password cannot be blank") | ||
| private String password; | ||
| } |
27 changes: 27 additions & 0 deletions
27
src/main/java/com/SkillsForge/expensetracker/dto/SignupRequest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| package com.SkillsForge.expensetracker.dto; | ||
|
|
||
| import jakarta.validation.constraints.Email; | ||
| import jakarta.validation.constraints.NotBlank; | ||
| import jakarta.validation.constraints.Size; | ||
| import lombok.AllArgsConstructor; | ||
| import lombok.Builder; | ||
| import lombok.Data; | ||
| import lombok.NoArgsConstructor; | ||
|
|
||
| @Data | ||
| @Builder | ||
| @AllArgsConstructor | ||
| @NoArgsConstructor | ||
| public class SignupRequest { | ||
| @NotBlank(message = "Email is required") | ||
| private String email; | ||
|
|
||
| @NotBlank(message = "Username cannot be blank") | ||
| @Size(min = 3, max = 20, message = "Username must be between 3 and 20 characters") | ||
| private String username; | ||
|
|
||
| @NotBlank(message = "Password is required") | ||
| @Size(min = 6, max = 50, message = "Password must be between 6 and 50 characters") | ||
| private String password; | ||
| } |
25 changes: 25 additions & 0 deletions
25
src/main/java/com/SkillsForge/expensetracker/dto/UserDto.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| package com.SkillsForge.expensetracker.dto; | ||
|
|
||
| import com.SkillsForge.expensetracker.app.enums.Role; | ||
| import com.SkillsForge.expensetracker.persistence.entity.User; | ||
| import java.time.LocalDateTime; | ||
|
|
||
| public record UserDto( | ||
| Long id, | ||
| String username, | ||
| String email, | ||
| Role role, | ||
| boolean enabled, | ||
| LocalDateTime createdAt, | ||
| LocalDateTime updatedAt) { | ||
| public static UserDto from(User user) { | ||
| return new UserDto( | ||
| user.getId(), | ||
| user.getUsername(), | ||
| user.getEmail(), | ||
| user.getRole(), | ||
| user.isEnabled(), | ||
| user.getCreatedAt(), | ||
| user.getUpdatedAt()); | ||
| } | ||
| } |
7 changes: 7 additions & 0 deletions
7
src/main/java/com/SkillsForge/expensetracker/exception/EmailAlreadyExistsException.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package com.SkillsForge.expensetracker.exception; | ||
|
|
||
| public class EmailAlreadyExistsException extends RuntimeException { | ||
| public EmailAlreadyExistsException(String message) { | ||
| super(message); | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.