From 369876eddad9a1cc0305214c0df11fb6c2439410 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Fri, 24 Mar 2023 10:24:09 +0100 Subject: [PATCH] fix(object-authorization): Fix object authorization for interfaces Very similar to https://github.com/jungsoft/rajska/pull/26, but for interfaces instead of unions Signed-off-by: Thomas Citharel --- lib/middlewares/object_authorization.ex | 9 ++++- .../middlewares/object_authorization_test.exs | 38 +++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/lib/middlewares/object_authorization.ex b/lib/middlewares/object_authorization.ex index e159c8f..ac58784 100644 --- a/lib/middlewares/object_authorization.ex +++ b/lib/middlewares/object_authorization.ex @@ -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 @@ -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 diff --git a/test/middlewares/object_authorization_test.exs b/test/middlewares/object_authorization_test.exs index bebf86f..44fc0a1 100644 --- a/test/middlewares/object_authorization_test.exs +++ b/test/middlewares/object_authorization_test.exs @@ -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 @@ -80,6 +88,7 @@ defmodule Rajska.ObjectAuthorizationTest do object :user do meta :authorize, :all + interfaces([:interface]) field :email, :string field :name, :string @@ -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 @@ -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}}) @@ -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 {