mirror of
https://github.com/gitlabhq/gitlabhq.git
synced 2025-07-25 16:00:50 +00:00
177 lines
6.2 KiB
Ruby
177 lines
6.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module API
|
|
class Integrations
|
|
class IntegratableOperations < Grape::API # rubocop:disable API/Base -- subclassing from Grape::API is required for mounting in the main API.
|
|
INTEGRATIONS_TAGS = %w[integrations].freeze
|
|
|
|
before do
|
|
render_api_error!('400 Integration not available', 400) if disallowed_integration_at_group_level?(params[:slug])
|
|
end
|
|
|
|
mounted do
|
|
helpers do
|
|
def disallowed_integration_at_group_level?(slug)
|
|
return unless slug.present?
|
|
|
|
parent_resource.is_a?(Group) && Integration.project_specific_integration_names.include?(slug.underscore)
|
|
end
|
|
|
|
def integration_attributes(integration)
|
|
integration.fields.inject([]) do |arr, hash|
|
|
arr << hash[:name].to_sym
|
|
end
|
|
end
|
|
|
|
def find_or_initialize_integration(slug)
|
|
parent_resource.find_or_initialize_integration(slug.underscore)
|
|
end
|
|
|
|
def parent_resource
|
|
unless respond_to?(:fetch_parent_resource, true)
|
|
raise NotImplementedError,
|
|
"You must implement a `fetch_parent_resource` method that returns " \
|
|
"the integratable resource in the namespace that mounts this API."
|
|
end
|
|
|
|
@parent_resource ||= fetch_parent_resource
|
|
end
|
|
end
|
|
|
|
desc 'List all active integrations' do
|
|
detail "Get a list of all active integrations."
|
|
success Entities::IntegrationBasic
|
|
failure [
|
|
{ code: 401, message: 'Unauthorized' },
|
|
{ code: 404, message: 'Not found' }
|
|
]
|
|
is_array true
|
|
tags INTEGRATIONS_TAGS
|
|
end
|
|
|
|
get(configuration[:path]) do
|
|
integrations = parent_resource.integrations.active
|
|
|
|
present integrations, with: Entities::IntegrationBasic
|
|
end
|
|
|
|
INTEGRATIONS.each do |slug, settings|
|
|
desc "Create/Edit #{slug.titleize} integration" do
|
|
detail "Set #{slug.titleize} integration."
|
|
success Entities::IntegrationBasic
|
|
failure [
|
|
{ code: 400, message: 'Bad request' },
|
|
{ code: 401, message: 'Unauthorized' },
|
|
{ code: 404, message: 'Not found' },
|
|
{ code: 422, message: 'Unprocessable entity' }
|
|
]
|
|
tags INTEGRATIONS_TAGS
|
|
end
|
|
params do
|
|
settings.each do |setting|
|
|
if setting[:required]
|
|
requires setting[:name], type: setting[:type], desc: setting[:desc]
|
|
else
|
|
optional setting[:name], type: setting[:type], desc: setting[:desc]
|
|
end
|
|
end
|
|
end
|
|
put("#{configuration[:path]}/#{slug}") do
|
|
integration = find_or_initialize_integration(slug)
|
|
|
|
params = declared_params(include_missing: false).merge(active: true)
|
|
|
|
render_api_error!('400 Integration not available', 400) if integration.nil?
|
|
|
|
manual_or_special = integration.manual_activation? || integration.is_a?(::Integrations::Prometheus)
|
|
|
|
unless manual_or_special
|
|
if integration.new_record?
|
|
render_api_error!("You cannot create the #{integration.class.title} integration from the API", 422)
|
|
end
|
|
|
|
params.delete(:active)
|
|
end
|
|
|
|
result = ::Integrations::UpdateService.new(
|
|
current_user: current_user, integration: integration, attributes: params
|
|
).execute
|
|
|
|
if result.success?
|
|
present integration, with: Entities::Integration
|
|
else
|
|
message = result.message || '400 Bad Request'
|
|
render_api_error!(message, 400)
|
|
end
|
|
end
|
|
end
|
|
|
|
desc "Disable an integration" do
|
|
detail "Disable the integration. Integration settings are preserved."
|
|
success code: 204
|
|
failure [
|
|
{ code: 400, message: 'Bad request' },
|
|
{ code: 401, message: 'Unauthorized' },
|
|
{ code: 404, message: 'Not found' }
|
|
]
|
|
tags INTEGRATIONS_TAGS
|
|
end
|
|
params do
|
|
requires :slug, type: String, values: INTEGRATIONS.keys,
|
|
desc: 'The name of the integration'
|
|
end
|
|
delete("#{configuration[:path]}/:slug") do
|
|
integration = find_or_initialize_integration(params[:slug])
|
|
|
|
not_found!('Integration') unless integration&.persisted?
|
|
|
|
if integration.is_a?(::Integrations::JiraCloudApp)
|
|
render_api_error!("You cannot disable the #{integration.class.title} integration from the API", 422)
|
|
end
|
|
|
|
destroy_conditionally!(integration) do
|
|
attrs = integration_attributes(integration).index_with do |attr|
|
|
column = if integration.attribute_present?(attr)
|
|
integration.column_for_attribute(attr)
|
|
elsif integration.data_fields_present?
|
|
integration.data_fields.column_for_attribute(attr)
|
|
end
|
|
|
|
case column
|
|
when nil, ActiveRecord::ConnectionAdapters::NullColumn
|
|
nil
|
|
else
|
|
column.default
|
|
end
|
|
end.merge(active: false)
|
|
|
|
render_api_error!('400 Bad Request', 400) unless integration.update(attrs)
|
|
end
|
|
end
|
|
|
|
desc "Get an integration settings" do
|
|
detail "Get the integration settings."
|
|
success Entities::Integration
|
|
failure [
|
|
{ code: 400, message: 'Bad request' },
|
|
{ code: 401, message: 'Unauthorized' },
|
|
{ code: 404, message: 'Not found' }
|
|
]
|
|
tags INTEGRATIONS_TAGS
|
|
end
|
|
params do
|
|
requires :slug, type: String, values: INTEGRATIONS.keys,
|
|
desc: 'The name of the integration'
|
|
end
|
|
get("#{configuration[:path]}/:slug") do
|
|
integration = find_or_initialize_integration(params[:slug])
|
|
|
|
not_found!('Integration') unless integration&.persisted?
|
|
|
|
present integration, with: Entities::Integration
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|