2021-01-29 08:47:59 +13:00
|
|
|
defmodule Ash.Test.Changeset.AuthorizerTest do
|
|
|
|
@moduledoc false
|
|
|
|
use ExUnit.Case, async: false
|
|
|
|
|
|
|
|
require Ash.Query
|
|
|
|
|
|
|
|
defmodule Post do
|
|
|
|
use Ash.Resource,
|
|
|
|
data_layer: Ash.DataLayer.Ets,
|
|
|
|
authorizers: [
|
|
|
|
Ash.Test.Authorizer
|
2023-12-28 12:14:29 +13:00
|
|
|
],
|
2024-03-28 09:06:40 +13:00
|
|
|
domain: Ash.Test.Changeset.AuthorizerTest.Domain
|
2021-01-29 08:47:59 +13:00
|
|
|
|
|
|
|
ets do
|
|
|
|
private? true
|
|
|
|
end
|
|
|
|
|
2022-04-04 17:48:37 +12:00
|
|
|
actions do
|
2024-03-28 09:06:40 +13:00
|
|
|
default_accept :*
|
|
|
|
defaults [:read, :destroy, create: :*, update: :*]
|
2023-12-28 04:27:22 +13:00
|
|
|
|
|
|
|
create :title_is_authorization do
|
|
|
|
accept []
|
|
|
|
|
|
|
|
change fn changeset, context ->
|
|
|
|
Ash.Changeset.change_attribute(changeset, :title, context.authorize?)
|
|
|
|
end
|
|
|
|
end
|
2022-04-04 17:48:37 +12:00
|
|
|
end
|
|
|
|
|
2021-01-29 08:47:59 +13:00
|
|
|
attributes do
|
|
|
|
uuid_primary_key :id
|
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
attribute :title, :string, allow_nil?: false, public?: true
|
2021-01-29 08:47:59 +13:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
defmodule Domain do
|
|
|
|
use Ash.Domain, otp_app: :ash
|
2021-01-29 08:47:59 +13:00
|
|
|
|
|
|
|
resources do
|
2024-03-28 09:06:40 +13:00
|
|
|
resource Post
|
2021-01-29 08:47:59 +13:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-07-19 16:48:31 +12:00
|
|
|
describe "authorization options" do
|
|
|
|
setup do
|
|
|
|
on_exit(fn ->
|
2024-03-28 09:06:40 +13:00
|
|
|
Application.delete_env(:ash, Domain)
|
2022-07-19 16:48:31 +12:00
|
|
|
end)
|
|
|
|
end
|
|
|
|
|
2022-07-22 14:23:18 +12:00
|
|
|
test "authorize :always authorizes automatically" do
|
2024-03-28 09:06:40 +13:00
|
|
|
Application.put_env(:ash, Domain,
|
2022-07-19 16:48:31 +12:00
|
|
|
authorization: [
|
2022-07-22 14:23:18 +12:00
|
|
|
authorize: :by_default
|
2022-07-19 16:48:31 +12:00
|
|
|
]
|
|
|
|
)
|
|
|
|
|
|
|
|
start_supervised({Ash.Test.Authorizer, strict_check: :forbidden})
|
|
|
|
|
|
|
|
assert_raise Ash.Error.Forbidden, fn ->
|
|
|
|
Post
|
|
|
|
|> Ash.Changeset.for_create(:create, %{title: "test"})
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.create!()
|
2022-07-19 16:48:31 +12:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-12-28 12:14:29 +13:00
|
|
|
test "authorize :by_default authorizes if actor is set" do
|
2024-03-28 09:06:40 +13:00
|
|
|
Application.put_env(:ash, Domain,
|
2023-12-28 12:14:29 +13:00
|
|
|
authorization: [
|
|
|
|
authorize: :by_default
|
|
|
|
]
|
|
|
|
)
|
2023-12-28 11:48:13 +13:00
|
|
|
|
2023-12-28 12:14:29 +13:00
|
|
|
start_supervised({Ash.Test.Authorizer, strict_check: :authorized})
|
2023-12-28 11:48:13 +13:00
|
|
|
|
2023-12-28 12:14:29 +13:00
|
|
|
post =
|
|
|
|
Post
|
|
|
|
|> Ash.Changeset.for_create(:title_is_authorization, %{}, actor: :an_actor)
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.create!()
|
2023-12-28 11:48:13 +13:00
|
|
|
|
2023-12-28 12:14:29 +13:00
|
|
|
assert post.title == "true"
|
|
|
|
end
|
2023-12-28 04:27:22 +13:00
|
|
|
|
2022-07-19 16:48:31 +12:00
|
|
|
test "require_actor? requires an actor for all requests" do
|
2024-03-28 09:06:40 +13:00
|
|
|
Application.put_env(:ash, Domain,
|
2022-07-19 16:48:31 +12:00
|
|
|
authorization: [
|
|
|
|
require_actor?: true,
|
2022-07-22 14:23:18 +12:00
|
|
|
authorize: :by_default
|
2022-07-19 16:48:31 +12:00
|
|
|
]
|
|
|
|
)
|
|
|
|
|
|
|
|
start_supervised({Ash.Test.Authorizer, strict_check: :forbidden})
|
|
|
|
|
2023-12-16 09:33:10 +13:00
|
|
|
assert_raise Ash.Error.Forbidden, fn ->
|
2022-07-19 16:48:31 +12:00
|
|
|
Post
|
|
|
|
|> Ash.Changeset.for_create(:create, %{title: "test"})
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.create!()
|
2022-07-19 16:48:31 +12:00
|
|
|
end
|
|
|
|
|
|
|
|
assert_raise Ash.Error.Forbidden, fn ->
|
|
|
|
Post
|
|
|
|
|> Ash.Changeset.for_create(:create, %{title: "test"})
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.create!(actor: nil)
|
2022-07-19 16:48:31 +12:00
|
|
|
end
|
|
|
|
|
|
|
|
assert_raise Ash.Error.Forbidden, fn ->
|
|
|
|
Post
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{title: "test"}, actor: nil)
|
|
|
|
|> Ash.create!()
|
2022-07-19 16:48:31 +12:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-01-29 08:47:59 +13:00
|
|
|
describe "strict check can filter results" do
|
|
|
|
test "a simple filter is applied" do
|
|
|
|
start_supervised(
|
|
|
|
{Ash.Test.Authorizer,
|
|
|
|
strict_check: {:filter, [title: "foo"]}, strict_check_context: [:query]}
|
|
|
|
)
|
|
|
|
|
|
|
|
Post
|
|
|
|
|> Ash.Changeset.for_create(:create, %{title: "test"})
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.create!(authorize?: false)
|
2021-01-29 08:47:59 +13:00
|
|
|
|
|
|
|
Post
|
|
|
|
|> Ash.Changeset.for_create(:create, %{title: "foo"})
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.create!(authorize?: false)
|
2021-01-29 08:47:59 +13:00
|
|
|
|
2024-03-28 09:06:40 +13:00
|
|
|
assert [%Post{title: "foo"}] = Ash.read!(Post, authorize?: true)
|
2021-01-29 08:47:59 +13:00
|
|
|
end
|
|
|
|
|
2022-10-06 13:08:36 +13:00
|
|
|
test "a filter cannot be applied to creates" do
|
2021-01-29 08:47:59 +13:00
|
|
|
start_supervised(
|
|
|
|
{Ash.Test.Authorizer,
|
|
|
|
strict_check: {:filter, [title: "foo"]}, strict_check_context: [:query, :changeset]}
|
|
|
|
)
|
|
|
|
|
|
|
|
# Filter always fails on creates
|
|
|
|
assert_raise Ash.Error.Forbidden, fn ->
|
|
|
|
Post
|
2022-08-10 12:25:43 +12:00
|
|
|
|> Ash.Changeset.for_create(:create, %{title: "test"}, authorize?: true)
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.create!()
|
2021-01-29 08:47:59 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
good_post =
|
|
|
|
Post
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{title: "foo"}, authorize?: false)
|
|
|
|
|> Ash.create!()
|
2021-01-29 08:47:59 +13:00
|
|
|
|
|
|
|
bad_post =
|
|
|
|
Post
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.Changeset.for_create(:create, %{title: "test"}, authorize?: false)
|
|
|
|
|> Ash.create!()
|
2021-01-29 08:47:59 +13:00
|
|
|
|
|
|
|
# Filters apply to the base data
|
|
|
|
assert_raise Ash.Error.Forbidden, fn ->
|
|
|
|
bad_post
|
2022-08-10 12:25:43 +12:00
|
|
|
|> Ash.Changeset.for_update(:update, %{title: "next"}, authorize?: true)
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.update!()
|
2021-01-29 08:47:59 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
good_post
|
2022-08-10 12:25:43 +12:00
|
|
|
|> Ash.Changeset.for_update(:update, %{title: "next"}, authorize?: true)
|
2024-03-28 09:06:40 +13:00
|
|
|
|> Ash.update!()
|
2021-01-29 08:47:59 +13:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|