2018-09-14 01:42:05 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2017-08-16 09:04:41 -04:00
|
|
|
class GraphqlController < ApplicationController
|
|
|
|
# Unauthenticated users have access to the API for public data
|
|
|
|
skip_before_action :authenticate_user!
|
2019-03-03 07:53:03 -05:00
|
|
|
|
|
|
|
# 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
|
2017-08-16 09:04:41 -04:00
|
|
|
|
|
|
|
before_action :check_graphql_feature_flag!
|
2019-03-27 10:59:02 -04:00
|
|
|
before_action :authorize_access_api!
|
2019-03-03 07:53:03 -05:00
|
|
|
before_action(only: [:execute]) { authenticate_sessionless_user!(:api) }
|
2017-08-16 09:04:41 -04:00
|
|
|
|
|
|
|
def execute
|
2018-05-21 07:42:07 -04:00
|
|
|
variables = Gitlab::Graphql::Variables.new(params[:variables]).to_h
|
2017-08-16 09:04:41 -04:00
|
|
|
query = params[:query]
|
|
|
|
operation_name = params[:operationName]
|
|
|
|
context = {
|
|
|
|
current_user: current_user
|
|
|
|
}
|
|
|
|
result = GitlabSchema.execute(query, variables: variables, context: context, operation_name: operation_name)
|
|
|
|
render json: result
|
|
|
|
end
|
|
|
|
|
2018-05-21 07:42:07 -04:00
|
|
|
rescue_from StandardError do |exception|
|
|
|
|
log_exception(exception)
|
|
|
|
|
|
|
|
render_error("Internal server error")
|
|
|
|
end
|
|
|
|
|
|
|
|
rescue_from Gitlab::Graphql::Variables::Invalid do |exception|
|
|
|
|
render_error(exception.message, status: :unprocessable_entity)
|
|
|
|
end
|
|
|
|
|
2017-08-16 09:04:41 -04:00
|
|
|
private
|
|
|
|
|
2019-03-27 10:59:02 -04:00
|
|
|
def authorize_access_api!
|
|
|
|
access_denied!("API not accessible for user.") unless can?(current_user, :access_api)
|
|
|
|
end
|
|
|
|
|
2017-08-16 09:04:41 -04:00
|
|
|
# Overridden from the ApplicationController to make the response look like
|
|
|
|
# a GraphQL response. That is nicely picked up in Graphiql.
|
|
|
|
def render_404
|
2018-05-21 07:42:07 -04:00
|
|
|
render_error("Not found!", status: :not_found)
|
|
|
|
end
|
|
|
|
|
|
|
|
def render_error(message, status: 500)
|
|
|
|
error = { errors: [message: message] }
|
2017-08-16 09:04:41 -04:00
|
|
|
|
2018-05-21 07:42:07 -04:00
|
|
|
render json: error, status: status
|
2017-08-16 09:04:41 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def check_graphql_feature_flag!
|
2018-12-13 05:12:13 -05:00
|
|
|
render_404 unless Gitlab::Graphql.enabled?
|
2017-08-16 09:04:41 -04:00
|
|
|
end
|
|
|
|
end
|