Fix System missing system actor in prod and prevent deletion #379
2 changed files with 35 additions and 5 deletions
|
|
@ -172,6 +172,31 @@ defmodule Mv.Helpers.SystemActor do
|
|||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns whether the given user is the system actor user (case-insensitive email match).
|
||||
|
||||
Use this instead of ad-hoc `to_string(user.email) == system_user_email()` so
|
||||
comparisons are consistent and case-insensitive everywhere.
|
||||
|
||||
## Returns
|
||||
|
||||
- `boolean()` - true if user's email matches system user email (case-insensitive)
|
||||
|
||||
## Examples
|
||||
|
||||
iex> Mv.Helpers.SystemActor.system_user?(user_with_system_email)
|
||||
true
|
||||
iex> Mv.Helpers.SystemActor.system_user?(other_user)
|
||||
false
|
||||
|
||||
"""
|
||||
@spec system_user?(Mv.Accounts.User.t() | map() | nil) :: boolean()
|
||||
def system_user?(%{email: email}) when not is_nil(email) do
|
||||
normalized_email(to_string(email)) == normalized_system_user_email()
|
||||
end
|
||||
|
||||
def system_user?(_), do: false
|
||||
|
||||
@doc """
|
||||
Returns the email address of the system user.
|
||||
|
||||
|
|
@ -191,6 +216,11 @@ defmodule Mv.Helpers.SystemActor do
|
|||
@spec system_user_email() :: String.t()
|
||||
def system_user_email, do: system_user_email_config()
|
||||
|
||||
# Case-insensitive normalized form for comparisons
|
||||
defp normalized_system_user_email, do: normalized_email(system_user_email_config())
|
||||
|
||||
defp normalized_email(email) when is_binary(email), do: String.downcase(email)
|
||||
|
||||
# Returns the system user email from environment variable or default
|
||||
# This allows configuration via SYSTEM_ACTOR_EMAIL env var
|
||||
@spec system_user_email_config() :: String.t()
|
||||
|
|
@ -368,7 +398,7 @@ defmodule Mv.Helpers.SystemActor do
|
|||
upsert_identity: :unique_email,
|
||||
authorize?: false
|
||||
)
|
||||
|> Ash.Changeset.for_update(:update, %{})
|
||||
|> Ash.Changeset.for_update(:update_internal, %{})
|
||||
|> Ash.Changeset.manage_relationship(:role, admin_role, type: :append_and_remove)
|
||||
|> Ash.update!(authorize?: false)
|
||||
|> Ash.load!(:role, domain: Mv.Accounts, authorize?: false)
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ defmodule Mv.Helpers.SystemActorTest do
|
|||
|> Ash.read_one(domain: Mv.Accounts, authorize?: false) do
|
||||
{:ok, user} when not is_nil(user) ->
|
||||
user
|
||||
|> Ash.Changeset.for_update(:update, %{})
|
||||
|> Ash.Changeset.for_update(:update_internal, %{})
|
||||
|> Ash.Changeset.manage_relationship(:role, admin_role, type: :append_and_remove)
|
||||
|> Ash.update!(authorize?: false)
|
||||
|> Ash.load!(:role, domain: Mv.Accounts, authorize?: false)
|
||||
|
|
@ -68,7 +68,7 @@ defmodule Mv.Helpers.SystemActorTest do
|
|||
upsert_identity: :unique_email,
|
||||
authorize?: false
|
||||
)
|
||||
|> Ash.Changeset.for_update(:update, %{})
|
||||
|> Ash.Changeset.for_update(:update_internal, %{})
|
||||
|> Ash.Changeset.manage_relationship(:role, admin_role, type: :append_and_remove)
|
||||
|> Ash.update!(authorize?: false)
|
||||
|> Ash.load!(:role, domain: Mv.Accounts, authorize?: false)
|
||||
|
|
@ -373,9 +373,9 @@ defmodule Mv.Helpers.SystemActorTest do
|
|||
|
||||
system_actor = SystemActor.get_system_actor()
|
||||
|
||||
# Assign wrong role to system user
|
||||
# Assign wrong role to system user (use :update_internal so bootstrap-style update is allowed)
|
||||
system_user
|
||||
|> Ash.Changeset.for_update(:update, %{})
|
||||
|> Ash.Changeset.for_update(:update_internal, %{})
|
||||
|> Ash.Changeset.manage_relationship(:role, read_only_role, type: :append_and_remove)
|
||||
|> Ash.update!(actor: system_actor)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue