debian-mirror-gitlab/app/services/jira/requests/base.rb

133 lines
5.4 KiB
Ruby
Raw Normal View History

2020-06-23 00:09:42 +05:30
# frozen_string_literal: true
module Jira
module Requests
class Base
2020-07-28 23:09:34 +05:30
JIRA_API_VERSION = 2
2021-10-27 15:23:28 +05:30
# Limit the size of the JSON error message we will attempt to parse, as the JSON is external input.
JIRA_ERROR_JSON_SIZE_LIMIT = 5_000
ERRORS = {
connection: [Errno::ECONNRESET, Errno::ECONNREFUSED],
2022-08-27 11:52:29 +05:30
jira_ruby: JIRA::HTTPError,
ssl: OpenSSL::SSL::SSLError,
timeout: [Timeout::Error, Errno::ETIMEDOUT],
uri: [URI::InvalidURIError, SocketError]
2021-10-27 15:23:28 +05:30
}.freeze
ALL_ERRORS = ERRORS.values.flatten.freeze
2020-06-23 00:09:42 +05:30
2021-09-30 23:02:18 +05:30
def initialize(jira_integration, params = {})
@project = jira_integration&.project
@jira_integration = jira_integration
2020-06-23 00:09:42 +05:30
end
def execute
2021-09-30 23:02:18 +05:30
return ServiceResponse.error(message: _('Jira service not configured.')) unless jira_integration&.active?
2020-06-23 00:09:42 +05:30
request
end
2021-03-11 19:13:27 +05:30
private
2021-09-30 23:02:18 +05:30
attr_reader :jira_integration, :project
2021-03-11 19:13:27 +05:30
2021-02-22 17:27:13 +05:30
# We have to add the context_path here because the Jira client is not taking it into account
2020-07-28 23:09:34 +05:30
def base_api_url
2021-02-22 17:27:13 +05:30
"#{context_path}/rest/api/#{api_version}"
2020-07-28 23:09:34 +05:30
end
2021-02-22 17:27:13 +05:30
def context_path
client.options[:context_path].to_s
end
2020-07-28 23:09:34 +05:30
# override this method in the specific request class implementation if a differnt API version is required
def api_version
JIRA_API_VERSION
end
2020-06-23 00:09:42 +05:30
def client
2021-09-30 23:02:18 +05:30
@client ||= jira_integration.client
2020-06-23 00:09:42 +05:30
end
def request
response = client.get(url)
build_service_response(response)
2022-07-16 23:28:13 +05:30
rescue *ALL_ERRORS => error
jira_integration.log_exception(error,
message: 'Error sending message',
client_url: client.options[:site]
2021-10-27 15:23:28 +05:30
)
2022-07-16 23:28:13 +05:30
ServiceResponse.error(message: error_message(error))
2021-10-27 15:23:28 +05:30
end
2021-12-11 22:18:48 +05:30
def auth_docs_link_start
2022-06-21 17:19:12 +05:30
auth_docs_link_url = Rails.application.routes.url_helpers.help_page_path('integration/jira/index', anchor: 'authentication-in-jira')
2021-12-11 22:18:48 +05:30
'<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: auth_docs_link_url }
end
def config_docs_link_start
config_docs_link_url = Rails.application.routes.url_helpers.help_page_path('integration/jira/configure')
'<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: config_docs_link_url }
end
2021-10-27 15:23:28 +05:30
def error_message(error)
reportable_error_message(error) ||
2021-12-11 22:18:48 +05:30
s_('JiraRequest|An error occurred while requesting data from Jira. Check your %{docs_link_start}Jira integration configuration%{docs_link_end} and try again.').html_safe % { docs_link_start: config_docs_link_start, docs_link_end: '</a>'.html_safe }
2021-10-27 15:23:28 +05:30
end
# Returns a user-facing error message if possible, otherwise `nil`.
def reportable_error_message(error)
case error
when ERRORS[:jira_ruby]
reportable_jira_ruby_error_message(error)
when ERRORS[:ssl]
s_('JiraRequest|An SSL error occurred while connecting to Jira: %{message}. Try your request again.') % { message: error.message }
when *ERRORS[:uri]
s_('JiraRequest|The Jira API URL for connecting to Jira is not valid. Check your Jira integration API URL and try again.')
when *ERRORS[:timeout]
s_('JiraRequest|A timeout error occurred while connecting to Jira. Try your request again.')
when *ERRORS[:connection]
s_('JiraRequest|A connection error occurred while connecting to Jira. Try your request again.')
end
end
# Returns a user-facing error message for a `JIRA::HTTPError` if possible,
# otherwise `nil`.
def reportable_jira_ruby_error_message(error)
case error.message
when 'Unauthorized'
2021-12-11 22:18:48 +05:30
s_('JiraRequest|The credentials for accessing Jira are not valid. Check your %{docs_link_start}Jira integration credentials%{docs_link_end} and try again.').html_safe % { docs_link_start: auth_docs_link_start, docs_link_end: '</a>'.html_safe }
2021-10-27 15:23:28 +05:30
when 'Forbidden'
2021-12-11 22:18:48 +05:30
s_('JiraRequest|The credentials for accessing Jira are not allowed to access the data. Check your %{docs_link_start}Jira integration credentials%{docs_link_end} and try again.').html_safe % { docs_link_start: auth_docs_link_start, docs_link_end: '</a>'.html_safe }
2021-10-27 15:23:28 +05:30
when 'Bad Request'
2021-12-11 22:18:48 +05:30
s_('JiraRequest|An error occurred while requesting data from Jira. Check your %{docs_link_start}Jira integration configuration%{docs_link_end} and try again.').html_safe % { docs_link_start: config_docs_link_start, docs_link_end: '</a>'.html_safe }
2021-10-27 15:23:28 +05:30
when /errorMessages/
jira_ruby_json_error_message(error.message)
end
end
def jira_ruby_json_error_message(error_message)
return if error_message.length > JIRA_ERROR_JSON_SIZE_LIMIT
begin
messages = Gitlab::Json.parse(error_message)['errorMessages']&.to_sentence
messages = Rails::Html::FullSanitizer.new.sanitize(messages).presence
return unless messages
2021-12-11 22:18:48 +05:30
s_('JiraRequest|An error occurred while requesting data from Jira: %{messages}. Check your %{docs_link_start}Jira integration configuration%{docs_link_end} and try again.').html_safe % { messages: messages, docs_link_start: config_docs_link_start, docs_link_end: '</a>'.html_safe }
2021-10-27 15:23:28 +05:30
rescue JSON::ParserError
end
2020-06-23 00:09:42 +05:30
end
def url
raise NotImplementedError
end
def build_service_response(response)
raise NotImplementedError
end
end
end
end