mitgliederverwaltung/docs/page-permission-route-coverage.md

5 KiB
Raw Blame History

Page Permission Route and Test Coverage

This document lists all protected routes, which permission set may access them, and how they are covered by tests.

Protected Routes (Router scope with CheckPagePermission in :browser)

Route own_data read_only normal_user admin
/
/members
/members/new
/members/:id ✓ (linked only)
/members/:id/edit ✓ (linked only)
/members/:id/show/edit ✓ (linked only)
/users
/users/new
/users/:id ✓ (own only) ✓ (own only) ✓ (own only)
/users/:id/edit ✓ (own only) ✓ (own only) ✓ (own only)
/users/:id/show/edit ✓ (own only) ✓ (own only) ✓ (own only)
/settings
/membership_fee_settings
/membership_fee_settings/new_fee_type
/membership_fee_settings/:id/edit_fee_type
/groups
/groups/new
/groups/:slug
/groups/:slug/edit
/statistics
/admin/roles
/admin/roles/new
/admin/roles/:id
/admin/roles/:id/edit
/join_requests
/join_requests/:id
/admin/datafields
/admin/import
/admin/import/template/en
/admin/import/template/de
/members/export.csv
/members/export.pdf

Note: Permission sets define /custom_field_values and related paths, but there are no such routes in the router; those entries are for future use. The Approval UI routes /join_requests and /join_requests/:id are implemented and routed: normal_user lists them explicitly in its permission set, and admin reaches them through the * wildcard.

Note on admin-only routes: /admin/datafields, /admin/import, /admin/import/template/en, /admin/import/template/de, and /members/export.pdf are not listed explicitly in any permission set; only admin can reach them, via the * wildcard. /members/export.csv is additionally granted explicitly to read_only and normal_user.

Public Paths (no permission check)

  • /auth*, /register, /reset, /sign-in, /sign-out, /confirm*, /password-reset*, /set_locale, /join

The public join page GET /join is explicitly public (Subtask 4); unauthenticated access returns 200 when join form is enabled, 404 when disabled. Unit test: test/mv_web/plugs/check_page_permission_test.exs (plug allows /join); integration: test/mv_web/live/join_live_test.exs.

The join confirmation route GET /confirm_join/:token is public (matched by /confirm*). Unit tests: test/mv_web/controllers/join_confirm_controller_test.exs (stubbed callback, no integration).

Test Coverage

File: test/mv_web/plugs/check_page_permission_test.exs covers both unit tests (plug called directly with a mock conn) and full-router integration tests. The route→permission-set matrix above is the source of truth; each permission set (own_data/Mitglied, read_only, normal_user/Kassenwart, admin) is exercised there. Allowed routes return 200; denied routes return 302 → /users/:id. GET / redirects own_data to its profile. Unauthenticated access is denied and redirected to /sign-in; public paths (/auth/sign-in, /register) are allowed. Error cases (no role, invalid permission_set_name) deny.

Two coverage notes:

  • Linked-member routes (/members/:id* for own_data) are covered by plug unit tests; full-router integration tests for the linked member are skipped due to session/LiveView constraints.
  • Join requests: normal_user and admin are allowed /join_requests and /join_requests/:id (normal_user via its explicit permission-set pages, admin via the * wildcard); read_only and own_data are denied.

Plug behaviour: reserved segments

The plug treats "new" as a reserved path segment so that patterns like /members/:id and /groups/:slug do not match /members/new or /groups/new. Thus /groups/new is only allowed when the permission set explicitly lists /groups/new (currently only admin).

Role and member_id loading

The plug may reload the user's role (and optionally member_id) before checking page permission. Session/load_from_session can leave the role unloaded; the plug uses Mv.Authorization.Actor.ensure_loaded/1 (and, when needed, loads member_id) so that permission checks always have the required data. No change to session loading is required; this is documented for clarity.