graphql_devise 0.14.3 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/README.md +111 -46
- data/app/controllers/graphql_devise/concerns/additional_controller_methods.rb +72 -0
- data/app/controllers/graphql_devise/concerns/set_user_by_token.rb +5 -27
- data/app/helpers/graphql_devise/mailer_helper.rb +2 -2
- data/app/models/graphql_devise/concerns/additional_model_methods.rb +21 -0
- data/app/models/graphql_devise/concerns/model.rb +6 -9
- data/lib/generators/graphql_devise/install_generator.rb +1 -1
- data/lib/graphql_devise.rb +20 -6
- data/lib/graphql_devise/concerns/controller_methods.rb +3 -3
- data/lib/graphql_devise/mount_method/operation_preparer.rb +6 -6
- data/lib/graphql_devise/mount_method/operation_preparers/custom_operation_preparer.rb +6 -4
- data/lib/graphql_devise/mount_method/operation_preparers/default_operation_preparer.rb +6 -4
- data/lib/graphql_devise/mount_method/operation_preparers/{resource_name_setter.rb → resource_klass_setter.rb} +4 -4
- data/lib/graphql_devise/resolvers/confirm_account.rb +1 -1
- data/lib/graphql_devise/resource_loader.rb +26 -11
- data/lib/graphql_devise/schema_plugin.rb +14 -6
- data/lib/graphql_devise/version.rb +1 -1
- data/spec/dummy/app/controllers/api/v1/graphql_controller.rb +11 -0
- data/spec/dummy/config/routes.rb +2 -1
- data/spec/generators/graphql_devise/install_generator_spec.rb +1 -1
- data/spec/graphql/user_queries_spec.rb +3 -1
- data/spec/requests/graphql_controller_spec.rb +1 -1
- data/spec/requests/user_controller_spec.rb +20 -0
- data/spec/services/mount_method/operation_preparer_spec.rb +5 -5
- data/spec/services/mount_method/operation_preparers/custom_operation_preparer_spec.rb +5 -5
- data/spec/services/mount_method/operation_preparers/default_operation_preparer_spec.rb +5 -5
- data/spec/services/mount_method/operation_preparers/{resource_name_setter_spec.rb → resource_klass_setter_spec.rb} +6 -6
- data/spec/services/resource_loader_spec.rb +5 -5
- data/spec/support/contexts/graphql_request.rb +2 -2
- metadata +8 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f90be997c50518d79c6b3fdaee2f896aeec557ca5084a6bac7059a518dd8ec3
|
4
|
+
data.tar.gz: e25b07dee790cd64a48a07970974c6ae3e2a567c9a75321f7af69c693140a342
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8453243ec0816b2fc828c13f1033b70e97ae71d68c2938af469a435f99a1b26369f0482a4abcda50fbf61c1a9d1fbde12b47a51f6fa42fdbb29afe5aa7f8760e
|
7
|
+
data.tar.gz: 0fb0ef651e1be37157948ce48e24690ec741e543abf5771ad85f6380a640efb9b772195b16132685887cef9eb8f03d923a12406c99877100c6f13408a70280d8
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v0.15.0](https://github.com/graphql-devise/graphql_devise/tree/v0.15.0) (2021-05-09)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/graphql-devise/graphql_devise/compare/v0.14.3...v0.15.0)
|
6
|
+
|
7
|
+
**Implemented enhancements:**
|
8
|
+
|
9
|
+
- Allow controller level authentication [\#175](https://github.com/graphql-devise/graphql_devise/pull/175) ([mcelicalderon](https://github.com/mcelicalderon))
|
10
|
+
|
11
|
+
**Deprecated:**
|
12
|
+
|
13
|
+
- Deprecate authenticating resources inside the GQL schema [\#176](https://github.com/graphql-devise/graphql_devise/pull/176) ([mcelicalderon](https://github.com/mcelicalderon))
|
14
|
+
|
15
|
+
**Merged pull requests:**
|
16
|
+
|
17
|
+
- Add controller level auth documentation [\#177](https://github.com/graphql-devise/graphql_devise/pull/177) ([mcelicalderon](https://github.com/mcelicalderon))
|
18
|
+
|
3
19
|
## [v0.14.3](https://github.com/graphql-devise/graphql_devise/tree/v0.14.3) (2021-04-28)
|
4
20
|
|
5
21
|
[Full Changelog](https://github.com/graphql-devise/graphql_devise/compare/v0.14.2...v0.14.3)
|
data/README.md
CHANGED
@@ -8,43 +8,44 @@ GraphQL interface on top of the [Devise Token Auth](https://github.com/lynndylan
|
|
8
8
|
## Table of Contents
|
9
9
|
|
10
10
|
<!--ts-->
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
* [
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
* [
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
* [
|
42
|
-
|
43
|
-
* [
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
11
|
+
* [GraphqlDevise](#graphqldevise)
|
12
|
+
* [Table of Contents](#table-of-contents)
|
13
|
+
* [Introduction](#introduction)
|
14
|
+
* [Installation](#installation)
|
15
|
+
* [Running the Generator](#running-the-generator)
|
16
|
+
* [Mounting the Schema in a Separate Route](#mounting-the-schema-in-a-separate-route)
|
17
|
+
* [Important](#important)
|
18
|
+
* [Mounting Operations in Your Own Schema (> v0.12.0)](#mounting-operations-in-your-own-schema--v0120)
|
19
|
+
* [Important](#important-1)
|
20
|
+
* [Usage](#usage)
|
21
|
+
* [Mounting Auth Schema on a Separate Route](#mounting-auth-schema-on-a-separate-route)
|
22
|
+
* [Mounting Operations Into Your Own Schema](#mounting-operations-into-your-own-schema)
|
23
|
+
* [Available Mount Options](#available-mount-options)
|
24
|
+
* [Available Operations](#available-operations)
|
25
|
+
* [Configuring Model](#configuring-model)
|
26
|
+
* [Email Reconfirmation](#email-reconfirmation)
|
27
|
+
* [Customizing Email Templates](#customizing-email-templates)
|
28
|
+
* [I18n](#i18n)
|
29
|
+
* [Authenticating Controller Actions](#authenticating-controller-actions)
|
30
|
+
* [Authenticate Resource in the Controller (>= v0.15.0)](#authenticate-resource-in-the-controller--v0150)
|
31
|
+
* [Authenticate Before Reaching Your GQL Schema (Deprecated)](#authenticate-before-reaching-your-gql-schema-deprecated)
|
32
|
+
* [Authenticate in Your GQL Schema (Deprecated)](#authenticate-in-your-gql-schema-deprecated)
|
33
|
+
* [Important](#important-2)
|
34
|
+
* [Making Requests](#making-requests)
|
35
|
+
* [Introspection query](#introspection-query)
|
36
|
+
* [Mutations](#mutations)
|
37
|
+
* [Queries](#queries)
|
38
|
+
* [Reset Password Flow](#reset-password-flow)
|
39
|
+
* [More Configuration Options](#more-configuration-options)
|
40
|
+
* [Devise Token Auth Initializer](#devise-token-auth-initializer)
|
41
|
+
* [Devise Initializer](#devise-initializer)
|
42
|
+
* [GraphQL Interpreter](#graphql-interpreter)
|
43
|
+
* [Using Alongside Standard Devise](#using-alongside-standard-devise)
|
44
|
+
* [Future Work](#future-work)
|
45
|
+
* [Contributing](#contributing)
|
46
|
+
* [License](#license)
|
47
|
+
|
48
|
+
<!-- Added by: mcelicalderon, at: Sat May 8 12:32:03 -05 2021 -->
|
48
49
|
|
49
50
|
<!--te-->
|
50
51
|
|
@@ -100,7 +101,7 @@ Will do the following:
|
|
100
101
|
- Add `devise` modules to `Admin` model
|
101
102
|
- Other changes that you can find [here](https://devise-token-auth.gitbook.io/devise-token-auth/config)
|
102
103
|
- Add the route to `config/routes.rb`
|
103
|
-
- `mount_graphql_devise_for
|
104
|
+
- `mount_graphql_devise_for Admin, at: 'api/auth'`
|
104
105
|
|
105
106
|
`Admin` could be any model name you are going to be using for authentication,
|
106
107
|
and `api/auth` could be any mount path you would like to use for auth.
|
@@ -149,7 +150,7 @@ You can mount this gem's GraphQL auth schema in your routes file like this:
|
|
149
150
|
|
150
151
|
Rails.application.routes.draw do
|
151
152
|
mount_graphql_devise_for(
|
152
|
-
|
153
|
+
User,
|
153
154
|
at: 'api/v1',
|
154
155
|
authenticatable_type: Types::MyCustomUserType,
|
155
156
|
operations: {
|
@@ -187,7 +188,7 @@ class DummySchema < GraphQL::Schema
|
|
187
188
|
query: Types::QueryType,
|
188
189
|
mutation: Types::MutationType,
|
189
190
|
resource_loaders: [
|
190
|
-
GraphqlDevise::ResourceLoader.new(
|
191
|
+
GraphqlDevise::ResourceLoader.new(User, only: [:login, :confirm_account])
|
191
192
|
]
|
192
193
|
)
|
193
194
|
|
@@ -242,10 +243,10 @@ this gem's auth operation into your schema, these are the options you can provid
|
|
242
243
|
|
243
244
|
```ruby
|
244
245
|
# Using the mount method in your config/routes.rb file
|
245
|
-
mount_graphql_devise_for(
|
246
|
+
mount_graphql_devise_for(User, {})
|
246
247
|
|
247
248
|
# Providing options to a GraphqlDevise::ResourceLoader
|
248
|
-
GraphqlDevise::ResourceLoader.new(
|
249
|
+
GraphqlDevise::ResourceLoader.new(User, {})
|
249
250
|
```
|
250
251
|
|
251
252
|
1. `at`: Route where the GraphQL schema will be mounted on the Rails server.
|
@@ -385,7 +386,71 @@ Keep in mind that if your app uses multiple locales, you should set the `I18n.lo
|
|
385
386
|
### Authenticating Controller Actions
|
386
387
|
When mounting the operation is in you own schema instead of a dedicated one, you will need to authenticate users in your controllers, just like in DTA. There are 2 alternatives to accomplish this.
|
387
388
|
|
388
|
-
#### Authenticate
|
389
|
+
#### Authenticate Resource in the Controller (>= v0.15.0)
|
390
|
+
This authentication mechanism sets the resource by token in the controller, or it doesn't if credentials are invalid.
|
391
|
+
You simply need to pass the return value of our `gql_devise_context` method in the context of your
|
392
|
+
GQL schema execution like this:
|
393
|
+
|
394
|
+
```ruby
|
395
|
+
# app/controllers/my_controller.rb
|
396
|
+
|
397
|
+
class MyController < ApplicationController
|
398
|
+
include GraphqlDevise::Concerns::SetUserByToken
|
399
|
+
|
400
|
+
def my_action
|
401
|
+
result = DummySchema.execute(params[:query], context: gql_devise_context(User))
|
402
|
+
render json: result unless performed?
|
403
|
+
end
|
404
|
+
end
|
405
|
+
```
|
406
|
+
`gql_devise_context` receives as many models as you need to authenticate in the request, like this:
|
407
|
+
```ruby
|
408
|
+
# app/controllers/my_controller.rb
|
409
|
+
|
410
|
+
class MyController < ApplicationController
|
411
|
+
include GraphqlDevise::Concerns::SetUserByToken
|
412
|
+
|
413
|
+
def my_action
|
414
|
+
result = DummySchema.execute(params[:query], context: gql_devise_context(User, Admin))
|
415
|
+
render json: result unless performed?
|
416
|
+
end
|
417
|
+
end
|
418
|
+
```
|
419
|
+
Internally in your own mutations and queries a key `current_resource` will be available in
|
420
|
+
the context if a resource was successfully authenticated or `nil` otherwise.
|
421
|
+
|
422
|
+
Keep in mind that sending multiple models to the `gql_devise_context` method means that depending
|
423
|
+
on who makes the request, the context value `current_resource` might contain instances of the
|
424
|
+
different models you provided.
|
425
|
+
|
426
|
+
**Note:** If for any reason you need more control over how users are authenticated, you can use the `authenticate_model`
|
427
|
+
method anywhere in your controller. The method will return the authenticated resource or nil if authentication fails.
|
428
|
+
It will also set the instance variable `@resource` in the controller.
|
429
|
+
|
430
|
+
Please note that by using this mechanism your GQL schema will be in control of what queries are
|
431
|
+
restricted to authenticated users and you can only do this at the root level fields of your GQL
|
432
|
+
schema. Configure the plugin as explained [here](#mounting-operations-into-your-own-schema)
|
433
|
+
so this can work.
|
434
|
+
|
435
|
+
In you main app's schema this is how you might specify if a field needs to be authenticated or not:
|
436
|
+
```ruby
|
437
|
+
module Types
|
438
|
+
class QueryType < Types::BaseObject
|
439
|
+
# user field used the default set in the Plugin's initializer
|
440
|
+
field :user, resolver: Resolvers::UserShow
|
441
|
+
# this field will never require authentication
|
442
|
+
field :public_field, String, null: false, authenticate: false
|
443
|
+
# this field requires authentication
|
444
|
+
field :private_field, String, null: false, authenticate: true
|
445
|
+
end
|
446
|
+
end
|
447
|
+
```
|
448
|
+
**Important:** Currently, the only check the plugin does to see if the user is authenticated or not when executing
|
449
|
+
the query, is verifying that `context[:current_resource].present?` in the GraphQL context.
|
450
|
+
So, be careful not to populate that key of the context with values other than what `gql_devise_context`
|
451
|
+
returns. The option to do more complex verifications will be added in the future.
|
452
|
+
|
453
|
+
#### Authenticate Before Reaching Your GQL Schema (Deprecated)
|
389
454
|
For this you will need to call `authenticate_<model>!` in a `before_action` controller hook.
|
390
455
|
In our example our model is `User`, so it would look like this:
|
391
456
|
```ruby
|
@@ -397,7 +462,7 @@ class MyController < ApplicationController
|
|
397
462
|
before_action :authenticate_user!
|
398
463
|
|
399
464
|
def my_action
|
400
|
-
result = DummySchema.execute(params[:query], context:
|
465
|
+
result = DummySchema.execute(params[:query], context: { current_resource: current_user })
|
401
466
|
render json: result unless performed?
|
402
467
|
end
|
403
468
|
end
|
@@ -406,7 +471,7 @@ end
|
|
406
471
|
The install generator can include the concern in you application controller.
|
407
472
|
If authentication fails for a request, execution will halt and a REST error will be returned since the request never reaches your GQL schema.
|
408
473
|
|
409
|
-
#### Authenticate in Your GQL Schema
|
474
|
+
#### Authenticate in Your GQL Schema (Deprecated)
|
410
475
|
For this you will need to add the `GraphqlDevise::SchemaPlugin` to your schema as described
|
411
476
|
[here](#mounting-operations-into-your-own-schema).
|
412
477
|
|
@@ -423,7 +488,7 @@ class MyController < ApplicationController
|
|
423
488
|
end
|
424
489
|
```
|
425
490
|
The `graphql_context` method receives a symbol identifying the resource you are trying
|
426
|
-
to authenticate. So if you mounted the `
|
491
|
+
to authenticate. So if you mounted the `User` resource, the symbol is `:user`. You can use
|
427
492
|
this snippet to find the symbol for more complex scenarios
|
428
493
|
`resource_klass.to_s.underscore.tr('/', '_').to_sym`. `graphql_context` can also take an
|
429
494
|
array of resources if you mounted more than one into your schema. The gem will try to
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphqlDevise
|
4
|
+
module Concerns
|
5
|
+
module AdditionalControllerMethods
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
attr_accessor :client_id, :token, :resource
|
10
|
+
end
|
11
|
+
|
12
|
+
def gql_devise_context(*models)
|
13
|
+
{
|
14
|
+
current_resource: authenticate_model(*models),
|
15
|
+
controller: self
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
def authenticate_model(*models)
|
20
|
+
models.each do |model|
|
21
|
+
set_resource_by_token(model)
|
22
|
+
return @resource if @resource.present?
|
23
|
+
end
|
24
|
+
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
|
28
|
+
def resource_class(resource = nil)
|
29
|
+
# Return the resource class instead of looking for a Devise mapping if resource is already a resource class
|
30
|
+
return resource if resource.respond_to?(:find_by)
|
31
|
+
|
32
|
+
super
|
33
|
+
end
|
34
|
+
|
35
|
+
def full_url_without_params
|
36
|
+
request.base_url + request.path
|
37
|
+
end
|
38
|
+
|
39
|
+
def set_resource_by_token(resource)
|
40
|
+
set_user_by_token(resource)
|
41
|
+
end
|
42
|
+
|
43
|
+
def graphql_context(resource_name)
|
44
|
+
ActiveSupport::Deprecation.warn(<<-DEPRECATION.strip_heredoc, caller)
|
45
|
+
`graphql_context` is deprecated and will be removed in a future version of this gem.
|
46
|
+
Use `gql_devise_context(model)` instead.
|
47
|
+
|
48
|
+
EXAMPLE
|
49
|
+
include GraphqlDevise::Concerns::SetUserByToken
|
50
|
+
|
51
|
+
DummySchema.execute(params[:query], context: gql_devise_context(User))
|
52
|
+
DummySchema.execute(params[:query], context: gql_devise_context(User, Admin))
|
53
|
+
DEPRECATION
|
54
|
+
|
55
|
+
{
|
56
|
+
resource_name: resource_name,
|
57
|
+
controller: self
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
def build_redirect_headers(access_token, client, redirect_header_options = {})
|
62
|
+
{
|
63
|
+
DeviseTokenAuth.headers_names[:"access-token"] => access_token,
|
64
|
+
DeviseTokenAuth.headers_names[:client] => client,
|
65
|
+
:config => params[:config],
|
66
|
+
:client_id => client,
|
67
|
+
:token => access_token
|
68
|
+
}.merge(redirect_header_options)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -2,34 +2,12 @@
|
|
2
2
|
|
3
3
|
module GraphqlDevise
|
4
4
|
module Concerns
|
5
|
-
|
5
|
+
module SetUserByToken
|
6
|
+
extend ActiveSupport::Concern
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
def full_url_without_params
|
11
|
-
request.base_url + request.path
|
12
|
-
end
|
13
|
-
|
14
|
-
def set_resource_by_token(resource)
|
15
|
-
set_user_by_token(resource)
|
16
|
-
end
|
17
|
-
|
18
|
-
def graphql_context(resource_name)
|
19
|
-
{
|
20
|
-
resource_name: resource_name,
|
21
|
-
controller: self
|
22
|
-
}
|
23
|
-
end
|
24
|
-
|
25
|
-
def build_redirect_headers(access_token, client, redirect_header_options = {})
|
26
|
-
{
|
27
|
-
DeviseTokenAuth.headers_names[:"access-token"] => access_token,
|
28
|
-
DeviseTokenAuth.headers_names[:client] => client,
|
29
|
-
:config => params[:config],
|
30
|
-
:client_id => client,
|
31
|
-
:token => access_token
|
32
|
-
}.merge(redirect_header_options)
|
8
|
+
included do
|
9
|
+
include DeviseTokenAuth::Concerns::SetUserByToken
|
10
|
+
include GraphqlDevise::Concerns::AdditionalControllerMethods
|
33
11
|
end
|
34
12
|
end
|
35
13
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module GraphqlDevise
|
4
4
|
module MailerHelper
|
5
5
|
def confirmation_query(resource_name:, token:, redirect_url:)
|
6
|
-
name = "#{
|
6
|
+
name = "#{GraphqlDevise.to_mapping_name(resource_name).camelize(:lower)}ConfirmAccount"
|
7
7
|
raw = <<-GRAPHQL
|
8
8
|
query($token:String!,$redirectUrl:String!){
|
9
9
|
#{name}(confirmationToken:$token,redirectUrl:$redirectUrl){
|
@@ -19,7 +19,7 @@ module GraphqlDevise
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def password_reset_query(token:, redirect_url:, resource_name:)
|
22
|
-
name = "#{
|
22
|
+
name = "#{GraphqlDevise.to_mapping_name(resource_name).camelize(:lower)}CheckPasswordToken"
|
23
23
|
raw = <<-GRAPHQL
|
24
24
|
query($token:String!,$redirectUrl:String!){
|
25
25
|
#{name}(resetPasswordToken:$token,redirectUrl:$redirectUrl){
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'graphql_devise/model/with_email_updater'
|
4
|
+
|
5
|
+
module GraphqlDevise
|
6
|
+
module Concerns
|
7
|
+
module AdditionalModelMethods
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
class_methods do
|
11
|
+
def reconfirmable
|
12
|
+
devise_modules.include?(:confirmable) && column_names.include?('unconfirmed_email')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def update_with_email(attributes = {})
|
17
|
+
GraphqlDevise::Model::WithEmailUpdater.new(self, attributes).call
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -4,17 +4,14 @@ require 'graphql_devise/model/with_email_updater'
|
|
4
4
|
|
5
5
|
module GraphqlDevise
|
6
6
|
module Concerns
|
7
|
-
Model
|
7
|
+
module Model
|
8
|
+
extend ActiveSupport::Concern
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
devise_modules.include?(:confirmable) && column_names.include?('unconfirmed_email')
|
13
|
-
end
|
14
|
-
end
|
10
|
+
included do
|
11
|
+
include DeviseTokenAuth::Concerns::User
|
12
|
+
include GraphqlDevise::Concerns::AdditionalModelMethods
|
15
13
|
|
16
|
-
|
17
|
-
GraphqlDevise::Model::WithEmailUpdater.new(self, attributes).call
|
14
|
+
GraphqlDevise.configure_warden_serializer_for_model(self)
|
18
15
|
end
|
19
16
|
end
|
20
17
|
end
|
data/lib/graphql_devise.rb
CHANGED
@@ -20,22 +20,36 @@ module GraphqlDevise
|
|
20
20
|
@schema_loaded = true
|
21
21
|
end
|
22
22
|
|
23
|
-
def self.resource_mounted?(
|
24
|
-
@mounted_resources.include?(
|
23
|
+
def self.resource_mounted?(model)
|
24
|
+
@mounted_resources.include?(model)
|
25
25
|
end
|
26
26
|
|
27
|
-
def self.mount_resource(
|
28
|
-
@mounted_resources <<
|
27
|
+
def self.mount_resource(model)
|
28
|
+
@mounted_resources << model
|
29
29
|
end
|
30
30
|
|
31
31
|
def self.add_mapping(mapping_name, resource)
|
32
|
-
return if Devise.mappings.key?(mapping_name)
|
32
|
+
return if Devise.mappings.key?(mapping_name.to_sym)
|
33
33
|
|
34
34
|
Devise.add_mapping(
|
35
35
|
mapping_name.to_s.pluralize.to_sym,
|
36
|
-
module: :devise, class_name: resource
|
36
|
+
module: :devise, class_name: resource.to_s
|
37
37
|
)
|
38
38
|
end
|
39
|
+
|
40
|
+
def self.to_mapping_name(resource)
|
41
|
+
resource.to_s.underscore.tr('/', '_')
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.configure_warden_serializer_for_model(model)
|
45
|
+
Devise.warden_config.serialize_into_session(to_mapping_name(model)) do |record|
|
46
|
+
model.serialize_into_session(record)
|
47
|
+
end
|
48
|
+
|
49
|
+
Devise.warden_config.serialize_from_session(to_mapping_name(model)) do |args|
|
50
|
+
model.serialize_from_session(*args)
|
51
|
+
end
|
52
|
+
end
|
39
53
|
end
|
40
54
|
|
41
55
|
require 'graphql_devise/engine'
|
@@ -40,11 +40,11 @@ module GraphqlDevise
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def resource_name
|
43
|
-
|
43
|
+
GraphqlDevise.to_mapping_name(resource_class)
|
44
44
|
end
|
45
45
|
|
46
46
|
def resource_class
|
47
|
-
|
47
|
+
self.class.instance_variable_get(:@resource_klass)
|
48
48
|
end
|
49
49
|
|
50
50
|
def recoverable_enabled?
|
@@ -60,7 +60,7 @@ module GraphqlDevise
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def current_resource
|
63
|
-
@current_resource ||= controller.send(:
|
63
|
+
@current_resource ||= controller.send(:set_resource_by_token, resource_class)
|
64
64
|
end
|
65
65
|
|
66
66
|
def client
|
@@ -3,17 +3,17 @@
|
|
3
3
|
require_relative 'operation_preparers/gql_name_setter'
|
4
4
|
require_relative 'operation_preparers/mutation_field_setter'
|
5
5
|
require_relative 'operation_preparers/resolver_type_setter'
|
6
|
-
require_relative 'operation_preparers/
|
6
|
+
require_relative 'operation_preparers/resource_klass_setter'
|
7
7
|
require_relative 'operation_preparers/default_operation_preparer'
|
8
8
|
require_relative 'operation_preparers/custom_operation_preparer'
|
9
9
|
|
10
10
|
module GraphqlDevise
|
11
11
|
module MountMethod
|
12
12
|
class OperationPreparer
|
13
|
-
def initialize(
|
13
|
+
def initialize(model:, selected_operations:, preparer:, custom:, additional_operations:)
|
14
14
|
@selected_operations = selected_operations
|
15
15
|
@preparer = preparer
|
16
|
-
@
|
16
|
+
@model = model
|
17
17
|
@custom = custom
|
18
18
|
@additional_operations = additional_operations
|
19
19
|
end
|
@@ -22,18 +22,18 @@ module GraphqlDevise
|
|
22
22
|
default_operations = OperationPreparers::DefaultOperationPreparer.new(
|
23
23
|
selected_operations: @selected_operations,
|
24
24
|
custom_keys: @custom.keys,
|
25
|
-
|
25
|
+
model: @model,
|
26
26
|
preparer: @preparer
|
27
27
|
).call
|
28
28
|
|
29
29
|
custom_operations = OperationPreparers::CustomOperationPreparer.new(
|
30
30
|
selected_keys: @selected_operations.keys,
|
31
31
|
custom_operations: @custom,
|
32
|
-
|
32
|
+
model: @model
|
33
33
|
).call
|
34
34
|
|
35
35
|
additional_operations = @additional_operations.each_with_object({}) do |(action, operation), result|
|
36
|
-
result[action] = OperationPreparers::
|
36
|
+
result[action] = OperationPreparers::ResourceKlassSetter.new(@model).call(operation)
|
37
37
|
end
|
38
38
|
|
39
39
|
default_operations.merge(custom_operations).merge(additional_operations)
|
@@ -4,19 +4,21 @@ module GraphqlDevise
|
|
4
4
|
module MountMethod
|
5
5
|
module OperationPreparers
|
6
6
|
class CustomOperationPreparer
|
7
|
-
def initialize(selected_keys:, custom_operations:,
|
7
|
+
def initialize(selected_keys:, custom_operations:, model:)
|
8
8
|
@selected_keys = selected_keys
|
9
9
|
@custom_operations = custom_operations
|
10
|
-
@
|
10
|
+
@model = model
|
11
11
|
end
|
12
12
|
|
13
13
|
def call
|
14
|
+
mapping_name = GraphqlDevise.to_mapping_name(@model)
|
15
|
+
|
14
16
|
@custom_operations.slice(*@selected_keys).each_with_object({}) do |(action, operation), result|
|
15
|
-
mapped_action = "#{
|
17
|
+
mapped_action = "#{mapping_name}_#{action}"
|
16
18
|
|
17
19
|
result[mapped_action.to_sym] = [
|
18
20
|
OperationPreparers::GqlNameSetter.new(mapped_action),
|
19
|
-
OperationPreparers::
|
21
|
+
OperationPreparers::ResourceKlassSetter.new(@model)
|
20
22
|
].reduce(operation) { |prepared_operation, preparer| preparer.call(prepared_operation) }
|
21
23
|
end
|
22
24
|
end
|
@@ -4,23 +4,25 @@ module GraphqlDevise
|
|
4
4
|
module MountMethod
|
5
5
|
module OperationPreparers
|
6
6
|
class DefaultOperationPreparer
|
7
|
-
def initialize(selected_operations:, custom_keys:,
|
7
|
+
def initialize(selected_operations:, custom_keys:, model:, preparer:)
|
8
8
|
@selected_operations = selected_operations
|
9
9
|
@custom_keys = custom_keys
|
10
|
-
@
|
10
|
+
@model = model
|
11
11
|
@preparer = preparer
|
12
12
|
end
|
13
13
|
|
14
14
|
def call
|
15
|
+
mapping_name = GraphqlDevise.to_mapping_name(@model)
|
16
|
+
|
15
17
|
@selected_operations.except(*@custom_keys).each_with_object({}) do |(action, operation_info), result|
|
16
|
-
mapped_action = "#{
|
18
|
+
mapped_action = "#{mapping_name}_#{action}"
|
17
19
|
operation = operation_info[:klass]
|
18
20
|
options = operation_info.except(:klass)
|
19
21
|
|
20
22
|
result[mapped_action.to_sym] = [
|
21
23
|
OperationPreparers::GqlNameSetter.new(mapped_action),
|
22
24
|
@preparer,
|
23
|
-
OperationPreparers::
|
25
|
+
OperationPreparers::ResourceKlassSetter.new(@model)
|
24
26
|
].reduce(child_class(operation)) do |prepared_operation, preparer|
|
25
27
|
preparer.call(prepared_operation, **options)
|
26
28
|
end
|
@@ -3,13 +3,13 @@
|
|
3
3
|
module GraphqlDevise
|
4
4
|
module MountMethod
|
5
5
|
module OperationPreparers
|
6
|
-
class
|
7
|
-
def initialize(
|
8
|
-
@
|
6
|
+
class ResourceKlassSetter
|
7
|
+
def initialize(klass)
|
8
|
+
@klass = klass
|
9
9
|
end
|
10
10
|
|
11
11
|
def call(operation, **)
|
12
|
-
operation.instance_variable_set(:@
|
12
|
+
operation.instance_variable_set(:@resource_klass, @klass)
|
13
13
|
|
14
14
|
operation
|
15
15
|
end
|
@@ -10,12 +10,27 @@ module GraphqlDevise
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def call(query, mutation)
|
13
|
-
mapping_name = @resource.to_s.underscore.tr('/', '_').to_sym
|
14
|
-
|
15
13
|
# clean_options responds to all keys defined in GraphqlDevise::MountMethod::SUPPORTED_OPTIONS
|
16
14
|
clean_options = GraphqlDevise::MountMethod::OptionSanitizer.new(@options).call!
|
17
15
|
|
18
|
-
|
16
|
+
model = if @resource.is_a?(String)
|
17
|
+
ActiveSupport::Deprecation.warn(<<-DEPRECATION.strip_heredoc, caller)
|
18
|
+
Providing a String as the model you want to mount is deprecated and will be removed in a future version of
|
19
|
+
this gem. Please use the actual model constant instead.
|
20
|
+
|
21
|
+
EXAMPLE
|
22
|
+
|
23
|
+
GraphqlDevise::ResourceLoader.new(User) # instead of GraphqlDevise::ResourceLoader.new('User')
|
24
|
+
|
25
|
+
mount_graphql_devise_for User # instead of mount_graphql_devise_for 'User'
|
26
|
+
DEPRECATION
|
27
|
+
@resource.constantize
|
28
|
+
else
|
29
|
+
@resource
|
30
|
+
end
|
31
|
+
|
32
|
+
# Necesary when mounting a resource via route file as Devise forces the reloading of routes
|
33
|
+
return clean_options if GraphqlDevise.resource_mounted?(model) && @routing
|
19
34
|
|
20
35
|
validate_options!(clean_options)
|
21
36
|
|
@@ -23,7 +38,7 @@ module GraphqlDevise
|
|
23
38
|
"Types::#{@resource}Type".safe_constantize ||
|
24
39
|
GraphqlDevise::Types::AuthenticatableType
|
25
40
|
|
26
|
-
prepared_mutations = prepare_mutations(
|
41
|
+
prepared_mutations = prepare_mutations(model, clean_options, authenticatable_type)
|
27
42
|
|
28
43
|
if prepared_mutations.any? && mutation.blank?
|
29
44
|
raise GraphqlDevise::Error, 'You need to provide a mutation type unless all mutations are skipped'
|
@@ -33,7 +48,7 @@ module GraphqlDevise
|
|
33
48
|
mutation.field(action, mutation: prepared_mutation, authenticate: false)
|
34
49
|
end
|
35
50
|
|
36
|
-
prepared_resolvers = prepare_resolvers(
|
51
|
+
prepared_resolvers = prepare_resolvers(model, clean_options, authenticatable_type)
|
37
52
|
|
38
53
|
if prepared_resolvers.any? && query.blank?
|
39
54
|
raise GraphqlDevise::Error, 'You need to provide a query type unless all queries are skipped'
|
@@ -43,17 +58,17 @@ module GraphqlDevise
|
|
43
58
|
query.field(action, resolver: resolver, authenticate: false)
|
44
59
|
end
|
45
60
|
|
46
|
-
GraphqlDevise.add_mapping(
|
47
|
-
GraphqlDevise.mount_resource(
|
61
|
+
GraphqlDevise.add_mapping(GraphqlDevise.to_mapping_name(@resource).to_sym, @resource)
|
62
|
+
GraphqlDevise.mount_resource(model) if @routing
|
48
63
|
|
49
64
|
clean_options
|
50
65
|
end
|
51
66
|
|
52
67
|
private
|
53
68
|
|
54
|
-
def prepare_resolvers(
|
69
|
+
def prepare_resolvers(model, clean_options, authenticatable_type)
|
55
70
|
GraphqlDevise::MountMethod::OperationPreparer.new(
|
56
|
-
|
71
|
+
model: model,
|
57
72
|
custom: clean_options.operations,
|
58
73
|
additional_operations: clean_options.additional_queries,
|
59
74
|
preparer: GraphqlDevise::MountMethod::OperationPreparers::ResolverTypeSetter.new(authenticatable_type),
|
@@ -63,9 +78,9 @@ module GraphqlDevise
|
|
63
78
|
).call
|
64
79
|
end
|
65
80
|
|
66
|
-
def prepare_mutations(
|
81
|
+
def prepare_mutations(model, clean_options, authenticatable_type)
|
67
82
|
GraphqlDevise::MountMethod::OperationPreparer.new(
|
68
|
-
|
83
|
+
model: model,
|
69
84
|
custom: clean_options.operations,
|
70
85
|
additional_operations: clean_options.additional_mutations,
|
71
86
|
preparer: GraphqlDevise::MountMethod::OperationPreparers::MutationFieldSetter.new(authenticatable_type),
|
@@ -16,7 +16,6 @@ module GraphqlDevise
|
|
16
16
|
|
17
17
|
# Must happen on initialize so operations are loaded before the types are added to the schema on GQL < 1.10
|
18
18
|
load_fields
|
19
|
-
reconfigure_warden!
|
20
19
|
end
|
21
20
|
|
22
21
|
def use(schema_definition)
|
@@ -31,6 +30,20 @@ module GraphqlDevise
|
|
31
30
|
auth_required = authenticate_option(field, trace_data)
|
32
31
|
context = context_from_data(trace_data)
|
33
32
|
|
33
|
+
if context.key?(:resource_name)
|
34
|
+
ActiveSupport::Deprecation.warn(<<-DEPRECATION.strip_heredoc, caller)
|
35
|
+
Providing `resource_name` as part of the GQL context, or doing so by using the `graphql_context(resource_name)`
|
36
|
+
method on your controller is deprecated and will be removed in a future version of this gem.
|
37
|
+
Please use `gql_devise_context` in you controller instead.
|
38
|
+
|
39
|
+
EXAMPLE
|
40
|
+
include GraphqlDevise::Concerns::SetUserByToken
|
41
|
+
|
42
|
+
DummySchema.execute(params[:query], context: gql_devise_context(User))
|
43
|
+
DummySchema.execute(params[:query], context: gql_devise_context(User, Admin))
|
44
|
+
DEPRECATION
|
45
|
+
end
|
46
|
+
|
34
47
|
if auth_required && !(public_introspection && introspection_field?(field))
|
35
48
|
context = set_current_resource(context)
|
36
49
|
raise_on_missing_resource(context, field)
|
@@ -102,11 +115,6 @@ module GraphqlDevise
|
|
102
115
|
auth_required.nil? ? @authenticate_default : auth_required
|
103
116
|
end
|
104
117
|
|
105
|
-
def reconfigure_warden!
|
106
|
-
Devise.class_variable_set(:@@warden_configured, nil)
|
107
|
-
Devise.configure_warden!
|
108
|
-
end
|
109
|
-
|
110
118
|
def load_fields
|
111
119
|
@resource_loaders.each do |resource_loader|
|
112
120
|
raise Error, 'Invalid resource loader instance' unless resource_loader.instance_of?(GraphqlDevise::ResourceLoader)
|
@@ -19,6 +19,17 @@ module Api
|
|
19
19
|
render json: DummySchema.execute(params[:query], context: graphql_context([:user, :fail]))
|
20
20
|
end
|
21
21
|
|
22
|
+
def controller_auth
|
23
|
+
result = DummySchema.execute(
|
24
|
+
params[:query],
|
25
|
+
operation_name: params[:operationName],
|
26
|
+
variables: ensure_hash(params[:variables]),
|
27
|
+
context: gql_devise_context(SchemaUser, User)
|
28
|
+
)
|
29
|
+
|
30
|
+
render json: result unless performed?
|
31
|
+
end
|
32
|
+
|
22
33
|
private
|
23
34
|
|
24
35
|
def execute_params(item)
|
data/spec/dummy/config/routes.rb
CHANGED
@@ -11,7 +11,7 @@ Rails.application.routes.draw do
|
|
11
11
|
}
|
12
12
|
|
13
13
|
mount_graphql_devise_for(
|
14
|
-
|
14
|
+
Admin,
|
15
15
|
authenticatable_type: Types::CustomAdminType,
|
16
16
|
skip: [:sign_up, :check_password_token],
|
17
17
|
operations: {
|
@@ -37,4 +37,5 @@ Rails.application.routes.draw do
|
|
37
37
|
post '/api/v1/graphql', to: 'api/v1/graphql#graphql'
|
38
38
|
post '/api/v1/interpreter', to: 'api/v1/graphql#interpreter'
|
39
39
|
post '/api/v1/failing', to: 'api/v1/graphql#failing_resource_name'
|
40
|
+
post '/api/v1/controller_auth', to: 'api/v1/graphql#controller_auth'
|
40
41
|
end
|
@@ -33,7 +33,7 @@ RSpec.describe GraphqlDevise::InstallGenerator, type: :generator do
|
|
33
33
|
|
34
34
|
assert_file 'app/controllers/application_controller.rb', /^\s{2}include GraphqlDevise::Concerns::SetUserByToken/
|
35
35
|
|
36
|
-
assert_file 'app/graphql/gqld_dummy_schema.rb', /\s+#{Regexp.escape("GraphqlDevise::ResourceLoader.new(
|
36
|
+
assert_file 'app/graphql/gqld_dummy_schema.rb', /\s+#{Regexp.escape("GraphqlDevise::ResourceLoader.new(Admin)")}/
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
@@ -74,7 +74,7 @@ RSpec.describe GraphqlDevise::GraphqlController do
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def post_request(path)
|
77
|
-
if
|
77
|
+
if Rails::VERSION::MAJOR >= 5
|
78
78
|
post(path, params: params)
|
79
79
|
else
|
80
80
|
post(path, params)
|
@@ -42,6 +42,26 @@ RSpec.describe "Integrations with the user's controller" do
|
|
42
42
|
GRAPHQL
|
43
43
|
end
|
44
44
|
|
45
|
+
context 'when authenticating before using the GQL schema' do
|
46
|
+
before { post_request('/api/v1/controller_auth') }
|
47
|
+
|
48
|
+
context 'when user is authenticated' do
|
49
|
+
let(:headers) { create(:schema_user).create_new_auth_token }
|
50
|
+
|
51
|
+
it 'allows authentication at the controller level' do
|
52
|
+
expect(json_response[:data][:privateField]).to eq('Field will always require authentication')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'when user is not authenticated' do
|
57
|
+
it 'returns a must sign in error' do
|
58
|
+
expect(json_response[:errors]).to contain_exactly(
|
59
|
+
hash_including(message: 'privateField field requires authentication', extensions: { code: 'AUTHENTICATION_ERROR' })
|
60
|
+
)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
45
65
|
context 'when using a regular schema' do
|
46
66
|
before { post_request('/api/v1/graphql') }
|
47
67
|
|
@@ -1,12 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'rails_helper'
|
4
4
|
|
5
5
|
RSpec.describe GraphqlDevise::MountMethod::OperationPreparer do
|
6
6
|
describe '#call' do
|
7
7
|
subject(:prepared_operations) do
|
8
8
|
described_class.new(
|
9
|
-
|
9
|
+
model: model,
|
10
10
|
selected_operations: selected,
|
11
11
|
preparer: preparer,
|
12
12
|
custom: custom,
|
@@ -15,14 +15,14 @@ RSpec.describe GraphqlDevise::MountMethod::OperationPreparer do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
let(:logout_class) { Class.new(GraphQL::Schema::Resolver) }
|
18
|
-
let(:
|
18
|
+
let(:model) { User }
|
19
19
|
let(:preparer) { double(:preparer, call: logout_class) }
|
20
20
|
let(:custom) { { login: double(:custom_login, graphql_name: nil) } }
|
21
21
|
let(:additional) { { user_additional: double(:user_additional) } }
|
22
22
|
let(:selected) do
|
23
23
|
{
|
24
|
-
login:
|
25
|
-
logout:{ klass: logout_class }
|
24
|
+
login: { klass: double(:login_default) },
|
25
|
+
logout: { klass: logout_class }
|
26
26
|
}
|
27
27
|
end
|
28
28
|
|
@@ -1,14 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'rails_helper'
|
4
4
|
|
5
5
|
RSpec.describe GraphqlDevise::MountMethod::OperationPreparers::CustomOperationPreparer do
|
6
6
|
describe '#call' do
|
7
|
-
subject(:prepared) { described_class.new(selected_keys: selected_keys, custom_operations: operations,
|
7
|
+
subject(:prepared) { described_class.new(selected_keys: selected_keys, custom_operations: operations, model: model).call }
|
8
8
|
|
9
9
|
let(:login_operation) { double(:confirm_operation, graphql_name: nil) }
|
10
10
|
let(:logout_operation) { double(:sign_up_operation, graphql_name: nil) }
|
11
|
-
let(:
|
11
|
+
let(:model) { User }
|
12
12
|
let(:operations) { { login: login_operation, logout: logout_operation, invalid: double(:invalid) } }
|
13
13
|
let(:selected_keys) { [:login, :logout, :sign_up, :confirm] }
|
14
14
|
|
@@ -22,8 +22,8 @@ RSpec.describe GraphqlDevise::MountMethod::OperationPreparers::CustomOperationPr
|
|
22
22
|
|
23
23
|
prepared
|
24
24
|
|
25
|
-
expect(login_operation.instance_variable_get(:@
|
26
|
-
expect(logout_operation.instance_variable_get(:@
|
25
|
+
expect(login_operation.instance_variable_get(:@resource_klass)).to eq(User)
|
26
|
+
expect(logout_operation.instance_variable_get(:@resource_klass)).to eq(User)
|
27
27
|
end
|
28
28
|
|
29
29
|
context 'when no selected keys are provided' do
|
@@ -1,17 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'rails_helper'
|
4
4
|
|
5
5
|
RSpec.describe GraphqlDevise::MountMethod::OperationPreparers::DefaultOperationPreparer do
|
6
6
|
describe '#call' do
|
7
7
|
subject(:prepared) { default_preparer.call }
|
8
8
|
|
9
|
-
let(:default_preparer) { described_class.new(selected_operations: operations, custom_keys: custom_keys,
|
9
|
+
let(:default_preparer) { described_class.new(selected_operations: operations, custom_keys: custom_keys, model: model, preparer: preparer) }
|
10
10
|
let(:confirm_operation) { double(:confirm_operation, graphql_name: nil) }
|
11
11
|
let(:sign_up_operation) { double(:sign_up_operation, graphql_name: nil) }
|
12
12
|
let(:login_operation) { double(:confirm_operation, graphql_name: nil) }
|
13
13
|
let(:logout_operation) { double(:sign_up_operation, graphql_name: nil) }
|
14
|
-
let(:
|
14
|
+
let(:model) { User }
|
15
15
|
let(:preparer) { double(:preparer) }
|
16
16
|
let(:custom_keys) { [:login, :logout] }
|
17
17
|
let(:operations) do
|
@@ -46,8 +46,8 @@ RSpec.describe GraphqlDevise::MountMethod::OperationPreparers::DefaultOperationP
|
|
46
46
|
|
47
47
|
prepared
|
48
48
|
|
49
|
-
expect(confirm_operation.instance_variable_get(:@
|
50
|
-
expect(sign_up_operation.instance_variable_get(:@
|
49
|
+
expect(confirm_operation.instance_variable_get(:@resource_klass)).to eq(User)
|
50
|
+
expect(sign_up_operation.instance_variable_get(:@resource_klass)).to eq(User)
|
51
51
|
end
|
52
52
|
|
53
53
|
context 'when no custom keys are provided' do
|
@@ -1,16 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'rails_helper'
|
4
4
|
|
5
|
-
RSpec.describe GraphqlDevise::MountMethod::OperationPreparers::
|
5
|
+
RSpec.describe GraphqlDevise::MountMethod::OperationPreparers::ResourceKlassSetter do
|
6
6
|
describe '#call' do
|
7
|
-
subject(:prepared_operation) { described_class.new(
|
7
|
+
subject(:prepared_operation) { described_class.new(model).call(operation) }
|
8
8
|
|
9
|
-
let(:operation)
|
10
|
-
let(:
|
9
|
+
let(:operation) { double(:operation) }
|
10
|
+
let(:model) { User }
|
11
11
|
|
12
12
|
it 'sets a gql name to the operation' do
|
13
|
-
expect(prepared_operation.instance_variable_get(:@
|
13
|
+
expect(prepared_operation.instance_variable_get(:@resource_klass)).to eq(model)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'rails_helper'
|
4
4
|
|
5
5
|
RSpec.describe GraphqlDevise::ResourceLoader do
|
6
6
|
describe '#call' do
|
@@ -15,8 +15,8 @@ RSpec.describe GraphqlDevise::ResourceLoader do
|
|
15
15
|
|
16
16
|
before do
|
17
17
|
allow(GraphqlDevise).to receive(:add_mapping).with(:user, resource)
|
18
|
-
allow(GraphqlDevise).to receive(:resource_mounted?).with(
|
19
|
-
allow(GraphqlDevise).to receive(:mount_resource).with(
|
18
|
+
allow(GraphqlDevise).to receive(:resource_mounted?).with(User).and_return(mounted)
|
19
|
+
allow(GraphqlDevise).to receive(:mount_resource).with(User)
|
20
20
|
end
|
21
21
|
|
22
22
|
it 'loads operations into the provided types' do
|
@@ -64,13 +64,13 @@ RSpec.describe GraphqlDevise::ResourceLoader do
|
|
64
64
|
|
65
65
|
it 'adds mappings' do
|
66
66
|
expect(GraphqlDevise).to receive(:add_mapping).with(:user, resource)
|
67
|
-
expect(GraphqlDevise).to receive(:mount_resource).with(
|
67
|
+
expect(GraphqlDevise).to receive(:mount_resource).with(User)
|
68
68
|
|
69
69
|
loader
|
70
70
|
end
|
71
71
|
|
72
72
|
context 'when resource was already mounted' do
|
73
|
-
before { allow(GraphqlDevise).to receive(:resource_mounted?).with(
|
73
|
+
before { allow(GraphqlDevise).to receive(:resource_mounted?).with(User).and_return(true) }
|
74
74
|
|
75
75
|
it 'skips schema loading' do
|
76
76
|
expect(query).not_to receive(:field)
|
@@ -4,7 +4,7 @@ RSpec.shared_context 'with graphql query request' do
|
|
4
4
|
let(:headers) { {} }
|
5
5
|
let(:variables) { {} }
|
6
6
|
let(:graphql_params) do
|
7
|
-
if
|
7
|
+
if Rails::VERSION::MAJOR >= 5
|
8
8
|
{ params: { query: query, variables: variables }, headers: headers }
|
9
9
|
else
|
10
10
|
[{ query: query, variables: variables }, headers]
|
@@ -20,7 +20,7 @@ RSpec.shared_context 'with graphql query request' do
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def send_request(path, method)
|
23
|
-
if
|
23
|
+
if Rails::VERSION::MAJOR >= 5
|
24
24
|
public_send(method, path, **graphql_params)
|
25
25
|
else
|
26
26
|
public_send(method, path, *graphql_params)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql_devise
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.15.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mario Celi
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2021-
|
12
|
+
date: 2021-05-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: devise_token_auth
|
@@ -289,10 +289,12 @@ files:
|
|
289
289
|
- README.md
|
290
290
|
- Rakefile
|
291
291
|
- app/controllers/graphql_devise/application_controller.rb
|
292
|
+
- app/controllers/graphql_devise/concerns/additional_controller_methods.rb
|
292
293
|
- app/controllers/graphql_devise/concerns/set_user_by_token.rb
|
293
294
|
- app/controllers/graphql_devise/graphql_controller.rb
|
294
295
|
- app/helpers/graphql_devise/application_helper.rb
|
295
296
|
- app/helpers/graphql_devise/mailer_helper.rb
|
297
|
+
- app/models/graphql_devise/concerns/additional_model_methods.rb
|
296
298
|
- app/models/graphql_devise/concerns/model.rb
|
297
299
|
- app/views/.keep
|
298
300
|
- app/views/graphql_devise/mailer/confirmation_instructions.html.erb
|
@@ -322,7 +324,7 @@ files:
|
|
322
324
|
- lib/graphql_devise/mount_method/operation_preparers/gql_name_setter.rb
|
323
325
|
- lib/graphql_devise/mount_method/operation_preparers/mutation_field_setter.rb
|
324
326
|
- lib/graphql_devise/mount_method/operation_preparers/resolver_type_setter.rb
|
325
|
-
- lib/graphql_devise/mount_method/operation_preparers/
|
327
|
+
- lib/graphql_devise/mount_method/operation_preparers/resource_klass_setter.rb
|
326
328
|
- lib/graphql_devise/mount_method/operation_sanitizer.rb
|
327
329
|
- lib/graphql_devise/mount_method/option_sanitizer.rb
|
328
330
|
- lib/graphql_devise/mount_method/option_sanitizers/array_checker.rb
|
@@ -458,7 +460,7 @@ files:
|
|
458
460
|
- spec/services/mount_method/operation_preparers/gql_name_setter_spec.rb
|
459
461
|
- spec/services/mount_method/operation_preparers/mutation_field_setter_spec.rb
|
460
462
|
- spec/services/mount_method/operation_preparers/resolver_type_setter_spec.rb
|
461
|
-
- spec/services/mount_method/operation_preparers/
|
463
|
+
- spec/services/mount_method/operation_preparers/resource_klass_setter_spec.rb
|
462
464
|
- spec/services/mount_method/operation_sanitizer_spec.rb
|
463
465
|
- spec/services/mount_method/option_sanitizer_spec.rb
|
464
466
|
- spec/services/mount_method/option_sanitizers/array_checker_spec.rb
|
@@ -500,7 +502,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
500
502
|
- !ruby/object:Gem::Version
|
501
503
|
version: '0'
|
502
504
|
requirements: []
|
503
|
-
rubygems_version: 3.
|
505
|
+
rubygems_version: 3.1.4
|
504
506
|
signing_key:
|
505
507
|
specification_version: 4
|
506
508
|
summary: GraphQL queries and mutations on top of devise_token_auth
|
@@ -607,7 +609,7 @@ test_files:
|
|
607
609
|
- spec/services/mount_method/operation_preparers/gql_name_setter_spec.rb
|
608
610
|
- spec/services/mount_method/operation_preparers/mutation_field_setter_spec.rb
|
609
611
|
- spec/services/mount_method/operation_preparers/resolver_type_setter_spec.rb
|
610
|
-
- spec/services/mount_method/operation_preparers/
|
612
|
+
- spec/services/mount_method/operation_preparers/resource_klass_setter_spec.rb
|
611
613
|
- spec/services/mount_method/operation_sanitizer_spec.rb
|
612
614
|
- spec/services/mount_method/option_sanitizer_spec.rb
|
613
615
|
- spec/services/mount_method/option_sanitizers/array_checker_spec.rb
|