From f0134f00eeb7b1f2424be554600779b92a8e4bb8 Mon Sep 17 00:00:00 2001 From: Moritz Date: Fri, 30 Jan 2026 11:13:41 +0100 Subject: [PATCH 1/2] Docs: note User-Member Linking enforcement in code - update_user restricted via ActorIsAdmin; Form gates Member-Linking UI --- docs/roles-and-permissions-architecture.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/roles-and-permissions-architecture.md b/docs/roles-and-permissions-architecture.md index 5b930a7..dbf2353 100644 --- a/docs/roles-and-permissions-architecture.md +++ b/docs/roles-and-permissions-architecture.md @@ -2002,6 +2002,8 @@ Users and Members are separate entities that can be linked. Special rules: - A user cannot link themselves to an existing member - A user CAN create a new member and be directly linked to it (self-service) +**Enforcement:** The User resource restricts the `update_user` action (which accepts the `member` argument for link/unlink) to admins only via `Mv.Authorization.Checks.ActorIsAdmin`. The UserLive.Form shows the Member-Linking UI and runs member link/unlink on save only when the current user is admin; non-admins use the `:update` action (email only) for profile edit. + ### Approach: Separate Ash Actions We use **different Ash actions** to enforce different policies: From 6e13a3aa341234de522d2f716ee95f0e50123488 Mon Sep 17 00:00:00 2001 From: Moritz Date: Fri, 30 Jan 2026 11:13:41 +0100 Subject: [PATCH 2/2] Docs: note User-Member Linking enforcement in code - update_user restricted via ActorIsAdmin; Form gates Member-Linking UI --- docs/roles-and-permissions-architecture.md | 2 ++ lib/mv/authorization/permission_sets.ex | 3 --- lib/mv_web/live/user_live/form.ex | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/roles-and-permissions-architecture.md b/docs/roles-and-permissions-architecture.md index 5b930a7..dbf2353 100644 --- a/docs/roles-and-permissions-architecture.md +++ b/docs/roles-and-permissions-architecture.md @@ -2002,6 +2002,8 @@ Users and Members are separate entities that can be linked. Special rules: - A user cannot link themselves to an existing member - A user CAN create a new member and be directly linked to it (self-service) +**Enforcement:** The User resource restricts the `update_user` action (which accepts the `member` argument for link/unlink) to admins only via `Mv.Authorization.Checks.ActorIsAdmin`. The UserLive.Form shows the Member-Linking UI and runs member link/unlink on save only when the current user is admin; non-admins use the `:update` action (email only) for profile edit. + ### Approach: Separate Ash Actions We use **different Ash actions** to enforce different policies: diff --git a/lib/mv/authorization/permission_sets.ex b/lib/mv/authorization/permission_sets.ex index 33964be..858748d 100644 --- a/lib/mv/authorization/permission_sets.ex +++ b/lib/mv/authorization/permission_sets.ex @@ -120,7 +120,6 @@ defmodule Mv.Authorization.PermissionSets do pages: [ # No "/" - Mitglied must not see member index at root (same content as /members). # Own profile (sidebar links to /users/:id) and own user edit - "/profile", "/users/:id", "/users/:id/edit", "/users/:id/show/edit", @@ -156,7 +155,6 @@ defmodule Mv.Authorization.PermissionSets do pages: [ "/", # Own profile (sidebar links to /users/:id; redirect target must be allowed) - "/profile", "/users/:id", "/users/:id/edit", "/users/:id/show/edit", @@ -206,7 +204,6 @@ defmodule Mv.Authorization.PermissionSets do pages: [ "/", # Own profile (sidebar links to /users/:id; redirect target must be allowed) - "/profile", "/users/:id", "/users/:id/edit", "/users/:id/show/edit", diff --git a/lib/mv_web/live/user_live/form.ex b/lib/mv_web/live/user_live/form.ex index b24b214..f3cec75 100644 --- a/lib/mv_web/live/user_live/form.ex +++ b/lib/mv_web/live/user_live/form.ex @@ -95,7 +95,7 @@ defmodule MvWeb.UserLive.Form do - <%= if @user do %> + <%= if @user && @can_manage_member_linking do %>

{gettext("Admin Note")}: {gettext(