improvement: allow policy conditions to be applied inside their block

```elixir
policy do
  condition [...]
  authorize_if ...
end
```
This commit is contained in:
Zach Daniel 2024-07-22 07:10:09 -04:00
parent 3c2f51224a
commit 34d6f229c5
4 changed files with 17 additions and 5 deletions

View file

@ -178,7 +178,7 @@ defmodule Ash.Policy.Authorizer do
""" """
] ]
], ],
args: [:condition], args: [{:optional, :condition}],
target: Ash.Policy.Policy, target: Ash.Policy.Policy,
no_depend_modules: [:condition], no_depend_modules: [:condition],
transform: {Ash.Policy.Policy, :transform, []}, transform: {Ash.Policy.Policy, :transform, []},
@ -274,7 +274,7 @@ defmodule Ash.Policy.Authorizer do
"A check or list of checks that must be true in order for this field policy to apply. If not specified, it always applies." "A check or list of checks that must be true in order for this field policy to apply. If not specified, it always applies."
] ]
], ],
args: [:fields, {:optional, :condition, {Ash.Policy.Check.Static, result: true}}], args: [:fields, {:optional, :condition}],
target: Ash.Policy.FieldPolicy, target: Ash.Policy.FieldPolicy,
transform: {Ash.Policy.FieldPolicy, :transform, []}, transform: {Ash.Policy.FieldPolicy, :transform, []},
entities: [ entities: [

View file

@ -16,11 +16,18 @@ defmodule Ash.Policy.FieldPolicy do
if Enum.empty?(field_policy.policies) do if Enum.empty?(field_policy.policies) do
{:error, "Field policies must have at least one check."} {:error, "Field policies must have at least one check."}
else else
field_policy =
if field_policy.condition in [nil, []] do
%{field_policy | condition: [{Ash.Policy.Check.Static, result: true}]}
else
field_policy
end
{:ok, {:ok,
%{ %{
field_policy field_policy
| policies: Enum.map(field_policy.policies, &set_field_policy_opt/1), | policies: Enum.map(field_policy.policies, &set_field_policy_opt/1),
condition: Enum.map(List.wrap(field_policy.condition || []), &set_field_policy_opt/1) condition: Enum.map(List.wrap(field_policy.condition), &set_field_policy_opt/1)
}} }}
end end
end end

View file

@ -54,10 +54,14 @@ defmodule Ash.Policy.Policy do
def transform(policy) do def transform(policy) do
if Enum.empty?(policy.policies) do if Enum.empty?(policy.policies) do
{:error, "Policies must have at least one check."} {:error, "Policies must have at least one check."}
else
if policy.condition in [nil, []] do
{:ok, %{policy | condition: [{Ash.Policy.Check.Static, result: true}]}}
else else
{:ok, policy} {:ok, policy}
end end
end end
end
defp build_requirements_expression(policies, authorizer) do defp build_requirements_expression(policies, authorizer) do
{at_least_one_policy_expression, authorizer} = {at_least_one_policy_expression, authorizer} =

View file

@ -45,7 +45,8 @@ defmodule Ash.Test.Actions.AggregateTest do
end end
policies do policies do
policy always() do policy do
condition(always())
authorize_if expr(public == true) authorize_if expr(public == true)
end end
end end