mirror of
https://github.com/ash-project/ash.git
synced 2024-09-20 05:23:03 +12:00
fix: respect selects in related_query (#464)
This commit is contained in:
parent
e4f30f368e
commit
7689e8e531
4 changed files with 53 additions and 29 deletions
|
@ -510,11 +510,7 @@ defmodule Ash.Actions.Load do
|
|||
name: "load #{source}",
|
||||
api: related_query.api,
|
||||
path: this_request_path,
|
||||
query:
|
||||
load_query(
|
||||
relationship,
|
||||
related_query
|
||||
),
|
||||
query: related_query,
|
||||
data:
|
||||
data(
|
||||
relationship,
|
||||
|
@ -798,11 +794,7 @@ defmodule Ash.Actions.Load do
|
|||
name: "load join #{join_relationship.name}",
|
||||
api: related_query.api,
|
||||
path: request_path ++ [:load, join_relationship_path_names],
|
||||
query:
|
||||
load_query(
|
||||
join_relationship,
|
||||
related_query
|
||||
),
|
||||
query: related_query,
|
||||
data:
|
||||
Request.resolve(dependencies, fn
|
||||
data ->
|
||||
|
@ -1266,25 +1258,6 @@ defmodule Ash.Actions.Load do
|
|||
end
|
||||
end
|
||||
|
||||
defp load_query(%{manual: manual}, related_query)
|
||||
when not is_nil(manual) do
|
||||
related_query
|
||||
end
|
||||
|
||||
defp load_query(
|
||||
relationship,
|
||||
related_query
|
||||
) do
|
||||
if Map.get(relationship, :no_attributes?) do
|
||||
relationship.destination
|
||||
|> Ash.Query.new(related_query.api)
|
||||
else
|
||||
relationship.destination
|
||||
|> Ash.Query.new(related_query.api)
|
||||
|> Ash.Query.filter(^related_query.filter)
|
||||
end
|
||||
end
|
||||
|
||||
defp true_load_query(relationship, query, data, path, request_path) do
|
||||
{source_attribute, path} =
|
||||
if relationship.type == :many_to_many do
|
||||
|
|
|
@ -2,6 +2,8 @@ defmodule Ash.Test.Policy.RbacTest do
|
|||
@doc false
|
||||
use ExUnit.Case
|
||||
|
||||
require Ash.Query
|
||||
|
||||
alias Ash.Test.Support.PolicyRbac.{Api, File, Membership, Organization, User}
|
||||
|
||||
setup do
|
||||
|
@ -34,6 +36,47 @@ defmodule Ash.Test.Policy.RbacTest do
|
|||
assert [%{name: "foo"}] = Api.read!(File, actor: user)
|
||||
end
|
||||
|
||||
test "query params on relation are passed correctly to the policy", %{
|
||||
user: user,
|
||||
org: org
|
||||
} do
|
||||
user = Map.put(user, :rel_check, true)
|
||||
|
||||
file_with_access = create_file(org, "foo")
|
||||
give_role(user, org, :viewer, :file, file_with_access.id)
|
||||
create_file(org, "bar")
|
||||
create_file(org, "baz")
|
||||
|
||||
# select a forbidden field
|
||||
query =
|
||||
Organization
|
||||
|> Ash.Query.filter(id == ^org.id)
|
||||
|> Ash.Query.load(files: File |> Ash.Query.select([:forbidden]))
|
||||
|
||||
assert_raise Ash.Error.Forbidden, fn ->
|
||||
Api.read!(query, actor: user) == []
|
||||
end
|
||||
|
||||
# specify no select (everything is selected)
|
||||
query =
|
||||
Organization
|
||||
|> Ash.Query.filter(id == ^org.id)
|
||||
|> Ash.Query.load([:files])
|
||||
|
||||
assert_raise Ash.Error.Forbidden, fn ->
|
||||
Api.read!(query, actor: user) == []
|
||||
end
|
||||
|
||||
# select only an allowed field
|
||||
query =
|
||||
Organization
|
||||
|> Ash.Query.filter(id == ^org.id)
|
||||
|> Ash.Query.load(files: File |> Ash.Query.select([:id]))
|
||||
|
||||
assert [%Organization{files: [%File{id: id}]}] = Api.read!(query, actor: user)
|
||||
assert id == file_with_access.id
|
||||
end
|
||||
|
||||
test "unauthorized if no policy is defined", %{user: user} do
|
||||
assert_raise Ash.Error.Forbidden, fn ->
|
||||
Api.read!(User, actor: user) == []
|
||||
|
|
|
@ -10,6 +10,11 @@ defmodule Ash.Test.Support.PolicyRbac.File do
|
|||
policy always() do
|
||||
authorize_if(can?(:file))
|
||||
end
|
||||
|
||||
policy actor_attribute_equals(:rel_check, true) do
|
||||
forbid_if selecting(:forbidden)
|
||||
authorize_if always()
|
||||
end
|
||||
end
|
||||
|
||||
ets do
|
||||
|
@ -23,6 +28,7 @@ defmodule Ash.Test.Support.PolicyRbac.File do
|
|||
attributes do
|
||||
uuid_primary_key(:id)
|
||||
attribute(:name, :string)
|
||||
attribute(:forbidden, :string)
|
||||
end
|
||||
|
||||
relationships do
|
||||
|
|
|
@ -19,5 +19,7 @@ defmodule Ash.Test.Support.PolicyRbac.Organization do
|
|||
has_many :memberships, Ash.Test.Support.PolicyRbac.Membership do
|
||||
destination_attribute(:organization_id)
|
||||
end
|
||||
|
||||
has_many :files, Ash.Test.Support.PolicyRbac.File
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue