Skip to content

Commit

Permalink
Fix object scope authorization when query returns a list or nil
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrielpra1 committed Aug 10, 2019
1 parent 0364347 commit c7f1da3
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 12 deletions.
21 changes: 11 additions & 10 deletions lib/middlewares/object_scope_authorization.ex
Original file line number Diff line number Diff line change
Expand Up @@ -118,18 +118,19 @@ defmodule Rajska.ObjectScopeAuthorization do
apply_authorization!(resolution, scoped_struct, Map.get(resolution, :value), nested_keys ++ [:id])
end

defp apply_authorization!(resolution, scoped_struct, value, [first_key | remaining_keys]) when length(remaining_keys) > 0 do
case Map.get(value, first_key) do
nested_value when is_map(nested_value) ->
apply_authorization!(resolution, scoped_struct, nested_value, remaining_keys)
defp apply_authorization!(resolution, scoped_struct, values, keys) when is_list(values) do
Enum.all?(values, fn value ->
apply_authorization!(resolution, scoped_struct, value, keys)
end)
end

values when is_list(values) ->
Enum.all?(values, fn value ->
apply_authorization!(resolution, scoped_struct, value, remaining_keys)
end)
defp apply_authorization!(resolution, scoped_struct, nil, _keys) do
Rajska.apply_auth_mod(resolution, :has_resolution_access?, [resolution, scoped_struct, nil])
end

nil -> Rajska.apply_auth_mod(resolution, :has_resolution_access?, [resolution, scoped_struct, nil])
end
defp apply_authorization!(resolution, scoped_struct, value, [first_key | remaining_keys]) when length(remaining_keys) > 0 do
nested_value = Map.get(value, first_key)
apply_authorization!(resolution, scoped_struct, nested_value, remaining_keys)
end

defp apply_authorization!(resolution, scoped_struct, value, [first_key]) do
Expand Down
68 changes: 66 additions & 2 deletions test/middlewares/object_scope_authorization_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,23 @@ defmodule Rajska.ObjectScopeAuthorizationTest do
}}
end
end

field :users_query, list_of(:user) do
middleware Rajska.QueryAuthorization, permit: :all
resolve fn _args, _ ->
{:ok, [
%{id: 1, name: "bob"},
%{id: 2, name: "bob"},
]}
end
end

field :nil_user_query, :user do
middleware Rajska.QueryAuthorization, permit: :all
resolve fn _args, _ ->
{:ok, nil}
end
end
end

object :user do
Expand Down Expand Up @@ -179,7 +196,7 @@ defmodule Rajska.ObjectScopeAuthorizationTest do
] == errors
end

test "Works when returned object is nil" do
test "Works when returned nested object is nil" do
assert {:ok, result} = Absinthe.run(all_query_no_company(2), __MODULE__.Schema, context: %{current_user: %{role: :user, id: 2}})
assert %{data: %{"allQueryNoCompany" => %{}}} = result
refute Map.has_key?(result, :errors)
Expand All @@ -198,7 +215,17 @@ defmodule Rajska.ObjectScopeAuthorizationTest do
] == errors
end

test "Works when returned object is a list" do
test "Works when query returns nil" do
assert {:ok, result} = Absinthe.run(nil_user_query(), __MODULE__.Schema, context: %{current_user: %{role: :user, id: 1}})
assert %{data: %{"nilUserQuery" => nil}} = result
refute Map.has_key?(result, :errors)

{:ok, result} = Absinthe.run(nil_user_query(), __MODULE__.Schema, context: %{current_user: %{role: :admin, id: 2}})
assert %{data: %{"nilUserQuery" => nil}} = result
refute Map.has_key?(result, :errors)
end

test "Works when returned nested object is a list" do
assert {:ok, %{errors: errors}} = Absinthe.run(all_query_companies_list(2), __MODULE__.Schema, context: %{current_user: %{role: :user, id: 2}})
assert [
%{
Expand All @@ -222,6 +249,21 @@ defmodule Rajska.ObjectScopeAuthorizationTest do
] == errors
end

test "Works when query returns a list" do
assert {:ok, %{errors: errors}} = Absinthe.run(users_query(), __MODULE__.Schema, context: %{current_user: %{role: :user, id: 2}})
assert [
%{
locations: [%{column: 0, line: 2}],
message: "Not authorized to access object user",
path: ["usersQuery"]
}
] == errors

{:ok, result} = Absinthe.run(users_query(), __MODULE__.Schema, context: %{current_user: %{role: :admin, id: 2}})
assert %{data: %{"usersQuery" => [_ | _]}} = result
refute Map.has_key?(result, :errors)
end

defp all_query(id) do
"""
{
Expand Down Expand Up @@ -301,4 +343,26 @@ defmodule Rajska.ObjectScopeAuthorizationTest do
}
"""
end

defp users_query do
"""
{
usersQuery {
name
email
}
}
"""
end

defp nil_user_query do
"""
{
nilUserQuery {
name
email
}
}
"""
end
end

0 comments on commit c7f1da3

Please sign in to comment.