improvement: verify reserved calc names, support as input

This commit is contained in:
Zach Daniel 2023-06-01 13:24:27 -04:00
parent adb6cefac1
commit bf6797619b
3 changed files with 51 additions and 4 deletions

View file

@ -904,12 +904,36 @@ defmodule Ash.Query do
load_relationship(query, [{field, nested_query}])
resource_calculation = Ash.Resource.Info.calculation(query.resource, field) ->
{name, load} =
cond do
Keyword.keyword?(rest) ->
case Keyword.fetch(rest, :as) do
{:ok, value} ->
{value, nil}
:error ->
{resource_calculation.name, resource_calculation.name}
end
is_map(rest) ->
case Map.fetch(rest, :as) do
{:ok, value} ->
{value, nil}
:error ->
{resource_calculation.name, resource_calculation.name}
end
true ->
{resource_calculation.name, resource_calculation.name}
end
{module, opts} = resource_calculation.calculation
with {:ok, args} <- validate_calculation_arguments(resource_calculation, rest),
{:ok, calculation} <-
Calculation.new(
resource_calculation.name,
name,
module,
opts,
{resource_calculation.type, resource_calculation.constraints},
@ -918,9 +942,9 @@ defmodule Ash.Query do
resource_calculation.load
) do
calculation =
select_and_load_calc(resource_calculation, %{calculation | load: field}, query)
select_and_load_calc(resource_calculation, %{calculation | load: load}, query)
Map.update!(query, :calculations, &Map.put(&1, field, calculation))
Map.update!(query, :calculations, &Map.put(&1, name, calculation))
else
{:error, error} ->
Ash.Query.add_error(query, :load, error)

View file

@ -1331,7 +1331,8 @@ defmodule Ash.Resource.Dsl do
]
@verifiers [
Ash.Resource.Verifiers.ValidateRelationshipAttributesMatch
Ash.Resource.Verifiers.ValidateRelationshipAttributesMatch,
Ash.Resource.Verifiers.VerifyReservedCalculationArguments
]
@moduledoc """

View file

@ -0,0 +1,22 @@
defmodule Ash.Resource.Verifiers.VerifyReservedCalculationArguments do
@moduledoc "Verifies that standard context keys are not used as calculation arguments"
use Spark.Dsl.Verifier
@reserved_calculation_argument_names ~w(actor tenant authorize? tracer as)a
def verify(dsl) do
dsl
|> Ash.Resource.Info.calculations()
|> Enum.each(fn calculation ->
Enum.each(calculation.arguments, fn argument ->
if argument.name in @reserved_calculation_argument_names do
raise Spark.Error.DslError,
module: Spark.Dsl.Verifier.get_persisted(dsl, :module),
message:
"Argument #{argument.name} is reserved and cannot be used in a calculation argument.",
path: [:calculations, calculation.name, :argument, argument.name]
end
end)
end)
end
end