Member Resource Policies closes #345 #346
3 changed files with 44 additions and 15 deletions
|
|
@ -41,8 +41,10 @@ defmodule Mv.EmailSync.Changes.SyncMemberEmailToUser do
|
|||
Ash.Changeset.around_transaction(changeset, fn cs, callback ->
|
||||
result = callback.(cs)
|
||||
|
||||
actor = Map.get(changeset.context, :actor)
|
||||
|
||||
with {:ok, member} <- Helpers.extract_record(result),
|
||||
linked_user <- Loader.get_linked_user(member) do
|
||||
linked_user <- Loader.get_linked_user(member, actor) do
|
||||
Helpers.sync_email_to_linked_record(result, linked_user, new_email)
|
||||
else
|
||||
_ -> result
|
||||
|
|
|
|||
|
|
@ -33,7 +33,17 @@ defmodule Mv.EmailSync.Changes.SyncUserEmailToMember do
|
|||
if Map.get(context, :syncing_email, false) do
|
||||
changeset
|
||||
else
|
||||
sync_email(changeset)
|
||||
# Ensure actor is in changeset context - get it from context if available
|
||||
actor = Map.get(changeset.context, :actor) || Map.get(context, :actor)
|
||||
|
||||
changeset_with_actor =
|
||||
if actor && !Map.has_key?(changeset.context, :actor) do
|
||||
Ash.Changeset.put_context(changeset, :actor, actor)
|
||||
else
|
||||
changeset
|
||||
end
|
||||
|
||||
sync_email(changeset_with_actor)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -42,7 +52,7 @@ defmodule Mv.EmailSync.Changes.SyncUserEmailToMember do
|
|||
result = callback.(cs)
|
||||
|
||||
with {:ok, record} <- Helpers.extract_record(result),
|
||||
{:ok, user, member} <- get_user_and_member(record) do
|
||||
{:ok, user, member} <- get_user_and_member(record, cs) do
|
||||
# When called from Member-side, we need to update the member in the result
|
||||
# When called from User-side, we update the linked member in DB only
|
||||
case record do
|
||||
|
|
@ -61,15 +71,19 @@ defmodule Mv.EmailSync.Changes.SyncUserEmailToMember do
|
|||
end
|
||||
|
||||
# Retrieves user and member - works for both resource types
|
||||
defp get_user_and_member(%Mv.Accounts.User{} = user) do
|
||||
case Loader.get_linked_member(user) do
|
||||
defp get_user_and_member(%Mv.Accounts.User{} = user, changeset) do
|
||||
actor = Map.get(changeset.context, :actor)
|
||||
|
||||
case Loader.get_linked_member(user, actor) do
|
||||
nil -> {:error, :no_member}
|
||||
member -> {:ok, user, member}
|
||||
end
|
||||
end
|
||||
|
||||
defp get_user_and_member(%Mv.Membership.Member{} = member) do
|
||||
case Loader.load_linked_user!(member) do
|
||||
defp get_user_and_member(%Mv.Membership.Member{} = member, changeset) do
|
||||
actor = Map.get(changeset.context, :actor)
|
||||
|
||||
case Loader.load_linked_user!(member, actor) do
|
||||
{:ok, user} -> {:ok, user, member}
|
||||
error -> error
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,11 +6,16 @@ defmodule Mv.EmailSync.Loader do
|
|||
|
||||
@doc """
|
||||
Loads the member linked to a user, returns nil if not linked or on error.
|
||||
"""
|
||||
def get_linked_member(%{member_id: nil}), do: nil
|
||||
|
||||
def get_linked_member(%{member_id: id}) do
|
||||
case Ash.get(Mv.Membership.Member, id) do
|
||||
Accepts optional actor for authorization.
|
||||
"""
|
||||
def get_linked_member(user, actor \\ nil)
|
||||
def get_linked_member(%{member_id: nil}, _actor), do: nil
|
||||
|
||||
def get_linked_member(%{member_id: id}, actor) do
|
||||
opts = if actor, do: [actor: actor], else: []
|
||||
|
||||
case Ash.get(Mv.Membership.Member, id, opts) do
|
||||
{:ok, member} -> member
|
||||
{:error, _} -> nil
|
||||
end
|
||||
|
|
@ -18,9 +23,13 @@ defmodule Mv.EmailSync.Loader do
|
|||
|
||||
@doc """
|
||||
Loads the user linked to a member, returns nil if not linked or on error.
|
||||
|
||||
Accepts optional actor for authorization.
|
||||
"""
|
||||
def get_linked_user(member) do
|
||||
case Ash.load(member, :user) do
|
||||
def get_linked_user(member, actor \\ nil) do
|
||||
opts = if actor, do: [actor: actor], else: []
|
||||
|
||||
case Ash.load(member, :user, opts) do
|
||||
{:ok, %{user: user}} -> user
|
||||
{:error, _} -> nil
|
||||
end
|
||||
|
|
@ -29,9 +38,13 @@ defmodule Mv.EmailSync.Loader do
|
|||
@doc """
|
||||
Loads the user linked to a member, returning an error tuple if not linked.
|
||||
Useful when a link is required for the operation.
|
||||
|
||||
Accepts optional actor for authorization.
|
||||
"""
|
||||
def load_linked_user!(member) do
|
||||
case Ash.load(member, :user) do
|
||||
def load_linked_user!(member, actor \\ nil) do
|
||||
opts = if actor, do: [actor: actor], else: []
|
||||
|
||||
case Ash.load(member, :user, opts) do
|
||||
{:ok, %{user: user}} when not is_nil(user) -> {:ok, user}
|
||||
{:ok, _} -> {:error, :no_linked_user}
|
||||
{:error, _} = error -> error
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue