fix: let staff bypass object-level project permission checks #24

Merged
Gilles merged 1 commit from fix/staff-object-permission-bypass into master 2026-10-31 18:59:19 +00:00
Owner

Summary

  • HasProjectRole.has_object_permission and CanValidateProject.has_object_permission (apps/orgs/permissions.py) never special-cased is_staff, even though every get_queryset() in apps.specs/apps.exports already does -- so list/create worked for staff with no ProjectMembership, but retrieve/update/delete (and PdfExportJobViewSet.download) 403'd.
  • Reproduced live: staff user created a PDF export job on a project with no membership there (create succeeded, perform_create has its own explicit staff check), then got 403 on both retrieving the job and downloading it.
  • Added the same is_staff bypass to both has_object_permission methods.

Test plan

  • New test: staff with no membership creates a job, then successfully retrieves and downloads it (previously 403 on both).
  • pytest -- 146/146 passing.
  • pylint/bandit/autopep8 --max-line-length=99 -- clean.

Closes #23.

🤖 Generated with Claude Code

https://claude.ai/code/session_013EeueXTWCT4Y6EbeideZcm

## Summary - `HasProjectRole.has_object_permission` and `CanValidateProject.has_object_permission` (`apps/orgs/permissions.py`) never special-cased `is_staff`, even though every `get_queryset()` in `apps.specs`/`apps.exports` already does -- so list/create worked for staff with no `ProjectMembership`, but retrieve/update/delete (and `PdfExportJobViewSet.download`) 403'd. - Reproduced live: staff user created a PDF export job on a project with no membership there (create succeeded, `perform_create` has its own explicit staff check), then got 403 on both retrieving the job and downloading it. - Added the same `is_staff` bypass to both `has_object_permission` methods. ## Test plan - [x] New test: staff with no membership creates a job, then successfully retrieves and downloads it (previously 403 on both). - [x] `pytest` -- 146/146 passing. - [x] `pylint`/`bandit`/`autopep8 --max-line-length=99` -- clean. Closes #23. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_013EeueXTWCT4Y6EbeideZcm
fix: let staff bypass object-level project permission checks
All checks were successful
ci / test (pull_request) Successful in 3m26s
ci / e2e (pull_request) Has been skipped
ci / docker (pull_request) Has been skipped
ci / deploy (pull_request) Has been skipped
95c7cd5555
get_queryset() in every apps.specs/apps.exports viewset already special-
cases is_staff, so list/create worked fine for staff with no
ProjectMembership. has_object_permission() on HasProjectRole/
CanValidateProject (apps/orgs/permissions.py) never did, so any single-
object action (retrieve/update/delete, including PdfExportJobViewSet.
download) 403'd for staff outside their own memberships.

Reproduced live: staff user created PDF export job #6 on a project with
no membership there (create succeeded via perform_create's own explicit
check), then got 403 on both the job's retrieve and its /download/ --
exactly what was reported as "erreur 403 au téléchargement".

Closes #23.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013EeueXTWCT4Y6EbeideZcm
Author
Owner
<!-- argus-link-bot:thierryade/backend --> 📊 [Rapports Argus pour cette PR](https://reports.stationmyr.net/thierryade/backend/pr/24)
Gilles merged commit b3c948a60c into master 2026-10-31 18:59:19 +00:00
Gilles deleted branch fix/staff-object-permission-bypass 2026-10-31 18:59:19 +00:00
Sign in to join this conversation.
No description provided.