improvement: properly mark conditions w/ access_type

fix: handle statically false conditions in filter logic
This commit is contained in:
Zach Daniel 2022-09-22 21:03:33 -04:00
parent ac30194601
commit fbcd745401
5 changed files with 50 additions and 2 deletions

View file

@ -485,6 +485,7 @@ defmodule Ash.Policy.Authorizer do
[[and: filters] | or_filters]
end
end)
|> Enum.filter(& &1)
end
defp maybe_forbid_strict(authorizer) do
@ -523,6 +524,7 @@ defmodule Ash.Policy.Authorizer do
scenarios = remove_clause(authorizer.scenarios, {check_module, check_opts})
new_facts = Map.put(authorizer.facts, {check_module, check_opts}, required_status)
global_filters(%{authorizer | facts: new_facts}, scenarios, [additional_filter | filter])
end
end

View file

@ -250,5 +250,8 @@ defmodule Ash.Policy.Info do
%{check | check_opts: Keyword.update(check_opts, :access_type, default, &(&1 || default))}
end
defp set_access_type({module, opts}, default),
do: {module, Keyword.update(opts, :access_type, default, &(&1 || default))}
defp set_access_type(other, _), do: other
end

View file

@ -3,14 +3,24 @@ defmodule Ash.Test.Policy.SimpleTest do
use ExUnit.Case
require Ash.Query
alias Ash.Test.Support.PolicySimple.{Api, Car, Organization, Post, Trip, User}
alias Ash.Test.Support.PolicySimple.{Api, Car, Organization, Post, Trip, Tweet, User}
setup do
[
user: Api.create!(Ash.Changeset.new(User))
user: Api.create!(Ash.Changeset.new(User)),
admin: Api.create!(Ash.Changeset.new(User, %{admin: true}))
]
end
test "bypass with condition does not apply subsequent filters", %{admin: admin, user: user} do
Api.create!(Ash.Changeset.new(Tweet))
Application.put_env(:ash, :foo, :bar)
assert [_] = Api.read!(Tweet, actor: admin)
assert [] = Api.read!(Tweet, actor: user)
end
test "filter checks work on create/update/destroy actions", %{user: user} do
user2 = Api.create!(Ash.Changeset.new(User))

View file

@ -11,5 +11,6 @@ defmodule Ash.Test.Support.PolicySimple.Registry do
entry(Simple.Car)
entry(Simple.CarUser)
entry(Simple.Trip)
entry(Simple.Tweet)
end
end

View file

@ -0,0 +1,32 @@
defmodule Ash.Test.Support.PolicySimple.Tweet do
@moduledoc false
use Ash.Resource,
data_layer: Ash.DataLayer.Ets,
authorizers: [Ash.Policy.Authorizer]
ets do
private?(true)
end
actions do
defaults [:create, :read, :update, :destroy]
end
attributes do
uuid_primary_key(:id)
end
policies do
bypass expr(^actor(:admin)) do
authorize_if always()
end
policy always() do
authorize_if(expr(user == ^actor(:id)))
end
end
relationships do
belongs_to :user, Ash.Test.Support.PolicySimple.User
end
end