mirror of
https://github.com/ash-project/ash.git
synced 2024-09-21 05:53:06 +12:00
269889c34b
We now only apply related policies to filter statements based on references that are explicitly annotated as inputs. This is the same logic that backs protecting access in filters for field policies.
135 lines
4.2 KiB
Elixir
135 lines
4.2 KiB
Elixir
defmodule Ash.Test.Policy.ComplexTest do
|
|
@doc false
|
|
use ExUnit.Case, async?: false
|
|
require Ash.Query
|
|
|
|
alias Ash.Test.Support.PolicyComplex.{Api, Bio, Comment, Post, User}
|
|
|
|
setup do
|
|
Application.put_env(:ash, :policies, show_policy_breakdowns?: true)
|
|
|
|
on_exit(fn ->
|
|
Application.delete_env(:ash, :policies)
|
|
end)
|
|
|
|
me = User.create!("me", %{email: "me@app.com", bio: "this is my bio"})
|
|
my_friend = User.create!("my friend", %{email: "my_friend@app.com"})
|
|
|
|
a_friend_of_my_friend =
|
|
User.create!("a friend of my friend", %{email: "friends_friend@app.com"})
|
|
|
|
User.add_friend!(me, my_friend.id, actor: me)
|
|
User.add_friend!(my_friend, a_friend_of_my_friend.id, actor: my_friend)
|
|
post_by_me = Post.create!("post by me", actor: me)
|
|
post_by_my_friend = Post.create!("post by my friend", actor: my_friend)
|
|
|
|
post_by_a_friend_of_my_friend =
|
|
Post.create!("post by a friend of my friend", actor: a_friend_of_my_friend)
|
|
|
|
comment_by_me_on_my_post =
|
|
Comment.create!(post_by_me.id, "comment by me on my own post", actor: me)
|
|
|
|
comment_by_my_friend_on_my_post =
|
|
Comment.create!(post_by_me.id, "comment by my friend on my", actor: my_friend)
|
|
|
|
comment_by_a_friend_of_a_friend_on_his_own_post =
|
|
Comment.create!(
|
|
post_by_a_friend_of_my_friend.id,
|
|
"comment by a friend of a friend on his own post",
|
|
actor: a_friend_of_my_friend
|
|
)
|
|
|
|
comment_by_a_friend_of_a_friend_on_my_friends_post =
|
|
Comment.create!(
|
|
post_by_my_friend.id,
|
|
"comment by a friend of a friend on my post",
|
|
actor: a_friend_of_my_friend,
|
|
# bypass auth to make a comment in this state
|
|
authorize?: false
|
|
)
|
|
|
|
[
|
|
me: me,
|
|
my_friend: my_friend,
|
|
post_by_me: post_by_me,
|
|
post_by_my_friend: post_by_my_friend,
|
|
comment_by_me_on_my_post: comment_by_me_on_my_post,
|
|
comment_by_my_friend_on_my_post: comment_by_my_friend_on_my_post,
|
|
comment_by_a_friend_of_a_friend_on_his_own_post:
|
|
comment_by_a_friend_of_a_friend_on_his_own_post,
|
|
comment_by_a_friend_of_a_friend_on_my_friends_post:
|
|
comment_by_a_friend_of_a_friend_on_my_friends_post
|
|
]
|
|
end
|
|
|
|
test "it properly limits on reads", %{me: me} do
|
|
assert [_, _] =
|
|
Post
|
|
|> Api.read!(actor: me)
|
|
end
|
|
|
|
test "it properly limits on reads of comments", %{me: me} do
|
|
assert [_, _] =
|
|
Comment
|
|
|> Api.read!(actor: me)
|
|
end
|
|
|
|
test "it properly scopes filters", %{me: me} do
|
|
User
|
|
|> Ash.Query.filter(posts.exists(author.friends, name == "me"))
|
|
|> Api.read!()
|
|
|
|
assert [_] =
|
|
Post
|
|
|> Ash.Query.filter(comments.text == "comment by a friend of a friend on my post")
|
|
|> Api.read!(actor: me, authorize?: false)
|
|
|
|
assert [] =
|
|
Post
|
|
|> Ash.Query.filter_input(
|
|
comments: [text: "comment by a friend of a friend on my post"]
|
|
)
|
|
|> Api.read!(actor: me)
|
|
end
|
|
|
|
test "it properly scopes single loads" do
|
|
assert [%{best_friend: %{name: "me"}}] =
|
|
User
|
|
|> Ash.Query.filter(best_friend.name == "me")
|
|
|> Api.read!()
|
|
|> Api.load!(:best_friend)
|
|
end
|
|
|
|
test "aggregates can be loaded", %{me: me} do
|
|
Post
|
|
|> Ash.Query.load(:count_of_comments)
|
|
|> Ash.Query.filter(count_of_comments == 10)
|
|
|> Api.read!(actor: me)
|
|
end
|
|
|
|
test "data can be loaded without forbidden errors from selecting", %{me: me} do
|
|
users =
|
|
Ash.Test.Support.PolicyComplex.User
|
|
|> Ash.Query.deselect(:private_email)
|
|
|> Api.read!(actor: me)
|
|
|
|
users
|
|
|> Api.load!([:posts], actor: me, authorize?: true)
|
|
end
|
|
|
|
test "loading data honors `accessing_from` policies", %{me: me} do
|
|
Api.load!(me, [:bio], authorize?: true, actor: me)
|
|
me |> User.set_bio!("New bio!", authorize?: true, actor: me)
|
|
|
|
User
|
|
|> Ash.Query.filter(bio == "New bio!")
|
|
|> Ash.Query.deselect(:private_email)
|
|
|> Api.read_one!(authorize?: true, actor: me)
|
|
|
|
me |> Api.load!([:bio_text], authorize?: true, actor: me)
|
|
|
|
assert_raise Ash.Error.Forbidden, fn ->
|
|
Api.read!(Bio, actor: me, authorize?: true)
|
|
end
|
|
end
|
|
end
|