diff options
Diffstat (limited to 'app/controllers/graphql_controller.rb')
-rw-r--r-- | app/controllers/graphql_controller.rb | 61 |
1 files changed, 53 insertions, 8 deletions
diff --git a/app/controllers/graphql_controller.rb b/app/controllers/graphql_controller.rb index 3ef03bc9622..1ce0afac83b 100644 --- a/app/controllers/graphql_controller.rb +++ b/app/controllers/graphql_controller.rb @@ -3,18 +3,21 @@ class GraphqlController < ApplicationController # Unauthenticated users have access to the API for public data skip_before_action :authenticate_user! - prepend_before_action(only: [:execute]) { authenticate_sessionless_user!(:api) } + + # Allow missing CSRF tokens, this would mean that if a CSRF is invalid or missing, + # the user won't be authenticated but can proceed as an anonymous user. + # + # If a CSRF is valid, the user is authenticated. This makes it easier to play + # around in GraphiQL. + protect_from_forgery with: :null_session, only: :execute before_action :check_graphql_feature_flag! + before_action :authorize_access_api! + before_action(only: [:execute]) { authenticate_sessionless_user!(:api) } def execute - variables = Gitlab::Graphql::Variables.new(params[:variables]).to_h - query = params[:query] - operation_name = params[:operationName] - context = { - current_user: current_user - } - result = GitlabSchema.execute(query, variables: variables, context: context, operation_name: operation_name) + result = multiplex? ? execute_multiplex : execute_query + render json: result end @@ -30,6 +33,48 @@ class GraphqlController < ApplicationController private + def execute_multiplex + GitlabSchema.multiplex(multiplex_queries, context: context) + end + + def execute_query + variables = build_variables(params[:variables]) + operation_name = params[:operationName] + + GitlabSchema.execute(query, variables: variables, context: context, operation_name: operation_name) + end + + def query + params[:query] + end + + def multiplex_queries + params[:_json].map do |single_query_info| + { + query: single_query_info[:query], + variables: build_variables(single_query_info[:variables]), + operation_name: single_query_info[:operationName], + context: context + } + end + end + + def context + @context ||= { current_user: current_user } + end + + def build_variables(variable_info) + Gitlab::Graphql::Variables.new(variable_info).to_h + end + + def multiplex? + params[:_json].present? + end + + def authorize_access_api! + access_denied!("API not accessible for user.") unless can?(current_user, :access_api) + end + # Overridden from the ApplicationController to make the response look like # a GraphQL response. That is nicely picked up in Graphiql. def render_404 |