Feat/comment controller - #55
Conversation
- Implemented an endpoint to create comments with validation and user authentication.
📝 WalkthroughWalkthroughAdds Spring Security dependency, a permissive SecurityConfig, a new CommentController with five REST endpoints using authenticated user context, and updates CommentService.countByRecord to require a User and perform an authorization check before counting comments. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Client as Client
participant Controller as CommentController
participant Service as CommentService
participant Policy as CommentPolicy
participant Repo as CommentRepository
participant MRRepo as MedicalRecordRepository
Client->>Controller: GET /api/comments/record/{recordId}/count
Controller->>Service: countByRecord(recordId, currentUser)
Service->>MRRepo: findById(recordId)
MRRepo-->>Service: MedicalRecord
Service->>Policy: canView(currentUser, MedicalRecord)
Policy-->>Service: allowed / denied
alt allowed
Service->>Repo: countByMedicalRecordId(recordId)
Repo-->>Service: count (Long)
Service-->>Controller: count
Controller-->>Client: 200 OK (count)
else denied
Service-->>Controller: throw ResourceNotFound/AccessDenied
Controller-->>Client: 403/404
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
src/main/java/org/example/vet1177/controllers/CommentController.java (1)
34-42: Prefer201 Createdfor successful comment creation.Line 34 currently returns
200 OK; for resource creation,201 Createdis the better REST contract.HTTP status adjustment
- return ResponseEntity.ok( + return ResponseEntity.status(201).body( CommentResponse.from( commentService.create( request.recordId(), request.body(), currentUser ) ) );🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/org/example/vet1177/controllers/CommentController.java` around lines 34 - 42, Change the controller to return HTTP 201 for successful comment creation: in CommentController replace the ResponseEntity.ok(...) that wraps CommentResponse.from(commentService.create(...)) with a ResponseEntity.status(HttpStatus.CREATED).body(CommentResponse.from(...)) (or ResponseEntity.created(URI).body(...) if you want to include a Location header); ensure HttpStatus is imported and keep the same call to commentService.create(...) and CommentResponse.from(...) unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@pom.xml`:
- Around line 80-83: Create a new configuration class (e.g., ApiSecurityConfig)
and add a `@Bean` method SecurityFilterChain securityFilterChain(HttpSecurity
http) that configures API-specific security: disable formLogin and default login
redirects, disable or selectively configure CSRF for stateless API endpoints,
set sessionManagement to SessionCreationPolicy.STATELESS, configure
exceptionHandling to return 401/403 (instead of redirect), permit anonymous
access to endpoints like /api/auth/** and /api/public/** and require
authentication for other /api/** paths, and enable CORS; also expose a
PasswordEncoder bean (e.g., BCryptPasswordEncoder) and, if you use JWT, ensure
AuthenticationManager/ Jwt filters are wired into the filter chain. Ensure the
class and method names (ApiSecurityConfig and securityFilterChain) are used so
reviewers can find and verify the configuration.
In `@src/main/java/org/example/vet1177/controllers/CommentController.java`:
- Around line 86-88: The countByRecord endpoint leaks metadata because it calls
commentService.countByRecord(recordId) without an authenticated user check;
change the controller and service so countByRecord accepts the currentUser
(e.g., Principal or User) and in CommentService.countByRecord load the medical
record by recordId, call commentPolicy.canView(currentUser, record) and only if
authorized return commentRepository.countByMedicalRecordId(recordId), otherwise
throw an appropriate access denied exception.
- Around line 30-33: The controller methods create, getByRecord, update, and
delete currently inject `@AuthenticationPrincipal` User which is unsafe because
User is a JPA entity and not a UserDetails; change each method signature to
accept `@AuthenticationPrincipal` UserDetails principal (e.g., in create,
getByRecord, update, delete) and then resolve the domain User inside the method
via your UserRepository (e.g.,
userRepository.findByUsername(principal.getUsername()) or
userService.loadByUsername) and handle the case where the domain User is missing
(return 401/404 as appropriate); ensure you update references to the old User
parameter in these methods to use the resolved domain User and keep
request/response types (CreateCommentRequest, CommentResponse) unchanged.
---
Nitpick comments:
In `@src/main/java/org/example/vet1177/controllers/CommentController.java`:
- Around line 34-42: Change the controller to return HTTP 201 for successful
comment creation: in CommentController replace the ResponseEntity.ok(...) that
wraps CommentResponse.from(commentService.create(...)) with a
ResponseEntity.status(HttpStatus.CREATED).body(CommentResponse.from(...)) (or
ResponseEntity.created(URI).body(...) if you want to include a Location header);
ensure HttpStatus is imported and keep the same call to
commentService.create(...) and CommentResponse.from(...) unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 784bc378-fdcd-4fed-a69e-716211ee9920
📒 Files selected for processing (2)
pom.xmlsrc/main/java/org/example/vet1177/controllers/CommentController.java
| <dependency> | ||
| <groupId>org.springframework.boot</groupId> | ||
| <artifactId>spring-boot-starter-security</artifactId> | ||
| </dependency> |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify whether custom Spring Security configuration exists.
# Expected: at least one SecurityFilterChain bean suitable for API usage.
rg -nP --type=java -C3 'SecurityFilterChain|@EnableWebSecurity|HttpSecurity|csrf\s*\(' src/main/java
rg -nP --type=java -C3 '@Bean\s+.*SecurityFilterChain'Repository: ithsjava25/project-backend-org-random-coders
Length of output: 70
Add explicit Spring Security configuration to handle API requests properly.
The spring-boot-starter-security dependency has been added but no SecurityFilterChain bean exists to configure API-specific security (CSRF handling, authentication endpoints, session policies). Without this configuration, API write operations will return 401/403 errors and may trigger unexpected login redirects.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@pom.xml` around lines 80 - 83, Create a new configuration class (e.g.,
ApiSecurityConfig) and add a `@Bean` method SecurityFilterChain
securityFilterChain(HttpSecurity http) that configures API-specific security:
disable formLogin and default login redirects, disable or selectively configure
CSRF for stateless API endpoints, set sessionManagement to
SessionCreationPolicy.STATELESS, configure exceptionHandling to return 401/403
(instead of redirect), permit anonymous access to endpoints like /api/auth/**
and /api/public/** and require authentication for other /api/** paths, and
enable CORS; also expose a PasswordEncoder bean (e.g., BCryptPasswordEncoder)
and, if you use JWT, ensure AuthenticationManager/ Jwt filters are wired into
the filter chain. Ensure the class and method names (ApiSecurityConfig and
securityFilterChain) are used so reviewers can find and verify the
configuration.
| public ResponseEntity<CommentResponse> create( | ||
| @Valid @RequestBody CreateCommentRequest request, | ||
| @AuthenticationPrincipal User currentUser) { | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify principal/type compatibility and all affected injection points.
# Expected:
# - User entity should implement UserDetails OR controller should consume UserDetails/custom principal.
# - All `@AuthenticationPrincipal` usages should align with configured Authentication principal type.
rg -nP --type=java -C3 'class\s+User\b|implements\s+UserDetails' src/main/java/org/example/vet1177/entities/User.java
rg -nP --type=java -C2 '@AuthenticationPrincipal\s+User\b|@AuthenticationPrincipal\s+.*UserDetails\b' src/main/javaRepository: ithsjava25/project-backend-org-random-coders
Length of output: 2439
🏁 Script executed:
# Find security configuration files
fd -e java -e yml -e yaml -e properties | xargs grep -l "SecurityConfig\|UserDetailsService\|@EnableWebSecurity\|AuthenticationProvider" 2>/dev/null | head -20Repository: ithsjava25/project-backend-org-random-coders
Length of output: 70
🏁 Script executed:
# Search for UserDetailsService implementation
rg -n "implements UserDetailsService|class.*UserDetailsService" --type=javaRepository: ithsjava25/project-backend-org-random-coders
Length of output: 70
🏁 Script executed:
# Check if User is registered or used as principal in any configuration
rg -n "User\s*principal|new User|authentication.*User" --type=java -C2 | head -50Repository: ithsjava25/project-backend-org-random-coders
Length of output: 601
🏁 Script executed:
# Search for any Spring Security configuration (including annotations)
rg -n "@EnableWebSecurity|@Configuration|SecurityFilterChain|WebSecurityConfigurerAdapter" --type=javaRepository: ithsjava25/project-backend-org-random-coders
Length of output: 70
🏁 Script executed:
# Search for authentication/security in application.properties or application.yml
fd -e properties -e yml -e yaml | xargs cat 2>/dev/nullRepository: ithsjava25/project-backend-org-random-coders
Length of output: 1150
🏁 Script executed:
# Check if there's a custom principal class or custom UserDetails implementation
rg -n "implements UserDetails|extends User|class.*Principal" --type=javaRepository: ithsjava25/project-backend-org-random-coders
Length of output: 70
🏁 Script executed:
# Look for authentication manager or provider configuration
rg -n "AuthenticationManager|AuthenticationProvider|DaoAuthenticationProvider" --type=javaRepository: ithsjava25/project-backend-org-random-coders
Length of output: 70
🏁 Script executed:
# Search more broadly for any Spring Security related code
rg -n "spring.security|@Bean.*SecurityFilterChain|UserDetailsService" --type=javaRepository: ithsjava25/project-backend-org-random-coders
Length of output: 70
🏁 Script executed:
# Check pom.xml or build.gradle for spring-security dependency
fd -e pom.xml -e gradle.build | xargs cat 2>/dev/null | grep -i "spring-security\|security"Repository: ithsjava25/project-backend-org-random-coders
Length of output: 70
🏁 Script executed:
# List all Java files in the project to understand structure
find src -name "*.java" -type f | head -30Repository: ithsjava25/project-backend-org-random-coders
Length of output: 2143
🏁 Script executed:
# Check the entire User entity class definition
cat -n src/main/java/org/example/vet1177/entities/User.javaRepository: ithsjava25/project-backend-org-random-coders
Length of output: 4598
🏁 Script executed:
# Check if Spring Security is even a dependency - search pom.xml in root
find . -name "pom.xml" -o -name "build.gradle" | head -5Repository: ithsjava25/project-backend-org-random-coders
Length of output: 97
🏁 Script executed:
# Search for any authentication annotation usage or auth filter
rg -n "@RequestHeader.*Authorization|@CookieValue|HttpServletRequest.*getHeader|Authorization" --type=java | head -20Repository: ithsjava25/project-backend-org-random-coders
Length of output: 70
🏁 Script executed:
# Check if there's any servlet filter or interceptor for authentication
rg -n "Filter|Interceptor|@Component|@WebFilter" --type=java | grep -i "auth\|security\|filter" | head -20Repository: ithsjava25/project-backend-org-random-coders
Length of output: 70
🏁 Script executed:
# Look at the main application file to see what's configured
cat -n src/main/java/org/example/vet1177/Vet1177Application.javaRepository: ithsjava25/project-backend-org-random-coders
Length of output: 504
🏁 Script executed:
# Check pom.xml for dependencies, especially spring-security
cat -n pom.xml | head -100Repository: ithsjava25/project-backend-org-random-coders
Length of output: 4027
🏁 Script executed:
# Search for any Bean definitions that might handle authentication
rg -n "@Bean" --type=javaRepository: ithsjava25/project-backend-org-random-coders
Length of output: 70
@AuthenticationPrincipal User is unsafe—User entity does not implement UserDetails.
Lines 32, 50, 66, and 79 inject @AuthenticationPrincipal User currentUser, but User is a JPA entity without UserDetails implementation. With Spring Security auto-configuration active, the principal type mismatch will cause null injection or runtime ClassCastException when authentication is triggered, breaking all authenticated endpoints.
Use @AuthenticationPrincipal UserDetails principal and resolve the domain user separately:
public ResponseEntity<CommentResponse> create(
`@Valid` `@RequestBody` CreateCommentRequest request,
- `@AuthenticationPrincipal` User currentUser) {
+ `@AuthenticationPrincipal` UserDetails principal) {
+
+ User currentUser = userService.findByEmail(principal.getUsername());Apply the same pattern to getByRecord (line 50), update (line 66), and delete (line 79).
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| public ResponseEntity<CommentResponse> create( | |
| @Valid @RequestBody CreateCommentRequest request, | |
| @AuthenticationPrincipal User currentUser) { | |
| public ResponseEntity<CommentResponse> create( | |
| `@Valid` `@RequestBody` CreateCommentRequest request, | |
| `@AuthenticationPrincipal` UserDetails principal) { | |
| User currentUser = userService.findByEmail(principal.getUsername()); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/main/java/org/example/vet1177/controllers/CommentController.java` around
lines 30 - 33, The controller methods create, getByRecord, update, and delete
currently inject `@AuthenticationPrincipal` User which is unsafe because User is a
JPA entity and not a UserDetails; change each method signature to accept
`@AuthenticationPrincipal` UserDetails principal (e.g., in create, getByRecord,
update, delete) and then resolve the domain User inside the method via your
UserRepository (e.g., userRepository.findByUsername(principal.getUsername()) or
userService.loadByUsername) and handle the case where the domain User is missing
(return 401/404 as appropriate); ensure you update references to the old User
parameter in these methods to use the resolved domain User and keep
request/response types (CreateCommentRequest, CommentResponse) unchanged.
| @GetMapping("/record/{recordId}/count") | ||
| public ResponseEntity<Long> countByRecord(@PathVariable UUID recordId) { | ||
| return ResponseEntity.ok(commentService.countByRecord(recordId)); |
There was a problem hiding this comment.
countByRecord lacks authorization context and can leak record metadata.
Line 87 exposes count by recordId without currentUser, and the related service method has no policy check. That allows unauthorized users to infer activity on records via ID enumeration.
Suggested fix (controller + service contract)
- public ResponseEntity<Long> countByRecord(`@PathVariable` UUID recordId) {
- return ResponseEntity.ok(commentService.countByRecord(recordId));
+ public ResponseEntity<Long> countByRecord(
+ `@PathVariable` UUID recordId,
+ `@AuthenticationPrincipal` User currentUser) {
+ return ResponseEntity.ok(commentService.countByRecord(recordId, currentUser));
}// In CommentService:
// 1) Load record
// 2) commentPolicy.canView(currentUser, record)
// 3) return commentRepository.countByMedicalRecordId(recordId)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/main/java/org/example/vet1177/controllers/CommentController.java` around
lines 86 - 88, The countByRecord endpoint leaks metadata because it calls
commentService.countByRecord(recordId) without an authenticated user check;
change the controller and service so countByRecord accepts the currentUser
(e.g., Principal or User) and in CommentService.countByRecord load the medical
record by recordId, call commentPolicy.canView(currentUser, record) and only if
authorized return commentRepository.countByMedicalRecordId(recordId), otherwise
throw an appropriate access denied exception.
…ontroller` and `CommentService` - Require `currentUser` for counting comments. - Introduce `SecurityConfig` with temporary permissive access. - Enforce access control via `CommentPolicy`.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/main/java/org/example/vet1177/controllers/CommentController.java (1)
30-33:⚠️ Potential issue | 🔴 CriticalUnresolved principal-binding risk across all endpoints.
This still injects
@AuthenticationPrincipal Userdirectly. Given current security setup, this can resolve tonull(or incompatible principal type) and break service/policy calls at runtime.#!/bin/bash # Verify principal type compatibility and direct User principal injection. rg -nP --type=java -C3 'class\s+User\b|implements\s+UserDetails' src/main/java/org/example/vet1177/entities/User.java rg -nP --type=java -C2 '@AuthenticationPrincipal\s+User\b' src/main/java/org/example/vet1177/controllers/CommentController.javaAlso applies to: 48-50, 63-67, 77-80, 88-90
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/org/example/vet1177/controllers/CommentController.java` around lines 30 - 33, The controller methods (e.g., CommentController.create) currently inject `@AuthenticationPrincipal` User currentUser which may be null or an incompatible principal type; change the parameter to accept java.security.Principal or org.springframework.security.core.Authentication (e.g., Principal principal or Authentication auth) and resolve the application User explicitly via your user lookup (e.g., UserService.findByUsername(principal.getName())) with null/incompatible-type checks; update all affected methods (the create method and the other endpoints flagged) to validate the resolved User and throw a 401/appropriate exception when absent instead of assuming non-null injection, and add clear error handling/logging for incompatible principal types.
🧹 Nitpick comments (1)
src/main/java/org/example/vet1177/controllers/CommentController.java (1)
34-42: Prefer201 Createdfor successful comment creation.
POST /api/commentscurrently returns200 OK; consider returning201 Createdto match resource-creation semantics.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/org/example/vet1177/controllers/CommentController.java` around lines 34 - 42, Change the POST handler in CommentController to return HTTP 201 when a comment is created: after calling commentService.create(...) and wrapping with CommentResponse.from(...), build a ResponseEntity with status CREATED instead of ok(). Update the method that currently returns ResponseEntity.ok(...) so it uses ResponseEntity.status(HttpStatus.CREATED).body(...) (or ResponseEntity.created(...) with a Location header if desired) while keeping the same payload from CommentResponse.from(...).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/main/java/org/example/vet1177/security/SecurityConfig.java`:
- Around line 17-20: SecurityConfig currently allows all requests via
anyRequest().permitAll(), leaving CommentController endpoints
("/api/comments/**" which expect `@AuthenticationPrincipal` User) unprotected;
update SecurityConfig to remove the global permitAll and explicitly require
authentication for the comment routes (e.g. configure
authorizeHttpRequests/authorizeRequests so "/api/comments/**" -> authenticated()
and non-sensitive routes -> permitAll()), keeping CSRF/other settings as
appropriate; reference the authorizeHttpRequests call in SecurityConfig and the
CommentController path "/api/comments/**" and `@AuthenticationPrincipal` User when
making the change.
---
Duplicate comments:
In `@src/main/java/org/example/vet1177/controllers/CommentController.java`:
- Around line 30-33: The controller methods (e.g., CommentController.create)
currently inject `@AuthenticationPrincipal` User currentUser which may be null or
an incompatible principal type; change the parameter to accept
java.security.Principal or org.springframework.security.core.Authentication
(e.g., Principal principal or Authentication auth) and resolve the application
User explicitly via your user lookup (e.g.,
UserService.findByUsername(principal.getName())) with null/incompatible-type
checks; update all affected methods (the create method and the other endpoints
flagged) to validate the resolved User and throw a 401/appropriate exception
when absent instead of assuming non-null injection, and add clear error
handling/logging for incompatible principal types.
---
Nitpick comments:
In `@src/main/java/org/example/vet1177/controllers/CommentController.java`:
- Around line 34-42: Change the POST handler in CommentController to return HTTP
201 when a comment is created: after calling commentService.create(...) and
wrapping with CommentResponse.from(...), build a ResponseEntity with status
CREATED instead of ok(). Update the method that currently returns
ResponseEntity.ok(...) so it uses
ResponseEntity.status(HttpStatus.CREATED).body(...) (or
ResponseEntity.created(...) with a Location header if desired) while keeping the
same payload from CommentResponse.from(...).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 87f1ec24-7b44-4364-ad7b-3ca7886e2645
📒 Files selected for processing (3)
src/main/java/org/example/vet1177/controllers/CommentController.javasrc/main/java/org/example/vet1177/security/SecurityConfig.javasrc/main/java/org/example/vet1177/services/CommentService.java
| .csrf(csrf -> csrf.disable()) | ||
| .authorizeHttpRequests(auth -> auth | ||
| .anyRequest().permitAll() // ← temporärt, öppnar allt | ||
| ) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify routing auth rules and principal-based controller usage are aligned.
rg -nP --type=java -C3 'anyRequest\(\)\.permitAll\(|requestMatchers\(.+\)\.authenticated\(' src/main/java/org/example/vet1177
rg -nP --type=java -C2 '@AuthenticationPrincipal\s+User\b' src/main/java/org/example/vet1177/controllersRepository: ithsjava25/project-backend-org-random-coders
Length of output: 3625
🏁 Script executed:
#!/bin/bash
# Check CommentController's request mapping and all endpoints
rg -nP --type=java -B5 'class CommentController|@RequestMapping|@PostMapping|@GetMapping|@PutMapping|@DeleteMapping' src/main/java/org/example/vet1177/controllers/CommentController.java | head -40
# Check if other controllers also use `@AuthenticationPrincipal`
rg -nP --type=java '@AuthenticationPrincipal\s+User\b' src/main/java/org/example/vet1177/controllers/ | grep -v CommentControllerRepository: ithsjava25/project-backend-org-random-coders
Length of output: 1000
🏁 Script executed:
#!/bin/bash
# Find all controllers in the codebase
find src/main/java/org/example/vet1177/controllers -name "*.java" -type f
# Check all controllers for authentication requirements
rg -nP --type=java '@RestController|@Controller|@RequestMapping|@AuthenticationPrincipal' src/main/java/org/example/vet1177/controllersRepository: ithsjava25/project-backend-org-random-coders
Length of output: 994
Do not ship with global permitAll on all routes.
Line 19 of SecurityConfig.java opens every endpoint without authentication. The CommentController endpoints (all 5 methods at /api/comments/**) require @AuthenticationPrincipal User but are currently accessible without authentication, creating a critical security gap.
🔐 Suggested hardening
return http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
- .anyRequest().permitAll() // ← temporärt, öppnar allt
+ .requestMatchers("/api/comments/**").authenticated()
+ .anyRequest().permitAll()
)
.build();📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| .csrf(csrf -> csrf.disable()) | |
| .authorizeHttpRequests(auth -> auth | |
| .anyRequest().permitAll() // ← temporärt, öppnar allt | |
| ) | |
| .csrf(csrf -> csrf.disable()) | |
| .authorizeHttpRequests(auth -> auth | |
| .requestMatchers("/api/comments/**").authenticated() | |
| .anyRequest().permitAll() | |
| ) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/main/java/org/example/vet1177/security/SecurityConfig.java` around lines
17 - 20, SecurityConfig currently allows all requests via
anyRequest().permitAll(), leaving CommentController endpoints
("/api/comments/**" which expect `@AuthenticationPrincipal` User) unprotected;
update SecurityConfig to remove the global permitAll and explicitly require
authentication for the comment routes (e.g. configure
authorizeHttpRequests/authorizeRequests so "/api/comments/**" -> authenticated()
and non-sensitive routes -> permitAll()), keeping CSRF/other settings as
appropriate; reference the authorizeHttpRequests call in SecurityConfig and the
CommentController path "/api/comments/**" and `@AuthenticationPrincipal` User when
making the change.
There was a problem hiding this comment.
This is a temporary security configuration to unblock
development and testing. Full JWT implementation with
JwtAuthFilter, stateless sessions and proper endpoint
restrictions will be added in feat/spring-security-config.
There was a problem hiding this comment.
@annikaholmqvist94, understood — thanks for the context! That makes sense as a development unblocking strategy. Just a friendly reminder to ensure the feat/spring-security-config branch enforces authentication on /api/comments/** (and other protected routes) before this reaches production, since the @AuthenticationPrincipal User parameters in CommentController will silently receive null if the endpoints remain unauthenticated at that point.
Would you like me to open a follow-up issue to track the JWT/security hardening work?
There was a problem hiding this comment.
yes please
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
gh issue create \
--repo ithsjava25/project-backend-org-random-coders \
--title "feat: Implement JWT security hardening (JwtAuthFilter, stateless sessions, endpoint restrictions)" \
--assignee annikaholmqvist94 \
--body "## Summary
This issue tracks the full JWT/Spring Security implementation that will replace the temporary permissive \`SecurityConfig\` introduced in PR `#55`.
## Background
PR `#55` ([feat/comment-controller](https://github.com/ithsjava25/project-backend-org-random-coders/pull/55)) added a \`SecurityConfig\` with \`anyRequest().permitAll()\` as a temporary measure to unblock development and testing. This must be hardened before reaching production.
## Tasks
- [ ] Implement \`JwtAuthFilter\` to validate JWT tokens on incoming requests
- [ ] Configure stateless session management (\`SessionCreationPolicy.STATELESS\`)
- [ ] Restrict \`/api/comments/**\` to authenticated users only (replacing the global \`permitAll\`)
- [ ] Restrict other protected routes as appropriate
- [ ] Ensure \`@AuthenticationPrincipal User\` in \`CommentController\` receives a valid non-null principal when endpoints are called with a valid token
## References
- PR `#55` comment: https://github.com/ithsjava25/project-backend-org-random-coders/pull/55#discussion_r3009802568
- Requested by: `@annikaholmqvist94`
## Notes
Until this is implemented, the \`@AuthenticationPrincipal User\` parameters in \`CommentController\` will silently receive \`null\` for unauthenticated requests."
Length of output: 73
@annikaholmqvist94, done! I've opened issue #61 to track the JWT security hardening work:
👉 #61
It covers:
- Implementing
JwtAuthFilter - Configuring stateless session management
- Restricting
/api/comments/**(and other protected routes) to authenticated users - Ensuring
@AuthenticationPrincipal Userreceives a valid non-null principal
Added endpoints for basic comment functionality, Closes #27
Summary by CodeRabbit
New Features
Chores