Skip to content

Commit 3d4972c

Browse files
Merge pull request #175 from graphql-devise/allow-controller-level-authentication
Allow controller level authentication
2 parents 23b14e5 + 2155f5d commit 3d4972c

22 files changed

Lines changed: 213 additions & 109 deletions
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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+
Array(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+
{
45+
resource_name: resource_name,
46+
controller: self
47+
}
48+
end
49+
50+
def build_redirect_headers(access_token, client, redirect_header_options = {})
51+
{
52+
DeviseTokenAuth.headers_names[:"access-token"] => access_token,
53+
DeviseTokenAuth.headers_names[:client] => client,
54+
:config => params[:config],
55+
:client_id => client,
56+
:token => access_token
57+
}.merge(redirect_header_options)
58+
end
59+
end
60+
end
61+
end

app/controllers/graphql_devise/concerns/set_user_by_token.rb

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,12 @@
22

33
module GraphqlDevise
44
module Concerns
5-
SetUserByToken = DeviseTokenAuth::Concerns::SetUserByToken
5+
module SetUserByToken
6+
extend ActiveSupport::Concern
67

7-
SetUserByToken.module_eval do
8-
attr_accessor :client_id, :token, :resource
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
3311
end
3412
end
3513
end

app/helpers/graphql_devise/mailer_helper.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
module GraphqlDevise
44
module MailerHelper
55
def confirmation_query(resource_name:, token:, redirect_url:)
6-
name = "#{resource_name.underscore.tr('/', '_').camelize(:lower)}ConfirmAccount"
6+
name = "#{GraphqlDevise.to_mapping_name(resource_name).camelize(:lower)}ConfirmAccount"
77
raw = <<-GRAPHQL
88
query($token:String!,$redirectUrl:String!){
99
#{name}(confirmationToken:$token,redirectUrl:$redirectUrl){
@@ -19,7 +19,7 @@ def confirmation_query(resource_name:, token:, redirect_url:)
1919
end
2020

2121
def password_reset_query(token:, redirect_url:, resource_name:)
22-
name = "#{resource_name.underscore.tr('/', '_').camelize(:lower)}CheckPasswordToken"
22+
name = "#{GraphqlDevise.to_mapping_name(resource_name).camelize(:lower)}CheckPasswordToken"
2323
raw = <<-GRAPHQL
2424
query($token:String!,$redirectUrl:String!){
2525
#{name}(resetPasswordToken:$token,redirectUrl:$redirectUrl){
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

app/models/graphql_devise/concerns/model.rb

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,14 @@
44

55
module GraphqlDevise
66
module Concerns
7-
Model = DeviseTokenAuth::Concerns::User
7+
module Model
8+
extend ActiveSupport::Concern
89

9-
Model.module_eval do
10-
class_methods do
11-
def reconfirmable
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
1513

16-
def update_with_email(attributes = {})
17-
GraphqlDevise::Model::WithEmailUpdater.new(self, attributes).call
14+
GraphqlDevise.configure_warden_serializer_for_model(self)
1815
end
1916
end
2017
end

lib/graphql_devise.rb

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,36 @@ def self.load_schema
2020
@schema_loaded = true
2121
end
2222

23-
def self.resource_mounted?(mapping_name)
24-
@mounted_resources.include?(mapping_name)
23+
def self.resource_mounted?(model)
24+
@mounted_resources.include?(model)
2525
end
2626

27-
def self.mount_resource(mapping_name)
28-
@mounted_resources << mapping_name
27+
def self.mount_resource(model)
28+
@mounted_resources << model
2929
end
3030

3131
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)
3333

3434
Devise.add_mapping(
3535
mapping_name.to_s.pluralize.to_sym,
3636
module: :devise, class_name: resource
3737
)
3838
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
3953
end
4054

4155
require 'graphql_devise/engine'

lib/graphql_devise/concerns/controller_methods.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,11 @@ def controller
4040
end
4141

4242
def resource_name
43-
self.class.instance_variable_get(:@resource_name)
43+
GraphqlDevise.to_mapping_name(resource_class)
4444
end
4545

4646
def resource_class
47-
controller.send(:resource_class, resource_name)
47+
self.class.instance_variable_get(:@resource_klass)
4848
end
4949

5050
def recoverable_enabled?
@@ -60,7 +60,7 @@ def blacklisted_redirect_url?(redirect_url)
6060
end
6161

6262
def current_resource
63-
@current_resource ||= controller.send(:set_user_by_token, resource_name)
63+
@current_resource ||= controller.send(:set_resource_by_token, resource_class)
6464
end
6565

6666
def client

lib/graphql_devise/mount_method/operation_preparer.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@
33
require_relative 'operation_preparers/gql_name_setter'
44
require_relative 'operation_preparers/mutation_field_setter'
55
require_relative 'operation_preparers/resolver_type_setter'
6-
require_relative 'operation_preparers/resource_name_setter'
6+
require_relative 'operation_preparers/resource_klass_setter'
77
require_relative 'operation_preparers/default_operation_preparer'
88
require_relative 'operation_preparers/custom_operation_preparer'
99

1010
module GraphqlDevise
1111
module MountMethod
1212
class OperationPreparer
13-
def initialize(mapping_name:, selected_operations:, preparer:, custom:, additional_operations:)
13+
def initialize(model:, selected_operations:, preparer:, custom:, additional_operations:)
1414
@selected_operations = selected_operations
1515
@preparer = preparer
16-
@mapping_name = mapping_name
16+
@model = model
1717
@custom = custom
1818
@additional_operations = additional_operations
1919
end
@@ -22,18 +22,18 @@ def call
2222
default_operations = OperationPreparers::DefaultOperationPreparer.new(
2323
selected_operations: @selected_operations,
2424
custom_keys: @custom.keys,
25-
mapping_name: @mapping_name,
25+
model: @model,
2626
preparer: @preparer
2727
).call
2828

2929
custom_operations = OperationPreparers::CustomOperationPreparer.new(
3030
selected_keys: @selected_operations.keys,
3131
custom_operations: @custom,
32-
mapping_name: @mapping_name
32+
model: @model
3333
).call
3434

3535
additional_operations = @additional_operations.each_with_object({}) do |(action, operation), result|
36-
result[action] = OperationPreparers::ResourceNameSetter.new(@mapping_name).call(operation)
36+
result[action] = OperationPreparers::ResourceKlassSetter.new(@model).call(operation)
3737
end
3838

3939
default_operations.merge(custom_operations).merge(additional_operations)

lib/graphql_devise/mount_method/operation_preparers/custom_operation_preparer.rb

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,21 @@ module GraphqlDevise
44
module MountMethod
55
module OperationPreparers
66
class CustomOperationPreparer
7-
def initialize(selected_keys:, custom_operations:, mapping_name:)
7+
def initialize(selected_keys:, custom_operations:, model:)
88
@selected_keys = selected_keys
99
@custom_operations = custom_operations
10-
@mapping_name = mapping_name
10+
@model = model
1111
end
1212

1313
def call
14+
mapping_name = GraphqlDevise.to_mapping_name(@model)
15+
1416
@custom_operations.slice(*@selected_keys).each_with_object({}) do |(action, operation), result|
15-
mapped_action = "#{@mapping_name}_#{action}"
17+
mapped_action = "#{mapping_name}_#{action}"
1618

1719
result[mapped_action.to_sym] = [
1820
OperationPreparers::GqlNameSetter.new(mapped_action),
19-
OperationPreparers::ResourceNameSetter.new(@mapping_name)
21+
OperationPreparers::ResourceKlassSetter.new(@model)
2022
].reduce(operation) { |prepared_operation, preparer| preparer.call(prepared_operation) }
2123
end
2224
end

lib/graphql_devise/mount_method/operation_preparers/default_operation_preparer.rb

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,25 @@ module GraphqlDevise
44
module MountMethod
55
module OperationPreparers
66
class DefaultOperationPreparer
7-
def initialize(selected_operations:, custom_keys:, mapping_name:, preparer:)
7+
def initialize(selected_operations:, custom_keys:, model:, preparer:)
88
@selected_operations = selected_operations
99
@custom_keys = custom_keys
10-
@mapping_name = mapping_name
10+
@model = model
1111
@preparer = preparer
1212
end
1313

1414
def call
15+
mapping_name = GraphqlDevise.to_mapping_name(@model)
16+
1517
@selected_operations.except(*@custom_keys).each_with_object({}) do |(action, operation_info), result|
16-
mapped_action = "#{@mapping_name}_#{action}"
18+
mapped_action = "#{mapping_name}_#{action}"
1719
operation = operation_info[:klass]
1820
options = operation_info.except(:klass)
1921

2022
result[mapped_action.to_sym] = [
2123
OperationPreparers::GqlNameSetter.new(mapped_action),
2224
@preparer,
23-
OperationPreparers::ResourceNameSetter.new(@mapping_name)
25+
OperationPreparers::ResourceKlassSetter.new(@model)
2426
].reduce(child_class(operation)) do |prepared_operation, preparer|
2527
preparer.call(prepared_operation, **options)
2628
end

0 commit comments

Comments
 (0)