docs/graphql.md in action_policy-0.3.2 vs docs/graphql.md in action_policy-0.3.3
- old
+ new
@@ -1,17 +1,17 @@
# GraphQL integration
-You can use Action Policy as an authorization library for you [GraphQL Ruby](https://graphql-ruby.org/) application via the [`action_policy-graphql` gem](https://github.com/palkan/action_policy-graphql).
+You can use Action Policy as an authorization library for your [GraphQL Ruby](https://graphql-ruby.org/) application via the [`action_policy-graphql` gem](https://github.com/palkan/action_policy-graphql).
This integration provides the following features:
- Fields & mutations authorization
- List and connections scoping
-- [**Exposing permissions/authorization rules in the API**](https://dev.to/evilmartians/exposing-permissions-in-graphql-apis-with-action-policy-1mfh).
+- [**Exposing permissions/authorization rules in the API**](https://evilmartians.com/chronicles/exposing-permissions-in-graphql-apis-with-action-policy).
## Getting Started
-First, add `action_policy-graphql` gem to your Gemfile (see [installation instructions](https://github.com/palkan/action_policy-graphql#installation)).
+First, add the `action_policy-graphql` gem to your Gemfile (see [installation instructions](https://github.com/palkan/action_policy-graphql#installation)).
Then, include `ActionPolicy::GraphQL::Behaviour` to your base type (or any other type/mutation where you want to use authorization features):
```ruby
# For fields authorization, lists scoping and rules exposing
@@ -21,15 +21,20 @@
# For using authorization helpers in mutations
class Types::BaseMutation < GraphQL::Schema::Mutation
include ActionPolicy::GraphQL::Behaviour
end
+
+# For using authorization helpers in resolvers
+class Types::BaseResolver < GraphQL::Schema::Resolver
+ include ActionPolicy::GraphQL::Behaviour
+end
```
## Authorization Context
-By default, Action Policy use `context[:current_user]` as the `user` [authorization context](./authoriation_context.md).
+By default, Action Policy uses `context[:current_user]` as the `user` [authorization context](./authorization_context.md).
**NOTE:** see below for more information on what's included into `ActionPolicy::GraphQL::Behaviour`.
## Authorizing Fields
@@ -73,30 +78,63 @@
```ruby
ActionPolicy::GraphQL.default_authorize_rule = :show_graphql_field?
```
+If you want to perform authorization before resolving the field value, you can use `preauthorize: *` option:
+
+```ruby
+field :homes, [Home], null: false, preauthorize: {with: HomePolicy}
+
+def homes
+ Home.all
+end
+```
+
+The code above is equal to:
+
+```ruby
+field :homes, [Home], null: false
+
+def homes
+ authorize! "homes", to: :index?, with: HomePolicy
+ Home.all
+end
+```
+
+**NOTE:** we pass the field's name as the `record` to the policy rule. We assume that preauthorization rules do not depend on
+the record itself and pass the field's name for debugging purposes only.
+
+You can customize the authorization options, e.g. `authorize: {to: :preview?, with: CustomPolicy}`.
+
+**NOTE:** unlike `authorize: *` you MUST specify the `with: SomePolicy` option.
+The default authorization rule depends on the type of the field:
+
+- for lists we use `index?` (configured by `ActionPolicy::GraphQL.default_preauthorize_list_rule` parameter)
+- for _singleton_ fields we use `show?` (configured by `ActionPolicy::GraphQL.default_preauthorize_node_rule` parameter)
+
### Class-level authorization
You can use Action Policy in the class-level [authorization hooks](https://graphql-ruby.org/authorization/authorization.html) (`self.authorized?`) like this:
```ruby
class Types::Friendship < Types::BaseObject
def self.authorized?(object, context)
super &&
- object.allowed_to?(
+ allowed_to?(
:show?,
object,
+ # NOTE: you must provide context explicitly
context: {user: context[:current_user]}
)
end
end
```
## Authorizing Mutations
-Mutation is just a Ruby class with a single API method. There is nothing specific in authorizing mutations: from the Action Policy point of view, they are just [_behaviours_](./behaviour.md).
+A mutation is just a Ruby class with a single API method. There is nothing specific in authorizing mutations: from the Action Policy point of view, they are just [_behaviours_](./behaviour.md).
If you want to authorize the mutation, you call `authorize!` method. For example:
```ruby
class Mutations::DestroyUser < Types::BaseMutation
@@ -164,10 +202,12 @@
authorized_scope object.events, with: CustomEventPolicy
end
end
```
+**NOTE:** you cannot use `authorize: *` and `authorized_scope: *` at the same time but you can combine `preauthorize: *` with `authorized_scope: *`.
+
See the documenation on [scoping](./scoping.md).
## Exposing Authorization Rules
With `action_policy-graphql` gem, you can easily expose your authorization logic to the client in a standardized way.
@@ -217,9 +257,19 @@
You can override a custom authorization field prefix (`can_`):
```ruby
ActionPolicy::GraphQL.default_authorization_field_prefix = "allowed_to_"
+```
+
+You can specify a custom field name as well (only for a single rule):
+
+```ruby
+class ProfileType < ::Common::Graphql::Type
+ # Adds can_create_post field.
+
+ expose_authorization_rules :create?, with: PostPolicy, field_name: "can_create_post"
+end
```
## Custom Behaviour
Including the default `ActionPolicy::GraphQL::Behaviour` is equal to adding the following to your base class: