Skip to content

Implement ticket access control and status workflow - #14

Merged
addee1 merged 8 commits into
mainfrom
feature/ticket-access-control
Apr 13, 2026
Merged

Implement ticket access control and status workflow#14
addee1 merged 8 commits into
mainfrom
feature/ticket-access-control

Conversation

@addee1

@addee1 addee1 commented Apr 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Implemented access control and status update logic for tickets.

Changes

  • Added role-based access control for viewing tickets

  • Reporter can only view their own tickets

  • Investigator can only view and update assigned tickets

  • Admin has full access

  • Implemented status update restrictions:

    • Investigator can only update status on assigned tickets
    • Enforced valid status transitions (OPEN → IN_PROGRESS → RESOLVED → CLOSED)
  • Added service logic for:

    • assign investigator
    • unassign investigator
    • update ticket status

Notes

  • Merged latest changes from main and resolved conflicts

Summary by CodeRabbit

  • New Features

    • Added "My Tickets" page for reporters and "Assigned Tickets" page for investigators with direct links to ticket views.
  • Security

    • Role-based access enforced for creating, viewing, assigning and updating tickets (ADMIN, INVESTIGATOR, REPORTER).
    • Assignment restricted to admins; investigators have limited status-update rights.
  • Behavior

    • Ticket creation records the authenticated submitter.
    • Assignment and status updates accept validated input and redirect to the ticket view.

@coderabbitai

coderabbitai Bot commented Apr 11, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 371c21b0-4e9a-4f4c-8915-c16079e4fc1c

📥 Commits

Reviewing files that changed from the base of the PR and between 0c0e919 and 702ecfb.

📒 Files selected for processing (1)
  • src/main/java/org/example/alfs/services/TicketService.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/java/org/example/alfs/services/TicketService.java

📝 Walkthrough

Walkthrough

Makes controller endpoints role-restricted via @PreAuthorize, converts assign/status handlers to accept validated DTOs and delegate to TicketService, injects SecurityUtils into TicketService, scopes ticket queries to the authenticated user (my/assigned), and tightens authorization and transition/assignment validation in service methods.

Changes

Cohort / File(s) Summary
Controller: security, DTOs, new endpoints
src/main/java/org/example/alfs/controllers/TicketController.java
Made ticketService private final; added @PreAuthorize to create/view/assign/status/my/assigned endpoints; assignTicket and updateStatus now accept validated DTOs and call service; added GET /my and GET /assigned; redirects updated to redirect:/view/id/{id}.
Service: SecurityUtils injection & auth rules
src/main/java/org/example/alfs/services/TicketService.java
Constructor now requires SecurityUtils; uses authenticated user in ticket creation; added getMyTickets and getMyAssignedTickets; removed public reporter/investigator-id query methods; added checkAccess/requireCurrentUser guards; tightened role checks for status updates, assignment/unassignment, and status transition validation/errors.
API surface / signatures
src/main/java/org/example/alfs/...
TicketService constructor signature changed; new service methods added and some reporter/investigator-id methods removed; controller method signatures updated to include DTOs and method-level security annotations.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Client
participant Controller as TicketController
participant SecUtils as SecurityUtils
participant Service as TicketService
participant Repo as TicketRepository

Client->>Controller: HTTP request (create/view/assign/update/my/assigned)
Controller->>SecUtils: resolve current user / roles
Controller->>Service: call service method (create/get/assign/update/getMy*)
Service->>SecUtils: verify current user / roles
alt authorized
    Service->>Repo: load/save ticket
    Repo-->>Service: ticket/tickets
    Service-->>Controller: TicketViewDTO / list
    Controller-->>Client: HTTP response / redirect
else forbidden
    Service-->>Controller: throws 403
    Controller-->>Client: 403 Forbidden
end

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Poem

🐇 I hopped through routes with careful paws,
Doors locked by roles, DTOs in my claws.
SecurityUtils whispers who I am,
My tickets found, assigned—no sham.
Thump-thump, I celebrate with carrot-paws.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.87% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: implementing role-based access control for tickets and enforcing status workflow transitions.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/ticket-access-control

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 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/alfs/services/TicketService.java`:
- Around line 191-198: The current transition check still allows RESOLVED ->
IN_PROGRESS because ALLOWED_TRANSITIONS contains that mapping; update the
transition rules so a TicketStatus.RESOLVED cannot move back to IN_PROGRESS
(either by removing RESOLVED -> IN_PROGRESS from the ALLOWED_TRANSITIONS map or
by adding an explicit guard in TicketService around ticket.getStatus()/newStatus
to reject RESOLVED -> IN_PROGRESS), ensuring the logic that throws the
ResponseStatusException continues to run for that case.
- Around line 130-155: The access checks in checkAccess and requireAdmin call
securityUtils.getCurrentUser() directly, which can throw raw RuntimeExceptions
and produce 500s; replace those direct calls with the existing auth-aware helper
(the helper that maps missing principal or missing user to 401/403) everywhere
in checkAccess and requireAdmin so lookup failures produce proper
ResponseStatusException 401/403 responses rather than raw RuntimeExceptions, and
don't catch/convert the helper's exceptions — let them propagate as intended.
- Around line 222-239: In assignInvestigator, validate the incoming
investigatorId parameter before calling userRepository.findById: if
investigatorId is null (or otherwise invalid), throw a
ResponseStatusException(HttpStatus.BAD_REQUEST, "Investigator id is required")
so a 400 is returned instead of letting userRepository.findById produce a server
error; place this check near the start of assignInvestigator (before the
userRepository.findById call) referencing investigatorId and
userRepository.findById.
🪄 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: 6edd8c76-2fa7-4345-85c2-6433204d6711

📥 Commits

Reviewing files that changed from the base of the PR and between 90b4906 and ebaf30c.

📒 Files selected for processing (2)
  • src/main/java/org/example/alfs/controllers/TicketController.java
  • src/main/java/org/example/alfs/services/TicketService.java

Comment thread src/main/java/org/example/alfs/services/TicketService.java
Comment thread src/main/java/org/example/alfs/services/TicketService.java
Comment thread src/main/java/org/example/alfs/services/TicketService.java
addee1 added 3 commits April 11, 2026 18:12
- Return 401 instead of 500 when authentication fails
- Disallow transition from RESOLVED to IN_PROGRESS

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/main/java/org/example/alfs/services/TicketService.java (1)

239-306: Centralize status transitions for assignment flows.

Line 279 and Line 304 mutate ticket status directly instead of reusing transition validation. This can drift from ALLOWED_TRANSITIONS over time and create inconsistent workflow behavior.

If reopening to OPEN is intentional for unassignment, make that transition explicit in one shared transition helper (or map), and route updateTicketStatus, assignInvestigator, and unassignInvestigator through the same validator.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/org/example/alfs/services/TicketService.java` around lines 239
- 306, assignInvestigator and unassignInvestigator directly set ticket status
(lines where ticket.setStatus is used) which bypasses the shared transition
rules; centralize status transitions by routing these flows through the same
validator/transition helper used by updateTicketStatus (or introduce a new
method like validateAndApplyTransition/updateStatusWithValidation that consults
ALLOWED_TRANSITIONS), replace direct ticket.setStatus(TicketStatus.IN_PROGRESS)
and ticket.setStatus(TicketStatus.OPEN) with calls to that helper, and ensure
the helper throws the same ResponseStatusException on illegal transitions so all
status changes use a single source of truth.
🤖 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/alfs/services/TicketService.java`:
- Around line 158-167: The method requireCurrentUser currently catches all
RuntimeException from securityUtils.getCurrentUser() and maps them to 401;
change this to only catch authentication-related exceptions (e.g.,
AuthenticationCredentialsNotFoundException, BadCredentialsException,
UsernameNotFoundException or your project's specific auth exception) and wrap
those in a ResponseStatusException(HttpStatus.UNAUTHORIZED, ...), while allowing
all other RuntimeExceptions from securityUtils.getCurrentUser() to propagate
unchanged; update the catch clause in requireCurrentUser to list the specific
exception types (or check the exception instance and rethrow if not
auth-related) so only genuine auth failures become 401.

---

Nitpick comments:
In `@src/main/java/org/example/alfs/services/TicketService.java`:
- Around line 239-306: assignInvestigator and unassignInvestigator directly set
ticket status (lines where ticket.setStatus is used) which bypasses the shared
transition rules; centralize status transitions by routing these flows through
the same validator/transition helper used by updateTicketStatus (or introduce a
new method like validateAndApplyTransition/updateStatusWithValidation that
consults ALLOWED_TRANSITIONS), replace direct
ticket.setStatus(TicketStatus.IN_PROGRESS) and
ticket.setStatus(TicketStatus.OPEN) with calls to that helper, and ensure the
helper throws the same ResponseStatusException on illegal transitions so all
status changes use a single source of truth.
🪄 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: 7db2f343-b37f-4b17-9ca2-f1e0584ab6b9

📥 Commits

Reviewing files that changed from the base of the PR and between 1219c0b and 0c0e919.

📒 Files selected for processing (1)
  • src/main/java/org/example/alfs/services/TicketService.java

Comment thread src/main/java/org/example/alfs/services/TicketService.java
}

ticket.setInvestigator(null);
ticket.setStatus(TicketStatus.OPEN);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick! Maybe revert to

Ticket savedTicket = ticketRepository.save(ticket);

return ticketMapper.entityToViewDTO(savedTicket);

to make it consistent with updateTicketStatus and assignInvestigator?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line 316-317

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants