Skip to content

Commit

Permalink
fix(object-authorization): Fix object authorization for interfaces
Browse files Browse the repository at this point in the history
Very similar to jungsoft#26, but for interfaces instead of unions

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
  • Loading branch information
tcitworld committed Mar 24, 2023
1 parent ac0487e commit 369876e
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 1 deletion.
9 changes: 8 additions & 1 deletion lib/middlewares/object_authorization.ex
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ defmodule Rajska.ObjectAuthorization do

# When is a Scalar, Custom or Enum type, authorize.
defp authorize_object(%type{} = object, fields, resolution)
when type in [Scalar, Custom, Type.Enum, Type.Enum.Value, Type.Union] do
when type in [Scalar, Custom, Type.Enum, Type.Enum.Value, Type.Union, Type.Interface] do
put_result(true, fields, resolution, object)
end

Expand Down Expand Up @@ -118,6 +118,13 @@ defmodule Rajska.ObjectAuthorization do
authorize(schema_node, selections ++ tail, resolution)
end

defp find_associations(
[%{schema_node: %Type.Interface{} = schema_node, selections: selections} | tail],
resolution
) do
authorize(schema_node, selections ++ tail, resolution)
end

defp find_associations(
[%{schema_node: schema_node, selections: selections} | tail],
resolution
Expand Down
38 changes: 38 additions & 0 deletions test/middlewares/object_authorization_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,18 @@ defmodule Rajska.ObjectAuthorizationTest do
{:ok, %{name: "bob"}}
end
end

field :interface_query, :interface do
middleware Rajska.QueryAuthorization, [permit: :all, scope: false]
resolve fn _, _ ->
{:ok, %{name: "bob"}}
end
end
end

object :wallet_balance do
meta :authorize, :admin
interfaces([:interface])

field :total, :integer
end
Expand All @@ -80,6 +88,7 @@ defmodule Rajska.ObjectAuthorizationTest do

object :user do
meta :authorize, :all
interfaces([:interface])

field :email, :string
field :name, :string
Expand All @@ -94,6 +103,13 @@ defmodule Rajska.ObjectAuthorizationTest do
%{total: _}, _ -> :wallet_balance
end
end

interface :interface do
resolve_type fn
%{name: _}, _ -> :user
%{total: _}, _ -> :wallet_balance
end
end
end

test "Public query with public object works for everyone" do
Expand Down Expand Up @@ -174,6 +190,13 @@ defmodule Rajska.ObjectAuthorizationTest do
refute Map.has_key?(result, :errors)
end

test "Works for interfaces" do
{:ok, result} = Absinthe.run(interface_query(), __MODULE__.Schema, context: %{current_user: %{role: :admin}})

assert %{data: %{"interfaceQuery" => %{"name" => "bob"}}} = result
refute Map.has_key?(result, :errors)
end

test "Works when using fragments and user has access" do
{:ok, result} = Absinthe.run(fragment_query_user(), __MODULE__.Schema, context: %{current_user: %{role: :user}})

Expand Down Expand Up @@ -266,6 +289,21 @@ defmodule Rajska.ObjectAuthorizationTest do
"""
end

defp interface_query do
"""
{
interfaceQuery {
... on User {
name
}
... on WalletBalance {
total
}
}
}
"""
end

defp fragment_query_user do
"""
fragment userFields on User {
Expand Down

0 comments on commit 369876e

Please sign in to comment.