improvement: retain actor context from changeset

This commit is contained in:
Zach Daniel 2021-03-21 11:31:01 -04:00
parent 4219e11401
commit ab31320e73
4 changed files with 40 additions and 1 deletions

View file

@ -12,6 +12,15 @@ defmodule Ash.Actions.Create do
upsert? = opts[:upsert?] || false
resource = changeset.resource
opts =
case Map.fetch(changeset.context[:private] || %{}, :actor) do
{:ok, actor} ->
Keyword.put_new(opts, :actor, actor)
_ ->
opts
end
authorize? =
if opts[:authorize?] == false do
false

View file

@ -34,6 +34,15 @@ defmodule Ash.Actions.Destroy do
|> Keyword.take([:verbose?, :actor, :authorize?])
|> Keyword.put(:transaction?, true)
opts =
case Map.fetch(changeset.context[:private] || %{}, :actor) do
{:ok, actor} ->
Keyword.put_new(opts, :actor, actor)
_ ->
opts
end
authorization_request =
Request.new(
resource: resource,

View file

@ -18,6 +18,15 @@ defmodule Ash.Actions.Update do
opts = Keyword.put(opts, :authorize?, authorize?)
opts =
case Map.fetch(changeset.context[:private] || %{}, :actor) do
{:ok, actor} ->
Keyword.put_new(opts, :actor, actor)
_ ->
opts
end
engine_opts =
opts
|> Keyword.take([:verbose?, :actor, :authorize?])

View file

@ -288,6 +288,8 @@ defmodule Ash.Changeset do
Constructs a changeset for a given create action, and validates it.
Anything that is modified prior to `for_create/4` is validated against the rules of the action, while *anything after it is not*.
This runs any `change`s contained on your action. To have your logic execute *only* during the action, you can use `after_action/2`
or `before_action/2`.
Multitenancy is *not* validated until an action is called. This allows you to avoid specifying a tenant until just before calling
the api action.
@ -407,6 +409,7 @@ defmodule Ash.Changeset do
if action do
changeset
|> set_actor(opts)
|> set_tenant(opts[:tenant] || changeset.tenant)
|> Map.put(:__validated_for_action__, action.name)
|> Map.put(:action, action)
@ -428,6 +431,7 @@ defmodule Ash.Changeset do
if action do
changeset
|> set_actor(opts)
|> set_tenant(opts[:tenant] || changeset.tenant)
|> Map.put(:action, action)
|> Map.put(:__validated_for_action__, action.name)
@ -448,6 +452,14 @@ defmodule Ash.Changeset do
end
end
defp set_actor(changeset, opts) do
if Keyword.has_key?(opts, :actor) do
put_context(changeset, :private, %{actor: opts[:actor]})
else
changeset
end
end
defp raise_no_action(resource, action, type) do
available_actions =
resource
@ -465,7 +477,7 @@ defmodule Ash.Changeset do
Ash.Changeset.for_#{type}(changeset_or_record, :action_name, input, options)
Available actions:
Available #{type} actions:
#{available_actions}
"""