Skip to content

fix(tickets,templates): standardize staff permission checks in templates (#151)#159

Open
b3lz3but wants to merge 1 commit intocaptainpragmatic:masterfrom
b3lz3but:fix/staff-permission-template-checks
Open

fix(tickets,templates): standardize staff permission checks in templates (#151)#159
b3lz3but wants to merge 1 commit intocaptainpragmatic:masterfrom
b3lz3but:fix/staff-permission-template-checks

Conversation

@b3lz3but
Copy link
Copy Markdown
Contributor

Summary

  • Replace inconsistent user.is_staff and user.is_staff or user.staff_role checks with user.is_staff_user across all ticket templates and backend views
  • Fixes support agents (staff_role="support", is_staff=False) being locked out of reopen button, internal notes, list view staff features, and attachment access
  • Increases comments container max-height from 384px to 600px on both platform and portal to eliminate excessive vertical whitespace

Files changed (8)

File What
tickets/detail.html Reopen button check
tickets/partials/comments_list.html Internal note visibility (2 checks)
tickets/list.html Header, search, skeleton grids (8 checks)
tickets/partials/tickets_table.html Customer column, empty state (5 checks)
tickets/partials/status_and_comments.html Staff reply actions, help text, container height
components/mobile_header.html Business section nav
tickets/views.py Internal note permission, comment type, is_public flag, attachment access
Portal status_and_comments.html Container height fix

Test plan

  • Verify support agent (staff_role="support", is_staff=False) can see reopen button on closed tickets
  • Verify support agent can see internal notes in comment list
  • Verify support agent sees staff features in ticket list (filters, customer column)
  • Verify support agent can access internal note attachments
  • Verify customer users cannot see internal notes or staff features
  • Verify comments container no longer has excessive whitespace below content

Closes #151

🤖 Generated with Claude Code

@b3lz3but
Copy link
Copy Markdown
Contributor Author

@mostlyvirtual — this PR is ready for review.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

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) with user.is_staff_user across 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 current User.is_staff_user implementation returns bool(self.staff_role) (it does not include Django’s is_staff). That means users with is_staff=True but an empty staff_role will be treated as non-staff here (can’t create internal notes, comment type becomes customer, internal attachments blocked, etc.). Fix by updating is_staff_user to include is_staff (or adjust these checks to consider user.is_staff as 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.

Copy link
Copy Markdown
Contributor

@mostlyvirtual mostlyvirtual left a comment

Choose a reason for hiding this comment

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

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`)

@b3lz3but b3lz3but force-pushed the fix/staff-permission-template-checks branch from 642a28b to c8d3fe7 Compare March 27, 2026 15:54
@b3lz3but
Copy link
Copy Markdown
Contributor Author

Review feedback addressed

max-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>
@b3lz3but b3lz3but force-pushed the fix/staff-permission-template-checks branch from c8d3fe7 to 05e1805 Compare March 27, 2026 21:57
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.

fix(tickets,templates): standardize staff permission checks in templates

3 participants