fix(tickets,templates): standardize staff permission checks in templates (#151)#159
Conversation
|
@mostlyvirtual — this PR is ready for review. |
2e11e74 to
56d7d58
Compare
There was a problem hiding this comment.
Pull request overview
Standardizes “staff” permission checks across ticket templates and ticket backend logic by using the custom user.is_staff_user flag, and adjusts a few unrelated test/CI/security hardening changes included in the PR.
Changes:
- Replace template conditionals (
user.is_staff,user.is_staff or user.staff_role) withuser.is_staff_useracross ticket UI components. - Update ticket backend permission checks (internal notes + internal attachment access) to rely on
user.is_staff_user. - Misc: improve SES/SNS webhook key-type safety, adjust API security tests to use real HMAC middleware helpers, and tweak CI test discovery invocation.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
services/platform/templates/tickets/detail.html |
Use user.is_staff_user for reopen button visibility |
services/platform/templates/tickets/partials/comments_list.html |
Use user.is_staff_user for internal note visibility |
services/platform/templates/tickets/list.html |
Use user.is_staff_user for staff-specific list UI |
services/platform/templates/tickets/partials/tickets_table.html |
Use user.is_staff_user for staff-only columns/empty-state copy |
services/platform/templates/tickets/partials/status_and_comments.html |
Staff reply actions switch to user.is_staff_user; increase comments container height |
services/platform/templates/components/mobile_header.html |
Business section visibility uses user.is_staff_user |
services/platform/apps/tickets/views.py |
Backend permission checks for internal notes + internal attachment access use user.is_staff_user |
services/portal/templates/tickets/partials/status_and_comments.html |
Increase comments container height |
services/platform/apps/notifications/webhooks.py |
Add RSA public key type check before signature verify |
services/platform/tests/api/test_api_users_security.py |
Portal login lockout tests run through real HMAC middleware via HMACTestMixin |
services/platform/tests/orders/test_orders_edit.py |
Align test expectation with Order._SAFE_DRAFT_FIELDS |
.github/workflows/platform.yml |
Convert affected test module labels to directory paths for discovery |
Comments suppressed due to low confidence (1)
services/platform/apps/tickets/views.py:263
- These permission checks now depend on
user.is_staff_user, but the currentUser.is_staff_userimplementation returnsbool(self.staff_role)(it does not include Django’sis_staff). That means users withis_staff=Truebut an emptystaff_rolewill be treated as non-staff here (can’t create internal notes, comment type becomescustomer, internal attachments blocked, etc.). Fix by updatingis_staff_userto includeis_staff(or adjust these checks to consideruser.is_staffas well) so the new standard doesn’t regress existing staff accounts.
if is_internal and not user.is_staff_user:
messages.error(request, _("❌ You do not have permission to create internal notes."))
return redirect("tickets:detail", pk=ticket_pk)
return None
def _determine_comment_type(user: User, is_internal: bool) -> str:
"""Determine the appropriate comment type based on user permissions."""
if is_internal and user.is_staff_user:
return "internal"
elif user.staff_role in ["support", "admin", "manager"]:
return "support"
else:
return "customer"
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
mostlyvirtual
left a comment
There was a problem hiding this comment.
Re-review: REWORK — 3 blocking issues + incomplete standardization
Must fix before merge (blocking)
1. Merge conflict
PR is CONFLICTING with master. Rebase required. Master has recent commits touching webhooks.py (already on master), test_orders_edit.py, and test_api_users_security.py — all included in this PR as unrelated changes that will conflict.
2. HTMX reply path uses `user.is_staff` instead of `user.is_staff_user`
`tickets/views.py:460` — `can_edit = ticket.status != "closed" or user.is_staff` was missed during migration. A support agent (`staff_role="support"`, `is_staff=False`) sees edit controls on page load but loses them after HTMX reply.
3. HTMX reply path sends ALL comments to template (including internal notes)
`tickets/views.py:461-468` — The HTMX response uses `ticket.comments.all()` without the server-side staff filter that `ticket_detail()` and `ticket_comments_htmx()` apply. Internal notes reach the template for all users — the `{% if %}` template check is the only gate. Apply the same queryset filter:
```python
if user.is_staff_user:
comments = ticket.comments.all().order_by("created_at")
else:
comments = ticket.comments.filter(comment_type__in=["customer", "support"]).order_by("created_at")
```
Should fix
4. `_determine_comment_type` elif still uses raw `staff_role` check
`views.py:260` — `user.staff_role in ["support", "admin", "manager"]` excludes `"billing"` role. Should be `user.is_staff_user` for consistency.
5. Template standardization is incomplete
The PR only migrates ticket templates. `base.html:113`, dashboard (16 occurrences), billing templates, and customer templates still use `user.is_staff or user.staff_role`. This creates inconsistent UX — navbar shows staff options but ticket pages don't (or vice versa) for edge-case users. Per project convention ("template fix cascade"), grep ALL template dirs before committing.
6. Unrelated changes bundled
4 of 12 files are unrelated to template permission checks: `webhooks.py` (RSA type narrowing — already on master), `test_api_users_security.py` (HMAC mixin), `test_orders_edit.py` (editable fields), `platform.yml` (CI fix — already on master). These should be split out or at minimum documented in the PR description.
7. `is_staff_user` property definition may need widening
`models.py:151` — Property is `return bool(self.staff_role)` which drops the `is_staff` leg. The old pattern was `is_staff or staff_role`. A user with `is_staff=True, staff_role=""` (created by `setup_test_users.py` and admin panel) loses staff privileges in ticket views. Verify this is intentional, or widen to `return self.is_staff or bool(self.staff_role) or self.is_superuser`. This is also flagged in PR #154 review — the two PRs should be coordinated.
What's good
- Template migration direction is correct — `user.is_staff_user` is the right target
- `comments_list.html` double-gate (view filter + template check) is solid defense-in-depth
- `mobile_header.html` change is clean
- CSS scroll height adjustment is reasonable (verify Tailwind version supports `max-h-150`)
642a28b to
c8d3fe7
Compare
Review feedback addressedmax-h-150 — no change needed. `max-h-150` is a valid Tailwind CSS v4 utility class (150 × 4px = 600px). This project uses Tailwind v4 where the spacing scale generates these classes natively. IDE confirms: "The class max-h-[600px] can be written as max-h-150". |
…ff_user (captainpragmatic#151) Replace inconsistent staff permission checks (is_staff, user.groups, manual role checking) with unified is_staff_user property across ticket views and templates. Signed-off-by: Ciprian Radulescu <craps2003@gmail.com> Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Ciprian Radulescu <craps2003@gmail.com>
c8d3fe7 to
05e1805
Compare
Summary
user.is_staffanduser.is_staff or user.staff_rolechecks withuser.is_staff_useracross all ticket templates and backend viewsstaff_role="support",is_staff=False) being locked out of reopen button, internal notes, list view staff features, and attachment accessFiles changed (8)
tickets/detail.htmltickets/partials/comments_list.htmltickets/list.htmltickets/partials/tickets_table.htmltickets/partials/status_and_comments.htmlcomponents/mobile_header.htmltickets/views.pystatus_and_comments.htmlTest plan
staff_role="support",is_staff=False) can see reopen button on closed ticketsCloses #151
🤖 Generated with Claude Code