Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ Rails.application.routes.draw do
login: Mutations::Login
},
skip: [:register],
# base_controller: ApiController,
additional_mutations: {
# generates mutation { adminUserSignUp }
admin_user_sign_up: Mutations::AdminUserSignUp
Expand Down Expand Up @@ -264,6 +265,7 @@ our default classes and yielding your customized code after calling `super`, exa
and an `authenticatable` type to every query. Gem will try to use `Types::<model>Type` by
default, so in our example you could define `Types::UserType` and every query and mutation
will use it. But, you can override this type with this option like in the example.
1. `base_controller`: Specifying this is optional. By default the controller used to mount the route is `GraphqlDevise::ApplicationController` which inherits from `ActionController::API` or `ActionController::Base` depending on the rails version of the main project. This option allows you to set the controller used as the parent of the controller where the route will be mounted. This config is similar to `Devise`'s `base_controller` config but in this case each route can have a different parent controller.
1. `skip`: An array of the operations that should not be available in the authentication schema. All these operations are
symbols and should belong to the list of available operations in the gem.
1. `only`: An array of the operations that should be available in the authentication schema. The `skip` and `only` options are
Expand Down
44 changes: 1 addition & 43 deletions app/controllers/graphql_devise/graphql_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,48 +5,6 @@
module GraphqlDevise
class GraphqlController < ApplicationController
include SetUserByToken

def auth
result = if params[:_json]
Schema.multiplex(
params[:_json].map do |param|
{ query: param[:query] }.merge(execute_params(param))
end
)
else
Schema.execute(params[:query], **execute_params(params))
end

render json: result unless performed?
end

attr_accessor :client_id, :token, :resource

private

def execute_params(item)
{
operation_name: item[:operationName],
variables: ensure_hash(item[:variables]),
context: { controller: self }
}
end

def ensure_hash(ambiguous_param)
case ambiguous_param
when String
if ambiguous_param.present?
ensure_hash(JSON.parse(ambiguous_param))
else
{}
end
when Hash, ActionController::Parameters
ambiguous_param
when nil
{}
else
raise ArgumentError, "Unexpected parameter: #{ambiguous_param}"
end
end
include AuthControllerMethods
end
end
50 changes: 50 additions & 0 deletions lib/graphql_devise/concerns/auth_controller_methods.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# frozen_string_literal: true

module GraphqlDevise
module AuthControllerMethods
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WDYT about renaming this one to AuthControllerActions?

extend ActiveSupport::Concern

def auth
result = if params[:_json]
Schema.multiplex(
params[:_json].map do |param|
{ query: param[:query] }.merge(execute_params(param))
end
)
else
Schema.execute(params[:query], **execute_params(params))
end

render json: result unless performed?
end

attr_accessor :client_id, :token, :resource

private

def execute_params(item)
{
operation_name: item[:operationName],
variables: ensure_hash(item[:variables]),
context: { controller: self }
}
end

def ensure_hash(ambiguous_param)
case ambiguous_param
when String
if ambiguous_param.present?
ensure_hash(JSON.parse(ambiguous_param))
else
{}
end
when Hash, ActionController::Parameters
ambiguous_param
when nil
{}
else
raise ArgumentError, "Unexpected parameter: #{ambiguous_param}"
end
end
end
end
14 changes: 12 additions & 2 deletions lib/graphql_devise/route_mounter.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
module GraphqlDevise
module RouteMounter
def mount_graphql_devise_for(resource, options = {})
routing = 'graphql_devise/graphql#auth'

if (base_controller = options.delete(:base_controller))
new_controller = GraphqlDevise.const_set("#{resource}AuthController", Class.new(base_controller))
new_controller.include(SetUserByToken)
new_controller.include(AuthControllerMethods)

routing = "#{new_controller.to_s.underscore.gsub('_controller','')}#auth"
end

clean_options = ResourceLoader.new(resource, options, true).call(
Types::QueryType,
Types::MutationType
)

post clean_options.at, to: 'graphql_devise/graphql#auth'
get clean_options.at, to: 'graphql_devise/graphql#auth'
post clean_options.at, to: routing
get clean_options.at, to: routing
end
end
end
7 changes: 7 additions & 0 deletions spec/dummy/app/controllers/cookies_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

class CookiesController < ApplicationController
include ActionController::Cookies
protect_from_forgery with: :null_session
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WDYT about doing what we did in

instead of setting a null session here? That way we could probably test that the correct cookie is set after login and other mutations

end

16 changes: 8 additions & 8 deletions spec/dummy/config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# frozen_string_literal: true

Rails.application.routes.draw do
mount_graphql_devise_for User, at: '/api/v1/graphql_auth', operations: {
login: Mutations::Login,
register: Mutations::Register
}, additional_mutations: {
register_confirmed_user: Mutations::RegisterConfirmedUser
}, additional_queries: {
public_user: Resolvers::PublicUser
}
mount_graphql_devise_for(
User,
at: '/api/v1/graphql_auth',
base_controller: CookiesController,
operations: { login: Mutations::Login, register: Mutations::Register },
additional_mutations: { register_confirmed_user: Mutations::RegisterConfirmedUser },
additional_queries: { public_user: Resolvers::PublicUser }
)

mount_graphql_devise_for(
Admin,
Expand Down