graphql_devise 0.14.3 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|