Fix/owner case creation rights#228
Conversation
…strictions and add closed record validation
… unnecessary type check
📝 WalkthroughWalkthroughAuthorization logic refactored across policies: Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 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: 1
🧹 Nitpick comments (2)
src/test/java/org/example/vet1177/policy/MedicalRecordPolicyTest.java (1)
145-149: Optional: also assert the message to lock in ordering.The test guarantees type but not that the forbidden path came from the role check rather than any other
ForbiddenException. Adding.hasMessage("Ägare får inte uppdatera journaler")would pin the ordering (role → isFinal) more strictly and future-proof against regressions where someone adds an earlier forbidden throw.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/test/java/org/example/vet1177/policy/MedicalRecordPolicyTest.java` around lines 145 - 149, The test canUpdate_ownerOnClosedRecord_shouldThrowForbiddenNotBusinessRule currently only asserts the exception type, so add an assertion on the exception message to ensure the forbidden came from the role check ordering; update the assertion on policy.canUpdate(owner, closedRecord) to also call .hasMessage("Ägare får inte uppdatera journaler") after .isInstanceOf(ForbiddenException.class) so the test verifies both type and exact message.src/main/java/org/example/vet1177/policy/AttachmentPolicy.java (1)
36-58: Minor: authz check runs after file validation.
validateFileType/validateFileSizerun before the role/ownership switch, so an unauthorized caller uploading a bad file gets aBusinessRuleExceptionabout file format/size instead of a 403. Not a security hole — the call is still rejected — but it leaks business rules to callers who shouldn't be touching the record and can be confusing to debug. Consider reordering: role/ownership first, then file-content validations.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/org/example/vet1177/policy/AttachmentPolicy.java` around lines 36 - 58, The authorization checks in canUpload are performed after file validations, leaking business rules to unauthorized callers; reorder the logic in canUpload so the role/ownership switch (checks using user.getRole(), user.getClinic(), record.getClinic(), record.getOwner(), record.getStatus(), and RecordStatus.CLOSED) runs first and returns/throws ForbiddenException for ADMIN/VET/OWNER as appropriate, and only after passing those auth checks call validateFileType(contentType) and validateFileSize(fileSize) (including the fileSize <= 0 IllegalArgumentException check) so file-format/size errors are only exposed to authorized callers.
🤖 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/policy/AttachmentPolicy.java`:
- Around line 51-56: Replace the direct enum comparison in AttachmentPolicy's
OWNER branch: instead of checking "record.getStatus() == RecordStatus.CLOSED"
use the existing status helper by calling "record.getStatus().isFinal()"; update
the conditional in the OWNER case (inside the AttachmentPolicy class, where
record.getOwner() is compared to user.getId()) to throw the same
ForbiddenException when record.getStatus().isFinal() is true so it matches
MedicalRecordService/MedicalRecordPolicy/CommentPolicy behavior.
---
Nitpick comments:
In `@src/main/java/org/example/vet1177/policy/AttachmentPolicy.java`:
- Around line 36-58: The authorization checks in canUpload are performed after
file validations, leaking business rules to unauthorized callers; reorder the
logic in canUpload so the role/ownership switch (checks using user.getRole(),
user.getClinic(), record.getClinic(), record.getOwner(), record.getStatus(), and
RecordStatus.CLOSED) runs first and returns/throws ForbiddenException for
ADMIN/VET/OWNER as appropriate, and only after passing those auth checks call
validateFileType(contentType) and validateFileSize(fileSize) (including the
fileSize <= 0 IllegalArgumentException check) so file-format/size errors are
only exposed to authorized callers.
In `@src/test/java/org/example/vet1177/policy/MedicalRecordPolicyTest.java`:
- Around line 145-149: The test
canUpdate_ownerOnClosedRecord_shouldThrowForbiddenNotBusinessRule currently only
asserts the exception type, so add an assertion on the exception message to
ensure the forbidden came from the role check ordering; update the assertion on
policy.canUpdate(owner, closedRecord) to also call .hasMessage("Ägare får inte
uppdatera journaler") after .isInstanceOf(ForbiddenException.class) so the test
verifies both type and exact message.
🪄 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: f6a846f4-f5f1-4d51-a728-d97f7a9513c8
📒 Files selected for processing (6)
src/main/java/org/example/vet1177/policy/AttachmentPolicy.javasrc/main/java/org/example/vet1177/policy/CommentPolicy.javasrc/main/java/org/example/vet1177/policy/MedicalRecordPolicy.javasrc/main/java/org/example/vet1177/security/SecurityConfig.javasrc/test/java/org/example/vet1177/policy/CommentPolicyTest.javasrc/test/java/org/example/vet1177/policy/MedicalRecordPolicyTest.java
| case OWNER -> { | ||
| if (!record.getOwner().getId().equals(user.getId())) | ||
| throw new ForbiddenException("Du kan bara ladda upp bilagor på egna ärenden"); | ||
| if (record.getStatus() == RecordStatus.CLOSED) | ||
| throw new ForbiddenException("Bilagor kan inte laddas upp på stängda ärenden"); | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
fd -t f 'RecordStatus.java' --exec cat {}
rg -nP '\bisFinal\s*\(' --type=java -C2Repository: ithsjava25/project-backend-org-random-coders
Length of output: 5640
Use RecordStatus.isFinal() instead of == CLOSED for consistency with the rest of the codebase.
MedicalRecordService, MedicalRecordPolicy, and CommentPolicy all use record.getStatus().isFinal(). For consistency, AttachmentPolicy should do the same instead of the direct enum comparison.
♻️ Proposed fix
case OWNER -> {
if (!record.getOwner().getId().equals(user.getId()))
throw new ForbiddenException("Du kan bara ladda upp bilagor på egna ärenden");
- if (record.getStatus() == RecordStatus.CLOSED)
+ if (record.getStatus().isFinal())
throw new ForbiddenException("Bilagor kan inte laddas upp på stängda ärenden");
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/main/java/org/example/vet1177/policy/AttachmentPolicy.java` around lines
51 - 56, Replace the direct enum comparison in AttachmentPolicy's OWNER branch:
instead of checking "record.getStatus() == RecordStatus.CLOSED" use the existing
status helper by calling "record.getStatus().isFinal()"; update the conditional
in the OWNER case (inside the AttachmentPolicy class, where record.getOwner() is
compared to user.getId()) to throw the same ForbiddenException when
record.getStatus().isFinal() is true so it matches
MedicalRecordService/MedicalRecordPolicy/CommentPolicy behavior.
Efter #216 kunde OWNER inte längre skapa ärenden eller ladda upp bilagor. Den här PR:en särar på "skapa/ladda upp/läsa" från "uppdatera/stänga/radera" så att OWNER fungerar som på 1177 kan
registrera och följa sitt eget djurs ärende
OWNER kan
OWNER kan inte
Ändringar
SecurityConfig
MedicalRecordPolicy
AttachmentPolicy
CommentPolicy
Tester
Test plan
Summary by CodeRabbit
Bug Fixes
Chores