diff --git a/lib/membership/member.ex b/lib/membership/member.ex index 6ab6668..76ed471 100644 --- a/lib/membership/member.ex +++ b/lib/membership/member.ex @@ -333,10 +333,10 @@ defmodule Mv.Membership.Member do authorize_if Mv.Authorization.Checks.HasPermission end - # Internal sync action: allow setting vereinfacht_contact_id (used only by SyncContact change). + # Internal sync action: only SystemActor may set vereinfacht_contact_id (used by SyncContact change). policy action(:set_vereinfacht_contact_id) do - description "Allow internal sync to set Vereinfacht contact ID" - authorize_if always() + description "Only system actor may set Vereinfacht contact ID" + authorize_if Mv.Authorization.Checks.ActorIsSystemUser end # CREATE/UPDATE: Forbid member–user link unless admin, then check permissions diff --git a/lib/mv/authorization/checks/actor_is_system_user.ex b/lib/mv/authorization/checks/actor_is_system_user.ex new file mode 100644 index 0000000..a614a83 --- /dev/null +++ b/lib/mv/authorization/checks/actor_is_system_user.ex @@ -0,0 +1,15 @@ +defmodule Mv.Authorization.Checks.ActorIsSystemUser do + @moduledoc """ + Policy check: true only when the actor is the system user (e.g. system@mila.local). + + Used to restrict internal actions (e.g. Member.set_vereinfacht_contact_id) so that + only code paths using SystemActor can perform them, not regular admins. + """ + use Ash.Policy.SimpleCheck + + @impl true + def describe(_opts), do: "actor is the system user" + + @impl true + def match?(actor, _context, _opts), do: Mv.Helpers.SystemActor.system_user?(actor) +end