improvement: add dynamic allow list

improvement: uniqify list_references
This commit is contained in:
Zach Daniel 2022-04-07 22:33:48 -04:00
parent 5bf8c39975
commit c98910add6
6 changed files with 35 additions and 5 deletions

View file

@ -3,6 +3,7 @@
locals_without_parens = [
accept: 1,
action: 1,
allow: 1,
allow_async?: 1,
allow_nil?: 1,
allow_nil_input: 1,

View file

@ -549,11 +549,25 @@ defmodule Ash.Api do
|> Enum.find(&(&1 == resource))
end
|> case do
nil -> {:error, NoSuchResource.exception(resource: resource)}
resource -> {:ok, resource}
nil ->
if allowed?(allow(api), resource) do
{:ok, resource}
else
{:error, NoSuchResource.exception(resource: resource)}
end
resource ->
{:ok, resource}
end
end
@spec allowed?(mfa | nil, module()) :: boolean
defp allowed?({m, f, a}, resource) do
apply(m, f, List.wrap(a) ++ [resource])
end
defp allowed?(_, _), do: false
@spec resources(Ash.Api.t()) :: list(Ash.Resource.t())
def resources(api) do
api
@ -577,7 +591,12 @@ defmodule Ash.Api do
Extension.get_opt(api, [:resources], :registry, nil, true)
end
@spec timeout(atom) :: :timeout | integer()
@spec allow(atom) :: mfa() | nil
def allow(api) do
Extension.get_opt(api, [:resources], :allow, nil, true)
end
@spec timeout(atom) :: nil | :infinity | integer()
def timeout(api) do
Extension.get_opt(api, [:execution], :timeout, 30_000, true)
end

View file

@ -31,12 +31,16 @@ defmodule Ash.Api.Dsl do
"""
],
schema: [
allow: [
type: :mfa,
doc: """
Support a dynamic resource list by providing a callback that checks wether or not the resource should be allowed.
"""
],
allow_unregistered?: [
type: :boolean,
default: false,
doc: """
This is still experimental, but will be supported if you run into any issues.
By default, an api will only work with resources that are explicitly included in the provided registry. In order to separate your
application into multiple domains, you may wish to "mix and match" your resources across contexts. Specifying this option allows you
to refer to resources in different apis in your resources, and allows providing any resource to api actions (to facilitate that requirement).

View file

@ -54,6 +54,10 @@ defmodule Ash.EmbeddableType do
resources do
allow_unregistered? true
end
execution do
timeout :infinity
end
end
@doc false

View file

@ -791,6 +791,7 @@ defmodule Ash.Filter do
else
Enum.map(refs, & &1.attribute)
end
|> Enum.uniq()
end
def put_at_path(value, []), do: value

View file

@ -129,6 +129,7 @@ defmodule Ash.Query.Aggregate do
|> Enum.map(fn {key, value} ->
{key, Enum.uniq_by(Enum.map(value, &elem(&1, 1)), & &1.name)}
end)
|> Enum.uniq()
|> Enum.reduce({[], [], []}, fn {{aggregate_resource, relationship_path, ref_path},
aggregates},
{auth_requests, value_requests, aggregates_in_query} ->