Skip to content

Commit

Permalink
Fix QueryScope authoritation rule example
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrielpra1 committed Dec 23, 2019
1 parent 7c97852 commit 3953210
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 39 deletions.
54 changes: 45 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,39 @@ Ensures Absinthe's queries can only be accessed by determined users.
resolve &AccountsResolver.create_user/2
end

field :update_user, :user do
arg :id, non_null(:integer)
arg :params, non_null(:user_params)

middleware Rajska.QueryAuthorization, [permit: [:user, :manager], scope: false]
resolve &AccountsResolver.update_user/2
end

field :invite_user, :user do
arg :email, non_null(:string)

middleware Rajska.QueryAuthorization, permit: :admin
resolve &AccountsResolver.invite_user/2
end
end
```

Query authorization will call [role_authorized?/2](https://hexdocs.pm/rajska/Rajska.Authorization.html#c:role_authorized?/2) to check if the [user](https://hexdocs.pm/rajska/Rajska.Authorization.html#c:get_current_user/1) [role](https://hexdocs.pm/rajska/Rajska.Authorization.html#c:get_user_role/1) is authorized to perform the query.

### Query Scope Authorization

Provides scoping to Absinthe's queries, allowing for more complex authorization rules. It is used together with [Query Authorization](#query-authorization).

```elixir
mutation do
field :create_user, :user do
arg :params, non_null(:user_params)

# all does not require scoping, since it means anyone can execute this query, even without being logged in.
middleware Rajska.QueryAuthorization, permit: :all
resolve &AccountsResolver.create_user/2
end

field :update_user, :user do
arg :id, non_null(:integer)
arg :params, non_null(:user_params)
Expand All @@ -116,21 +149,24 @@ Ensures Absinthe's queries can only be accessed by determined users.
resolve &AccountsResolver.delete_user/2
end

field :invite_user, :user do
arg :email, non_null(:string)
input_object :user_params do
field :id, non_null(:integer)
end

middleware Rajska.QueryAuthorization, [permit: :admin, rule: :invitation]
field :accept_user, :user do
arg :params, non_null(:user_params)

middleware Rajska.QueryAuthorization, [
permit: :user,
scope: User,
args: %{id: [:params, :id]},
rule: :accept_user
]
resolve &AccountsResolver.invite_user/2
end
end
```

Query authorization will call [role_authorized?/2](https://hexdocs.pm/rajska/Rajska.Authorization.html#c:role_authorized?/2) to check if the [user](https://hexdocs.pm/rajska/Rajska.Authorization.html#c:get_current_user/1) [role](https://hexdocs.pm/rajska/Rajska.Authorization.html#c:get_user_role/1) is authorized to perform the query.

### Query Scope Authorization

Provides scoping to Absinthe's queries, as seen above in [Query Authorization](#query-authorization).

In the above example, `:all` and `:admin` (`super_role`) permissions don't require the `:scope` keyword, but you can modify this behavior by overriding the [not_scoped_roles/0](https://hexdocs.pm/rajska/Rajska.Authorization.html#c:not_scoped_roles/0) function.

There are also extra options for this middleware, supporting the definition of custom rules, access of nested parameters and allowing optional parameters. All possibilities are listed below:
Expand Down
70 changes: 40 additions & 30 deletions lib/middlewares/query_scope_authorization.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,47 @@ defmodule Rajska.QueryScopeAuthorization do
[Create your Authorization module and add it and QueryAuthorization to your Absinthe.Schema](https://hexdocs.pm/rajska/Rajska.html#module-usage). Since Scope Authorization middleware must be used with Query Authorization, it is automatically called when adding the former. Then set the scoped module and argument field:
```elixir
mutation do
field :create_user, :user do
arg :params, non_null(:user_params)
middleware Rajska.QueryAuthorization, permit: :all
resolve &AccountsResolver.create_user/2
end
field :update_user, :user do
arg :id, non_null(:integer)
arg :params, non_null(:user_params)
middleware Rajska.QueryAuthorization, [permit: :user, scope: User] # same as [permit: :user, scope: User, args: :id]
resolve &AccountsResolver.update_user/2
mutation do
field :create_user, :user do
arg :params, non_null(:user_params)
# all does not require scoping, since it means anyone can execute this query, even without being logged in.
middleware Rajska.QueryAuthorization, permit: :all
resolve &AccountsResolver.create_user/2
end
field :update_user, :user do
arg :id, non_null(:integer)
arg :params, non_null(:user_params)
middleware Rajska.QueryAuthorization, [permit: :user, scope: User] # same as [permit: :user, scope: User, args: :id]
resolve &AccountsResolver.update_user/2
end
field :delete_user, :user do
arg :user_id, non_null(:integer)
# Providing a map for args is useful to map query argument to struct field.
middleware Rajska.QueryAuthorization, [permit: [:user, :manager], scope: User, args: %{id: :user_id}]
resolve &AccountsResolver.delete_user/2
end
input_object :user_params do
field :id, non_null(:integer)
end
field :accept_user, :user do
arg :params, non_null(:user_params)
middleware Rajska.QueryAuthorization, [
permit: :user,
scope: User,
args: %{id: [:params, :id]},
rule: :accept_user
]
resolve &AccountsResolver.invite_user/2
end
end
field :delete_user, :user do
arg :user_id, non_null(:integer)
# Providing a map for args is useful to map query argument to struct field.
middleware Rajska.QueryAuthorization, [permit: [:user, :manager], scope: User, args: %{id: :user_id}]
resolve &AccountsResolver.delete_user/2
end
field :invite_user, :user do
arg :email, non_null(:string)
middleware Rajska.QueryAuthorization, [permit: :admin, rule: :invitation]
resolve &AccountsResolver.invite_user/2
end
end
```
In the above example, `:all` and `:admin` permissions don't require the `:scope` keyword, as defined in the `c:Rajska.Authorization.not_scoped_roles/0` function, but you can modify this behavior by overriding it.
Expand Down

0 comments on commit 3953210

Please sign in to comment.