Aller au contenu

Auth and permissions

Status: Placeholder — to be developed. Last reviewed:Reference structural sibling: guidelines/i18n/translation-rules.md (rule + workflow style).

Scope (when this guideline lands)

Authentication and authorisation conventions: the custom email-based User, login flow, password reset, session vs token (none currently), permission decorators / mixins (LoginRequiredMixin, PermissionRequiredMixin, custom practice-access mixin), where to declare per-view access (decorator vs mixin vs dispatch check), how API endpoints in apps/websites/ authenticate (separate from the admin / user flow).

Out of scope (cross-refs)

  • Multi-tenant row-level isolation (which rows a user sees once they're authenticated) → guidelines/security/multi-tenant-isolation.md (placeholder). This file covers WHICH VIEWS they can reach.
  • PII handling and log redactionguidelines/security/pii-and-logging.md (placeholder).
  • Admin access control (superuser-only per website-pages-audit.md) → guidelines/backend/admin.md (placeholder).
  • Session middleware ordering / LocaleMiddleware placementguidelines/i18n/translation-rules.md.

Sources to mine when writing this

  • apps/accounts/ — custom User model (email-based login), login views, permission mixins. Read all class docstrings.
  • apps/core/permissions.pyfeature_required decorator and FeatureRequiredMixin. Survey usage.
  • apps/core/mixins.py — any auth-adjacent mixins.
  • config/urls.pylogin_required decorators and access patterns at the URL level.
  • Existing views — enumerate the permission patterns in use, converge on one.
  • apps/websites/views_cms.py — the API authentication story (likely a different mechanism — DRF auth class?).

Starter hard rules to investigate

  1. LoginRequiredMixin (or equivalent) on every non-public view. Login pages, password reset, and the website-API endpoints are the only exceptions.
  2. @feature_required('feature_name') decorator (or FeatureRequiredMixin) for feature-gated views — see apps/core/permissions.py pattern.
  3. Permission checks live in the view class, not the template. Templates can use {% if perms.... %} for cosmetic show/hide, but the server must enforce independently.
  4. No @login_required decorator on individual methods — use a class-level mixin so it can't be forgotten on post() etc.
  5. API endpoints have their own auth class (DRF) — separate from session auth used by website views.

Decision points to settle

  1. Where to declare access: decorator on URL pattern vs mixin on view class vs dispatch() check. Codebase has all three; pick one.
  2. Session vs token: project is session-based today. If/when an external integration needs token auth (e.g. Helios talking back), what's the policy?
  3. Password reset flow: built-in Django views or custom? Email content under microcopy guidelines?
  4. Group-based vs feature-based permissions: Django Groups map to feature sets in apps/core/permissions.py. Document the mapping policy.

Known deviations to look for during writing

  • Function-based views without @login_required (silent gap).
  • Permission checks done only in templates ({% if perms... %}) without a server-side mirror.
  • Custom auth bypass for "internal" or "debug" endpoints (security hole).
  • Inconsistent feature-gate decorators across views of the same feature.

If found, file IMMEDIATELY as a backlog item — auth gaps are P0.