Skip to content

Commit 18c91b6

Browse files
Don't require QueryAuthorization to be first
This would break usage in Relay. This can be improved to check if any Resolution middleware, and if those are found, compilation could still be halted like before. This ensures that there are no accidental 'open doors' when middleware isn't added before QueryAuthorization.
1 parent 2e59556 commit 18c91b6

File tree

1 file changed

+59
-42
lines changed

1 file changed

+59
-42
lines changed

lib/schema.ex

Lines changed: 59 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -14,53 +14,56 @@ defmodule Rajska.Schema do
1414
}
1515

1616
@spec add_query_authorization(
17-
[Middleware.spec(), ...],
18-
Field.t(),
19-
module()
20-
) :: [Middleware.spec(), ...]
17+
[Middleware.spec(), ...],
18+
Field.t(),
19+
module()
20+
) :: [Middleware.spec(), ...]
2121
def add_query_authorization(middleware, %{definition: Introspection}, _authorizaton),
2222
do: middleware
23-
def add_query_authorization(
24-
[{{QueryAuthorization, :call}, config} = query_authorization | middleware] = _middleware,
25-
%Field{name: query_name},
26-
authorization
27-
) do
28-
validate_query_auth_config!(config, authorization, query_name)
29-
30-
[query_authorization | middleware]
31-
end
3223

33-
def add_query_authorization(_middleware, %Field{name: name}, _authorization) do
34-
raise "No permission specified for query #{name}"
24+
def add_query_authorization(middleware, %Field{name: query_name}, authorization) do
25+
middleware
26+
|> Enum.find(&match?({{QueryAuthorization, :call}, _config}, &1))
27+
|> case do
28+
{{QueryAuthorization, :call}, config} ->
29+
validate_query_auth_config!(config, authorization, query_name)
30+
31+
nil ->
32+
raise "No permission specified for query #{query_name}"
33+
end
34+
35+
middleware
3536
end
3637

3738
@spec add_object_authorization([Middleware.spec(), ...]) :: [Middleware.spec(), ...]
38-
def add_object_authorization([{{QueryAuthorization, :call}, _} = query_authorization | middleware]) do
39+
def add_object_authorization([
40+
{{QueryAuthorization, :call}, _} = query_authorization | middleware
41+
]) do
3942
[query_authorization, ObjectAuthorization] ++ middleware
4043
end
4144

4245
def add_object_authorization(middleware), do: [ObjectAuthorization | middleware]
4346

4447
@spec add_field_authorization(
45-
[Middleware.spec(), ...],
46-
Field.t(),
47-
Object.t()
48-
) :: [Middleware.spec(), ...]
48+
[Middleware.spec(), ...],
49+
Field.t(),
50+
Object.t()
51+
) :: [Middleware.spec(), ...]
4952
def add_field_authorization(middleware, %Field{identifier: field}, object) do
5053
[{{FieldAuthorization, :call}, object: object, field: field} | middleware]
5154
end
5255

5356
@spec validate_query_auth_config!(
54-
[
55-
permit: atom(),
56-
scope: false | module(),
57-
args: %{} | [] | atom(),
58-
optional: false | true,
59-
rule: atom()
60-
],
61-
module(),
62-
String.t()
63-
) :: :ok | Exception.t()
57+
[
58+
permit: atom(),
59+
scope: false | module(),
60+
args: %{} | [] | atom(),
61+
optional: false | true,
62+
rule: atom()
63+
],
64+
module(),
65+
String.t()
66+
) :: :ok | Exception.t()
6467

6568
def validate_query_auth_config!(config, authorization, query_name) do
6669
permit = Keyword.get(config, :permit)
@@ -77,50 +80,64 @@ defmodule Rajska.Schema do
7780
validate_scope!(scope, permit, authorization)
7881
validate_args!(args)
7982
rescue
80-
e in RuntimeError -> reraise "Query #{query_name} is configured incorrectly, #{e.message}", __STACKTRACE__
83+
e in RuntimeError ->
84+
reraise "Query #{query_name} is configured incorrectly, #{e.message}", __STACKTRACE__
8185
end
8286
end
8387

84-
defp validate_presence!(nil, option), do: raise "#{inspect(option)} option must be present."
88+
defp validate_presence!(nil, option), do: raise("#{inspect(option)} option must be present.")
8589
defp validate_presence!(_value, _option), do: :ok
8690

8791
defp validate_boolean!(value, _option) when is_boolean(value), do: :ok
88-
defp validate_boolean!(_value, option), do: raise "#{inspect(option)} option must be a boolean."
92+
93+
defp validate_boolean!(_value, option),
94+
do: raise("#{inspect(option)} option must be a boolean.")
8995

9096
defp validate_atom!(value, _option) when is_atom(value), do: :ok
91-
defp validate_atom!(_value, option), do: raise "#{inspect(option)} option must be an atom."
97+
defp validate_atom!(_value, option), do: raise("#{inspect(option)} option must be an atom.")
9298

9399
defp validate_scope!(nil, role, authorization) do
94100
unless Enum.member?(authorization.not_scoped_roles(), role),
95-
do: raise ":scope option must be present for role #{inspect(role)}."
101+
do: raise(":scope option must be present for role #{inspect(role)}.")
96102
end
97103

98104
defp validate_scope!(false, _role, _authorization), do: :ok
99105

100106
defp validate_scope!(scope, _role, _authorization) when is_atom(scope) do
101107
struct!(scope)
102108
rescue
103-
UndefinedFunctionError -> reraise ":scope option #{inspect(scope)} is not a struct.", __STACKTRACE__
109+
UndefinedFunctionError ->
110+
reraise ":scope option #{inspect(scope)} is not a struct.", __STACKTRACE__
104111
end
105112

106113
defp validate_args!(args) when is_map(args) do
107114
Enum.each(args, fn
108-
{field, value} when is_atom(field) and is_atom(value) -> :ok
109-
{field, values} when is_atom(field) and is_list(values) -> validate_list_of_atoms!(values)
110-
field_value -> raise "the following args option is invalid: #{inspect(field_value)}. Since the provided args is a map, you should provide an atom key and an atom or list of atoms value."
115+
{field, value} when is_atom(field) and is_atom(value) ->
116+
:ok
117+
118+
{field, values} when is_atom(field) and is_list(values) ->
119+
validate_list_of_atoms!(values)
120+
121+
field_value ->
122+
raise "the following args option is invalid: #{inspect(field_value)}. Since the provided args is a map, you should provide an atom key and an atom or list of atoms value."
111123
end)
112124
end
113125

114126
defp validate_args!(args) when is_list(args), do: validate_list_of_atoms!(args)
115127

116128
defp validate_args!(args) when is_atom(args), do: :ok
117129

118-
defp validate_args!(args), do: raise "the following args option is invalid: #{inspect(args)}"
130+
defp validate_args!(args), do: raise("the following args option is invalid: #{inspect(args)}")
119131

120132
defp validate_list_of_atoms!(args) do
121133
Enum.each(args, fn
122-
arg when is_atom(arg) -> :ok
123-
arg -> raise "the following args option is invalid: #{inspect(args)}. Expected a list of atoms, but found #{inspect(arg)}"
134+
arg when is_atom(arg) ->
135+
:ok
136+
137+
arg ->
138+
raise "the following args option is invalid: #{inspect(args)}. Expected a list of atoms, but found #{
139+
inspect(arg)
140+
}"
124141
end)
125142
end
126143
end

0 commit comments

Comments
 (0)