2023-09-28 05:58:25 +13:00
|
|
|
defmodule Ash.Test.Policy.FieldPolicy.ExpressionConditionTest do
|
|
|
|
use ExUnit.Case, async: true
|
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
alias Ash.Test.Domain, as: Domain
|
2023-09-28 05:58:25 +13:00
|
|
|
|
|
|
|
defmodule ResourceWithMultiplePoliciesForOneField do
|
|
|
|
use Ash.Resource,
|
2024-03-28 09:06:40 +13:00
|
|
|
domain: Domain,
|
2023-09-28 05:58:25 +13:00
|
|
|
data_layer: Ash.DataLayer.Ets,
|
|
|
|
authorizers: [Ash.Policy.Authorizer]
|
|
|
|
|
|
|
|
attributes do
|
|
|
|
uuid_primary_key :id
|
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
attribute :name, :string do
|
|
|
|
public?(true)
|
|
|
|
end
|
|
|
|
|
|
|
|
attribute :other_name, :string do
|
|
|
|
public?(true)
|
|
|
|
end
|
|
|
|
|
|
|
|
attribute :other_other_name, :string do
|
|
|
|
public?(true)
|
|
|
|
end
|
2023-09-28 05:58:25 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
field_policies do
|
|
|
|
field_policy :name, [actor_attribute_equals(:admin, true)] do
|
|
|
|
authorize_if always()
|
|
|
|
end
|
|
|
|
|
|
|
|
field_policy :name, expr(name == ^actor(:name)) do
|
|
|
|
authorize_if always()
|
|
|
|
end
|
|
|
|
|
2023-09-28 07:40:40 +13:00
|
|
|
field_policy :other_name, [actor_attribute_equals(:admin, true)] do
|
|
|
|
forbid_if always()
|
2023-09-28 05:58:25 +13:00
|
|
|
end
|
|
|
|
|
2023-09-28 07:40:40 +13:00
|
|
|
field_policy :other_name, expr(name == ^actor(:name)) do
|
|
|
|
forbid_if always()
|
|
|
|
end
|
2023-09-28 05:58:25 +13:00
|
|
|
|
2023-09-28 07:40:40 +13:00
|
|
|
field_policy :other_other_name, [actor_attribute_equals(:admin, true)] do
|
2023-09-28 05:58:25 +13:00
|
|
|
authorize_if always()
|
|
|
|
end
|
|
|
|
|
2023-09-28 07:40:40 +13:00
|
|
|
field_policy :other_other_name, expr(name == ^actor(:name)) do
|
|
|
|
forbid_if always()
|
2023-09-28 05:58:25 +13:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
policies do
|
|
|
|
policy always() do
|
2023-09-28 07:40:40 +13:00
|
|
|
forbid_if never()
|
2023-09-28 05:58:25 +13:00
|
|
|
authorize_if always()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
code_interface do
|
|
|
|
define :create
|
|
|
|
define :read
|
|
|
|
end
|
|
|
|
|
|
|
|
actions do
|
2024-03-28 09:06:40 +13:00
|
|
|
default_accept :*
|
|
|
|
defaults [:read, create: :*]
|
2023-09-28 05:58:25 +13:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-09-28 07:40:40 +13:00
|
|
|
test "multiple field policies for the same field with different conditions work" do
|
|
|
|
ResourceWithMultiplePoliciesForOneField.create!(%{
|
|
|
|
name: "foo",
|
|
|
|
other_name: "foo",
|
|
|
|
other_other_name: "foo"
|
|
|
|
})
|
|
|
|
|
|
|
|
ResourceWithMultiplePoliciesForOneField.create!(%{
|
|
|
|
name: "baz",
|
|
|
|
other_name: "baz",
|
|
|
|
other_other_name: "bar"
|
|
|
|
})
|
2023-09-28 05:58:25 +13:00
|
|
|
|
|
|
|
assert [
|
2023-09-28 07:40:40 +13:00
|
|
|
%{
|
|
|
|
name: "baz",
|
|
|
|
other_name: %Ash.ForbiddenField{},
|
|
|
|
other_other_name: %Ash.ForbiddenField{}
|
|
|
|
},
|
|
|
|
%{name: "foo", other_name: %Ash.ForbiddenField{}, other_other_name: "foo"}
|
2023-09-28 05:58:25 +13:00
|
|
|
] =
|
2023-09-28 07:40:40 +13:00
|
|
|
ResourceWithMultiplePoliciesForOneField.read!(
|
2023-09-28 05:58:25 +13:00
|
|
|
actor: %{name: "baz", admin: true},
|
2023-09-28 07:40:40 +13:00
|
|
|
query: ResourceWithMultiplePoliciesForOneField |> Ash.Query.sort([:name])
|
2023-09-28 05:58:25 +13:00
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|