Harden member user-link check: argument presence, nil actor, policy scope

- 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
This commit is contained in:
Moritz 2026-02-04 13:46:49 +01:00
parent 34e049ef32
commit 543fded102
Signed by: moritz
GPG key ID: 1020A035E5DD0824
4 changed files with 79 additions and 36 deletions

View file

@ -312,11 +312,17 @@ defmodule Mv.Membership.Member do
authorize_if expr(id == ^actor(:member_id))
end
# GENERAL: Check permissions from user's role; forbid memberuser link unless admin
# ForbidMemberUserLinkUnlessAdmin: only admins may pass :user on create/update (no-op for read/destroy).
# READ/DESTROY: Check permissions only (no :user argument on these actions)
policy action_type([:read, :destroy]) do
description "Check permissions from user's role"
authorize_if Mv.Authorization.Checks.HasPermission
end
# CREATE/UPDATE: Forbid memberuser link unless admin, then check permissions
# ForbidMemberUserLinkUnlessAdmin: only admins may pass :user (link or unlink via nil/empty).
# HasPermission: :own_data → update linked; :read_only → no update; :normal_user/admin → update all.
policy action_type([:read, :create, :update, :destroy]) do
description "Check permissions and forbid user link unless admin"
policy action_type([:create, :update]) do
description "Forbid user link unless admin; then check permissions"
forbid_if Mv.Authorization.Checks.ForbidMemberUserLinkUnlessAdmin
authorize_if Mv.Authorization.Checks.HasPermission
end