mirror of
https://github.com/ash-project/ash.git
synced 2024-09-19 13:03:02 +12:00
chore: make the new policy behavior opt-in with config
This commit is contained in:
parent
82230f1a89
commit
06cd509e1f
7 changed files with 46 additions and 13 deletions
|
@ -29,6 +29,8 @@ if Mix.env() == :test do
|
|||
Ash.Test.Support.PolicySimple.Domain
|
||||
]
|
||||
|
||||
config :ash, :policy, forbid_static_forbidden_reads?: false
|
||||
|
||||
config :ash, :custom_expressions, [Ash.Test.Expressions.JaroDistance]
|
||||
|
||||
config :ash, :sat_testing, true
|
||||
|
|
|
@ -256,6 +256,9 @@ config :helpdesk, :ash_domains, [Helpdesk.Support]
|
|||
config :ash,
|
||||
include_embedded_source_by_default?: false,
|
||||
default_page_type: :keyset
|
||||
|
||||
config :ash, :policies,
|
||||
forbid_static_forbidden_reads?: false
|
||||
```
|
||||
|
||||
### Try our first resource out
|
||||
|
|
|
@ -36,8 +36,14 @@ defmodule Ash.Can do
|
|||
opts = Keyword.put_new(opts, :run_queries?, true)
|
||||
opts = Keyword.put_new(opts, :filter_with, :filter)
|
||||
|
||||
{resource, action_or_query_or_changeset, input} =
|
||||
resource_subject_input(action_or_query_or_changeset, domain, actor, opts)
|
||||
{resource, action_or_query_or_changeset, input, opts} =
|
||||
case resource_subject_input(action_or_query_or_changeset, domain, actor, opts) do
|
||||
{resource, action_or_query_or_changeset, input, new_opts} ->
|
||||
{resource, action_or_query_or_changeset, input, Keyword.merge(new_opts, opts)}
|
||||
|
||||
{resource, action_or_query_or_changeset, input} ->
|
||||
{resource, action_or_query_or_changeset, input, opts}
|
||||
end
|
||||
|
||||
subject =
|
||||
case action_or_query_or_changeset do
|
||||
|
@ -182,8 +188,7 @@ defmodule Ash.Can do
|
|||
domain: domain,
|
||||
tenant: opts[:tenant],
|
||||
actor: actor
|
||||
)
|
||||
|> filter_by_pkey(record), input}
|
||||
), input, data: [record]}
|
||||
|
||||
{%resource{}, %Ash.Resource.Actions.Action{} = action, input} ->
|
||||
{resource,
|
||||
|
@ -253,13 +258,6 @@ defmodule Ash.Can do
|
|||
end
|
||||
end
|
||||
|
||||
defp filter_by_pkey(query, %resource{} = record) do
|
||||
Ash.Query.do_filter(
|
||||
query,
|
||||
record |> Map.take(Ash.Resource.Info.primary_key(resource)) |> Map.to_list()
|
||||
)
|
||||
end
|
||||
|
||||
defp alter_source({:ok, true, query}, domain, actor, %Ash.Changeset{} = subject, opts) do
|
||||
case alter_source({:ok, true}, domain, actor, subject, Keyword.put(opts, :base_query, query)) do
|
||||
{:ok, true, new_subject} -> {:ok, true, new_subject, query}
|
||||
|
|
|
@ -1557,7 +1557,14 @@ defmodule Ash.Policy.Authorizer do
|
|||
end
|
||||
|
||||
defp forbidden_due_to_strict_policy?(authorizer) do
|
||||
if authorizer.for_fields || authorizer.action.type != :read do
|
||||
forbid_static_forbidden_reads? =
|
||||
Keyword.get(
|
||||
Application.get_env(:ash, :policy, []),
|
||||
:forbid_static_forbidden_reads?,
|
||||
true
|
||||
)
|
||||
|
||||
if forbid_static_forbidden_reads? || authorizer.for_fields || authorizer.action.type != :read do
|
||||
true
|
||||
else
|
||||
authorizer.policies
|
||||
|
|
|
@ -83,7 +83,15 @@ defmodule Ash.Policy.FilterCheck do
|
|||
|> filter(authorizer, opts)
|
||||
|> Ash.Expr.fill_template(actor, Ash.Policy.FilterCheck.args(authorizer), context)
|
||||
|> then(fn expr ->
|
||||
if authorizer.for_fields || authorizer.action.type != :read ||
|
||||
forbid_static_forbidden_reads? =
|
||||
Keyword.get(
|
||||
Application.get_env(:ash, :policy, []),
|
||||
:forbid_static_forbidden_reads?,
|
||||
true
|
||||
)
|
||||
|
||||
if forbid_static_forbidden_reads? || authorizer.for_fields ||
|
||||
authorizer.action.type != :read ||
|
||||
context[:private][:pre_flight_authorization?] do
|
||||
try_eval(expr, authorizer)
|
||||
else
|
||||
|
|
|
@ -65,6 +65,12 @@ defmodule Mix.Tasks.Ash.Install do
|
|||
[:default_page_type],
|
||||
:keyset
|
||||
)
|
||||
|> Igniter.Project.Config.configure(
|
||||
"config.exs",
|
||||
:ash,
|
||||
[:policies, :forbid_static_forbidden_reads?],
|
||||
false
|
||||
)
|
||||
|> then(fn igniter ->
|
||||
if "--example" in argv do
|
||||
generate_example(igniter, argv)
|
||||
|
|
|
@ -134,6 +134,15 @@ defmodule Ash.Test.Policy.SimpleTest do
|
|||
assert [] = Ash.read!(Tweet, actor: user)
|
||||
end
|
||||
|
||||
test "Ash.can? accepts a record to determine if it can be read", %{admin: admin, user: user} do
|
||||
tweet = Ash.create!(Ash.Changeset.for_create(Tweet, :create), authorize?: false)
|
||||
|
||||
Logger.configure(level: :debug)
|
||||
|
||||
assert Ash.can?({tweet, :read}, admin)
|
||||
refute Ash.can?({tweet, :read}, user)
|
||||
end
|
||||
|
||||
test "arguments can be referenced in expression policies", %{admin: admin, user: user} do
|
||||
Tweet
|
||||
|> Ash.Changeset.for_create(:create_foo, %{foo: "foo", user_id: admin.id}, actor: user)
|
||||
|
|
Loading…
Reference in a new issue