[FEATURE]: User Resource Policies #363

Closed
opened 2026-01-22 11:11:06 +01:00 by moritz · 0 comments
Owner

Description:

Add authorization policies to the User resource. Special case: Users can always read/update their own credentials.

Tasks:

  1. Open lib/mv/accounts/user.ex
  2. Add policies block
  3. Add special policy: Allow user to always access their own account (before general policy)
    policy action_type([:read, :update]) do
      authorize_if expr(id == ^actor(:id))
    end
    
  4. Add general policy: Check HasPermission for all actions
  5. Ensure :destroy is admin-only (via HasPermission)
  6. Preload :role relationship for actor

Policy Order:

  1. Allow user to read/update own account (id == actor.id)
  2. Check HasPermission (for admin operations)
  3. Default: Forbid

Acceptance Criteria:

  • User can always read/update own credentials
  • Only admin can read/update other users
  • Only admin can destroy users
  • Policy order is correct
  • Actor preloads :role relationship

Test Strategy (TDD):

Own Data Tests (All Roles):

  • User with :own_data can read own user record
  • User with :own_data can update own email/password
  • User with :own_data cannot read other users
  • User with :read_only can read own data
  • User with :normal_user can read own data
  • Verify special policy takes precedence

Admin Tests:

  • Admin can read all users
  • Admin can update any user's credentials
  • Admin can destroy users
  • Admin has unrestricted access

Forbidden Tests:

  • Non-admin cannot read other users
  • Non-admin cannot update other users
  • Non-admin cannot destroy users

Test File: test/mv/accounts/user_policies_test.exs

**Description:** Add authorization policies to the User resource. Special case: Users can always read/update their own credentials. **Tasks:** 1. Open `lib/mv/accounts/user.ex` 2. Add `policies` block 3. Add special policy: Allow user to always access their own account (before general policy) ```elixir policy action_type([:read, :update]) do authorize_if expr(id == ^actor(:id)) end ``` 4. Add general policy: Check HasPermission for all actions 5. Ensure :destroy is admin-only (via HasPermission) 6. Preload :role relationship for actor **Policy Order:** 1. Allow user to read/update own account (id == actor.id) 2. Check HasPermission (for admin operations) 3. Default: Forbid **Acceptance Criteria:** - [ ] User can always read/update own credentials - [ ] Only admin can read/update other users - [ ] Only admin can destroy users - [ ] Policy order is correct - [ ] Actor preloads :role relationship **Test Strategy (TDD):** **Own Data Tests (All Roles):** - User with :own_data can read own user record - User with :own_data can update own email/password - User with :own_data cannot read other users - User with :read_only can read own data - User with :normal_user can read own data - Verify special policy takes precedence **Admin Tests:** - Admin can read all users - Admin can update any user's credentials - Admin can destroy users - Admin has unrestricted access **Forbidden Tests:** - Non-admin cannot read other users - Non-admin cannot update other users - Non-admin cannot destroy users **Test File:** `test/mv/accounts/user_policies_test.exs`
moritz added the
M
label 2026-01-22 11:11:06 +01:00
moritz self-assigned this 2026-01-22 11:11:06 +01:00
moritz added this to the Sprint 11: 08.01-29.01 project 2026-01-22 11:11:06 +01:00
moritz added this to the We have different roles and permissions milestone 2026-02-03 16:41:54 +01:00
Sign in to join this conversation.
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: local-it/mitgliederverwaltung#363
No description provided.