-
Notifications
You must be signed in to change notification settings - Fork 993
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fixes #23678 - add graphql scaffolding
- Loading branch information
1 parent
4d85cea
commit d1e1858
Showing
24 changed files
with
503 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
module Api | ||
class GraphqlController < ActionController::Base | ||
include Foreman::ThreadSession::Cleaner | ||
include Foreman::Controller::Timezone | ||
include Foreman::Controller::RequireSsl | ||
include Foreman::Controller::Session | ||
include Foreman::Controller::Authentication | ||
|
||
rescue_from Exception, :with => :generic_exception if Rails.env.production? | ||
|
||
before_action :authenticate | ||
around_action :set_timezone | ||
|
||
def execute | ||
result = if params[:_json] | ||
execute_multiplexed_graphql_query | ||
else | ||
execute_single_graphql_query | ||
end | ||
|
||
render json: result | ||
end | ||
|
||
def api_request? | ||
true | ||
end | ||
|
||
private | ||
|
||
def execute_multiplexed_graphql_query | ||
current_user = User.current | ||
queries = params[:_json].map do |param| | ||
{ | ||
query: param['query'], | ||
operation_name: param['operationName'], | ||
variables: ensure_hash(param['variables']), | ||
context: { | ||
current_user: current_user, | ||
request_id: request.uuid | ||
} | ||
} | ||
end | ||
ForemanGraphqlSchema.multiplex(queries) | ||
end | ||
|
||
def execute_single_graphql_query | ||
ForemanGraphqlSchema.execute( | ||
params[:query], | ||
variables: variables, | ||
context: { | ||
current_user: User.current, | ||
request_id: request.uuid | ||
} | ||
) | ||
end | ||
|
||
def variables | ||
ensure_hash(params[:variables]) | ||
end | ||
|
||
def ensure_hash(ambiguous_param) | ||
case ambiguous_param | ||
when String | ||
if ambiguous_param.present? | ||
ensure_hash(JSON.parse(ambiguous_param)) | ||
else | ||
{} | ||
end | ||
when ActionController::Parameters | ||
ambiguous_param.to_unsafe_h | ||
when Hash | ||
ambiguous_param | ||
when nil | ||
{} | ||
else | ||
raise ArgumentError, "Unexpected parameter: #{ambiguous_param}" | ||
end | ||
rescue JSON::ParserError | ||
raise ArgumentError, "Could not parse JSON data in #{ambiguous_param}" | ||
end | ||
|
||
def generic_exception(exception) | ||
Foreman::Logging.exception('Action failed', exception) | ||
render json: "{ 'error': 500 }", :status => :internal_server_error | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -85,7 +85,6 @@ def set_current_user(user) | |
session[:user] = user.id | ||
update_activity_time | ||
end | ||
set_taxonomy | ||
user.present? | ||
end | ||
end |
17 changes: 17 additions & 0 deletions
17
app/controllers/concerns/foreman/controller/require_ssl.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
module Foreman | ||
module Controller | ||
module RequireSsl | ||
extend ActiveSupport::Concern | ||
|
||
included do | ||
force_ssl :if => :require_ssl? | ||
end | ||
|
||
protected | ||
|
||
def require_ssl? | ||
SETTINGS[:require_ssl] | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
module Foreman | ||
module Controller | ||
module Timezone | ||
extend ActiveSupport::Concern | ||
|
||
def set_timezone | ||
default_timezone = Time.zone | ||
client_timezone = User.current.try(:timezone) || cookies[:timezone] | ||
Time.zone = client_timezone if client_timezone.present? | ||
yield | ||
ensure | ||
# Reset timezone for the next thread | ||
Time.zone = default_timezone | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
class ForemanGraphqlSchema < GraphQL::Schema | ||
# Set up the graphql-batch gem | ||
lazy_resolve(Promise, :sync) | ||
use GraphQL::Batch | ||
|
||
query(Types::Query) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
module Queries | ||
class AuthorizedModelQuery | ||
def initialize(model_class:, user:) | ||
@model_class = model_class | ||
@user = user | ||
end | ||
|
||
delegate :find_by, to: :authorized_scope | ||
|
||
def results(params = {}) | ||
if params[:search].present? | ||
authorized_scope.search_for(*search_options(params)) | ||
elsif params[:orderField].present? | ||
ordered_results(order_field: params[:orderField], order_direction: params[:orderDirection]) | ||
else | ||
authorized_scope.all | ||
end | ||
end | ||
|
||
private | ||
|
||
attr_reader :model_class, :user | ||
|
||
def authorized_scope | ||
return model_class unless model_class.respond_to?(:authorized) | ||
|
||
permission = model_class.find_permission_name(:view) | ||
model_class.authorized_as(user, permission, model_class) | ||
end | ||
|
||
def search_options(params) | ||
search_options = [params[:search]] | ||
if params[:orderField].present? | ||
search_options << { :order => "#{params[:orderField]} #{params[:orderDirection]}".strip } | ||
end | ||
search_options | ||
end | ||
|
||
def ordered_results(order_field:, order_direction:) | ||
order_direction = order_direction.presence || :ASC | ||
authorized_scope.order(order_field => order_direction).all | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
module Queries | ||
class FetchField < GraphQL::Function | ||
attr_reader :type | ||
|
||
argument(:id, !types.Int, 'ID for Record') | ||
|
||
def initialize(model_class:, type:) | ||
@model_class = model_class | ||
@type = type | ||
end | ||
|
||
def call(_, args, ctx) | ||
Queries::AuthorizedModelQuery.new(model_class: @model_class, user: ctx[:current_user]) | ||
.find_by(id: args['id']) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
module Queries | ||
class PluralField < GraphQL::Function | ||
attr_reader :type | ||
|
||
argument(:search, types.String, 'Search query') | ||
argument(:orderField, types.String, 'Order field') | ||
argument(:orderDirection, types.String, 'Order direction') | ||
|
||
def initialize(model_class:, type:) | ||
@model_class = model_class | ||
@type = type | ||
end | ||
|
||
def call(_, args, ctx) | ||
params = args.to_h.slice('search', 'orderField', 'orderDirection').symbolize_keys | ||
Queries::AuthorizedModelQuery.new(model_class: @model_class, user: ctx[:current_user]) | ||
.results(params) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
module Types | ||
class BaseObject < GraphQL::Types::Relay::BaseObject | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
module Types | ||
class Model < BaseObject | ||
description 'A Model' | ||
|
||
field :id, Integer, null: false | ||
field :name, String, null: false | ||
field :info, String, null: true | ||
field :vendorClass, String, null: true | ||
field :hardwareModel, String, null: true | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
module Types | ||
class Query < GraphQL::Schema::Object | ||
graphql_name 'Query' | ||
|
||
field :model, Types::Model, | ||
function: Queries::FetchField.new(type: Types::Model, model_class: ::Model), null: true | ||
|
||
field :models, Types::Model.connection_type, connection: true, | ||
function: Queries::PluralField.new(type: Types::Model, model_class: ::Model) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
require 'graphql' | ||
require 'graphql/batch' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Foreman::Application.routes.draw do | ||
namespace :api, defaults: {format: 'json'} do | ||
post '/graphql', to: 'graphql#execute' | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
require 'test_helper' | ||
|
||
class Api::GraphqlControllerTest < ActionController::TestCase | ||
test 'empty query' do | ||
post :execute, params: {} | ||
|
||
assert_response :success | ||
refute_empty json_errors | ||
assert_includes json_error_messages, 'No query string was present' | ||
end | ||
end |
Oops, something went wrong.