- Use OidcRoleSyncContext for set_role_from_oidc_sync; document JWT peek risk.
- seed_admin without password sets Admin role on existing user (OIDC-only); update docs and test.
- Fix DE translation for 'access this page'; add get? true comment in User.
Register and sign-in call apply_admin_role_from_user_info; users in configured
admin group get Admin role, others get Mitglied. Internal User action + bypass policy.
- Member update_member: on_missing :unrelate → :ignore (no unlink when :user omitted)
- Test: normal_user update linked member without :user keeps link
- Doc: unlink only explicit (user: nil), admin-only; Actor.admin?(nil) note
- Check: defense-in-depth for "user" string key
- Forbid on :user argument presence (not value) to block unlink via nil/empty
- Defensive nil actor handling; policy restricted to create/update only
- Test: Ash.load with actor; test non-admin cannot unlink via user: nil
- Docs: unlink behaviour and policy split
- PermissionSets: Role read :all for own_data, read_only, normal_user; admin keeps full CRUD
- Role resource: authorizers and policies with HasPermission
- Tests: role_policies_test.exs (read all, create/update/destroy admin only)
- Fix existing tests to pass actor or authorize?: false for Role operations
- ActorPermissionSetIs check; bypass policy filters by member_id for own_data only.
- Admin with member_id still gets :all via HasPermission. Tests added.
- Extend permission_sets.ex with resources and pages for new domains
- Adjust HasPermission check for resource/action/scope
- Update roles-and-permissions and implementation-plan docs
- Add permission_sets_test.exs coverage
- Actor.permission_set_name(actor) returns role's permission set (supports nil role load).
- Actor.admin?(actor) returns true for system user or admin permission set.
- ActorIsAdmin policy check delegates to Actor.admin?/1.
- Remove "/" from own_data pages (Mitglied redirected to profile at root).
- Add /users/:id, /users/:id/edit, /users/:id/show/edit and member edit pages
for own_data so members can access own profile and linked member only.
- Read member_id via Ash.Changeset.get_argument_or_attribute/2 so it works
when set as attribute or argument
- Remove unused require Logger
- Document member_id source in moduledoc
- Authorizer and policies: bypass for read (member_id == actor.member_id),
CustomFieldValueCreateScope for create, HasPermission for read/update/destroy.
- HasPermission: pass authorizer into strict_check helper; document that create
must use a dedicated check (no filter).
Pattern match on %Mv.Accounts.User{} instead of generic actor.
Clearer intention, prevents accidental authorization bypasses.
Non-User actors are returned as-is (no-op).
SECURITY: Skip authorization for role loading to avoid circular dependency.
Actor loads their OWN role, needed for authorization itself.
Documented why this is safe.
- Use user.id instead of user_id for Member linked scope
- Use member.user.id for CustomFieldValue linked scope
- Add lazy logger evaluation
- Improve action nil handling
- Add integration tests for filter expressions
- Add /custom_field_values/:id to read_only pages (users can view list, should also view details)
- Add /custom_field_values/:id to normal_user pages
- Refactor tests to reduce duplication (use for-comprehension for structure tests)
- Add tests for invalid input types in valid_permission_set?/1
- Update @spec for valid_permission_set?/1 to accept any() type
- Add explicit ArgumentError for invalid permission set names with helpful message
- Soften performance claim in documentation (intended to be constant-time)
- Add tests for error handling
- Improve maintainability with guard clause for invalid inputs
Both permission sets allow User:update :own, so users should be able
to access their profile page. This makes the implementation consistent
with the documentation and the logical permission model.
- Add types for scope, action, resource_permission, permission_set
- Implement get_permissions/1 for all 4 sets (own_data, read_only, normal_user, admin)
- Implement valid_permission_set?/1 for string and atom validation
- Implement permission_set_name_to_atom/1 with error handling