mirror of
https://github.com/ash-project/ash.git
synced 2024-09-20 13:33:20 +12:00
fix: run before_action after authorization
This commit is contained in:
parent
bfdf917908
commit
93d4f1fd26
2 changed files with 32 additions and 21 deletions
|
@ -336,8 +336,6 @@ defmodule Ash.Actions.Read do
|
||||||
%{valid?: true} = query <-
|
%{valid?: true} = query <-
|
||||||
handle_attribute_multitenancy(query),
|
handle_attribute_multitenancy(query),
|
||||||
:ok <- validate_multitenancy(query),
|
:ok <- validate_multitenancy(query),
|
||||||
{%{valid?: true} = query, before_notifications} <-
|
|
||||||
run_before_action(query),
|
|
||||||
{:ok, initial_query, query, page_opts} <-
|
{:ok, initial_query, query, page_opts} <-
|
||||||
paginate(query, action, page: request_opts[:page]),
|
paginate(query, action, page: request_opts[:page]),
|
||||||
page_opts <- page_opts && Keyword.delete(page_opts, :filter),
|
page_opts <- page_opts && Keyword.delete(page_opts, :filter),
|
||||||
|
@ -362,7 +360,7 @@ defmodule Ash.Actions.Read do
|
||||||
query_opts: query_opts
|
query_opts: query_opts
|
||||||
}),
|
}),
|
||||||
%{
|
%{
|
||||||
notifications: before_notifications
|
notifications: []
|
||||||
}}
|
}}
|
||||||
else
|
else
|
||||||
%{valid?: false} = query ->
|
%{valid?: false} = query ->
|
||||||
|
@ -378,6 +376,19 @@ defmodule Ash.Actions.Read do
|
||||||
end
|
end
|
||||||
),
|
),
|
||||||
authorize?: !Keyword.has_key?(request_opts, :initial_data),
|
authorize?: !Keyword.has_key?(request_opts, :initial_data),
|
||||||
|
intermediate_data:
|
||||||
|
Request.resolve([path ++ [:fetch, :query]], fn data ->
|
||||||
|
data
|
||||||
|
|> get_in(path ++ [:fetch, :query])
|
||||||
|
|> run_before_action()
|
||||||
|
|> case do
|
||||||
|
{%{valid?: true} = query, before_notifications} ->
|
||||||
|
{:ok, query, %{notifications: before_notifications}}
|
||||||
|
|
||||||
|
{%{errors: errors}, _} ->
|
||||||
|
{:error, errors}
|
||||||
|
end
|
||||||
|
end),
|
||||||
data: data_field(request_opts, path, error_path),
|
data: data_field(request_opts, path, error_path),
|
||||||
path: path ++ [:fetch],
|
path: path ++ [:fetch],
|
||||||
async?: !Keyword.has_key?(request_opts, :initial_data),
|
async?: !Keyword.has_key?(request_opts, :initial_data),
|
||||||
|
@ -1000,9 +1011,9 @@ defmodule Ash.Actions.Read do
|
||||||
|
|
||||||
defp data_field(request_opts, path, error_path) do
|
defp data_field(request_opts, path, error_path) do
|
||||||
Request.resolve(
|
Request.resolve(
|
||||||
[path ++ [:fetch, :query]],
|
[path ++ [:fetch, :query], path ++ [:fetch, :intermediate_data]],
|
||||||
fn data ->
|
fn data ->
|
||||||
ash_query = get_in(data, path ++ [:fetch, :query])
|
ash_query = get_in(data, path ++ [:fetch, :intermediate_data])
|
||||||
# We don't care if this specific request is authorizing
|
# We don't care if this specific request is authorizing
|
||||||
# or the actor of this request, we care if the whole operation
|
# or the actor of this request, we care if the whole operation
|
||||||
actor = request_opts[:actor]
|
actor = request_opts[:actor]
|
||||||
|
@ -1228,20 +1239,6 @@ defmodule Ash.Actions.Read do
|
||||||
}}
|
}}
|
||||||
|
|
||||||
true ->
|
true ->
|
||||||
query =
|
|
||||||
initial_query
|
|
||||||
|> Ash.Query.unset([
|
|
||||||
:filter,
|
|
||||||
:aggregates,
|
|
||||||
:sort,
|
|
||||||
:limit,
|
|
||||||
:offset,
|
|
||||||
:distinct,
|
|
||||||
:select
|
|
||||||
])
|
|
||||||
|> Ash.Query.set_context(%{action: ash_query.action})
|
|
||||||
|> Ash.Query.data_layer_query(only_validate_filter?: true)
|
|
||||||
|
|
||||||
ash_query =
|
ash_query =
|
||||||
if ash_query.select || calculations_at_runtime == [] do
|
if ash_query.select || calculations_at_runtime == [] do
|
||||||
ash_query
|
ash_query
|
||||||
|
@ -1263,8 +1260,20 @@ defmodule Ash.Actions.Read do
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
with %{valid?: true} <- ash_query,
|
with {:ok, query} <-
|
||||||
{:ok, query} <- query,
|
initial_query
|
||||||
|
|> Ash.Query.unset([
|
||||||
|
:filter,
|
||||||
|
:aggregates,
|
||||||
|
:sort,
|
||||||
|
:limit,
|
||||||
|
:offset,
|
||||||
|
:distinct,
|
||||||
|
:select
|
||||||
|
])
|
||||||
|
|> Map.put(:context, ash_query.context)
|
||||||
|
|> Ash.Query.set_context(%{action: ash_query.action})
|
||||||
|
|> Ash.Query.data_layer_query(only_validate_filter?: true),
|
||||||
{:ok, filter} <-
|
{:ok, filter} <-
|
||||||
filter_with_related(
|
filter_with_related(
|
||||||
Enum.map(filter_requests, & &1.path),
|
Enum.map(filter_requests, & &1.path),
|
||||||
|
|
|
@ -16,6 +16,7 @@ defmodule Ash.Engine.Request do
|
||||||
:name,
|
:name,
|
||||||
:api,
|
:api,
|
||||||
:query,
|
:query,
|
||||||
|
:intermediate_data,
|
||||||
:data_layer_query,
|
:data_layer_query,
|
||||||
:authorization_filter,
|
:authorization_filter,
|
||||||
:write_to_data?,
|
:write_to_data?,
|
||||||
|
@ -177,6 +178,7 @@ defmodule Ash.Engine.Request do
|
||||||
action_type: opts[:action_type] || (opts[:action] && opts[:action].type),
|
action_type: opts[:action_type] || (opts[:action] && opts[:action].type),
|
||||||
action: opts[:action],
|
action: opts[:action],
|
||||||
async?: Keyword.get(opts, :async?, true),
|
async?: Keyword.get(opts, :async?, true),
|
||||||
|
intermediate_data: opts[:intermediate_data],
|
||||||
data: data,
|
data: data,
|
||||||
query: query,
|
query: query,
|
||||||
error_path: opts[:error_path],
|
error_path: opts[:error_path],
|
||||||
|
|
Loading…
Reference in a new issue