apply_otrs_configuration.rb 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. class Service::System::Import::ApplyOtrsConfiguration < Service::System::Import::ApplyConfigurationBase
  3. def execute
  4. sanitize_url
  5. super
  6. parse_url
  7. Setting.set('import_otrs_endpoint', @endpoint)
  8. Setting.set('import_otrs_endpoint_key', @secret)
  9. Setting.set('import_backend', 'otrs')
  10. end
  11. private
  12. def build_endpoint
  13. nil
  14. end
  15. def reachable!
  16. response = request(@url, verify_ssl: @tls_verify)
  17. raise_unreachable_error(response.error) if !response.success?
  18. verify_migrator!(response)
  19. end
  20. def verify_migrator!(response)
  21. begin
  22. migrator = JSON.parse(response.body)
  23. rescue JSON::ParserError
  24. raise_unreachable_error
  25. end
  26. raise_unreachable_error if !migrator.is_a?(Hash)
  27. %w[Notice Success].each do |key|
  28. raise_unreachable_error if !migrator.key?(key)
  29. end
  30. raise_unreachable_error if !migrator['Notice'].start_with?('zammad migrator')
  31. return if migrator['Success'].positive?
  32. message = migrator.fetch('Error', nil)
  33. raise_unreachable_error(message)
  34. end
  35. def sanitize_url
  36. # Replace semicolons with ampersands to allow proper processing of query parameters.
  37. current_url = @url.to_s
  38. @url = Addressable::URI.parse(
  39. CGI.unescape(current_url).split('?').each_with_index.map { |part, i| i.positive? ? part.tr(';', '&') : part }.join('?')
  40. ).normalize.to_s
  41. end
  42. def parse_url
  43. uri = Addressable::URI.parse(@url)
  44. @secret = uri.query_values['Key']
  45. port = uri.port.presence || (uri.scheme == 'https' ? 443 : 80)
  46. @endpoint = "#{uri.scheme}://#{uri.host}:#{port}#{uri.path}?Action=ZammadMigrator"
  47. end
  48. def accessible!
  49. Setting.set('import_otrs_endpoint', @url)
  50. Setting.set('import_otrs_endpoint_key', @secret)
  51. begin
  52. accessible = Import::OTRS.connection_test
  53. rescue
  54. # noop
  55. end
  56. Setting.set('import_otrs_endpoint', nil)
  57. Setting.set('import_otrs_endpoint_key', nil)
  58. raise InaccessibleError, __('The OTRS migrator plugin is not accessable. Please verify the API key.') if !accessible
  59. end
  60. def raise_unreachable_error(message = nil)
  61. raise UnreachableError, __('Please install the OTRS migrator plugin and provide a valid URL.') if message.blank?
  62. messages = {
  63. 'No such file' => __('The hostname could not be found.'),
  64. 'getaddrinfo: nodename nor servname provided, or not known' => __('The hostname could not be found.'),
  65. '503 Service Temporarily Unavailable' => __('The hostname could not be found.'),
  66. 'No route to host' => __('There is no route to this host.'),
  67. 'Connection refused' => __('The connection was refused.'),
  68. }
  69. human_message = messages.find { |key, _| message.match?(%r{#{Regexp.escape(key)}}i) }&.last
  70. raise UnreachableError, human_message.presence || message
  71. end
  72. end