Welcome to mirror list, hosted at ThFree Co, Russian Federation.

integrations_controller.rb « settings « projects « controllers « app - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 2bbcd9fe20c0ae56f0fc59b22ed9686d7fe78ea9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# frozen_string_literal: true

module Projects
  module Settings
    class IntegrationsController < Projects::ApplicationController
      include ::Integrations::Params
      include ::InternalRedirect

      before_action :authorize_admin_project!
      before_action :ensure_integration_enabled, only: [:edit, :update, :test]
      before_action :integration, only: [:edit, :update, :test]
      before_action :default_integration, only: [:edit, :update]
      before_action :web_hook_logs, only: [:edit, :update]
      before_action -> { check_test_rate_limit! }, only: :test

      respond_to :html

      layout "project_settings"

      feature_category :integrations
      urgency :low, [:test]

      def index
        @integrations = @project.find_or_initialize_integrations
      end

      def edit
      end

      def update
        attributes = integration_params[:integration]

        if use_inherited_settings?(attributes)
          integration.inherit_from_id = default_integration.id

          if saved = integration.save(context: :manual_change)
            BulkUpdateIntegrationService.new(default_integration, [integration]).execute
          end
        else
          attributes[:inherit_from_id] = nil
          integration.attributes = attributes
          saved = integration.save(context: :manual_change)
        end

        respond_to do |format|
          format.html do
            if saved
              redirect_to redirect_path, notice: success_message
            else
              render 'edit'
            end
          end

          format.json do
            status = saved ? :ok : :unprocessable_entity

            render json: serialize_as_json, status: status
          end
        end
      end

      def test
        if integration.testable?
          render json: integration_test_response, status: :ok
        else
          render json: {}, status: :not_found
        end
      end

      private

      def redirect_path
        safe_redirect_path(params[:redirect_to]).presence ||
          edit_project_settings_integration_path(project, integration)
      end

      def integration_test_response
        unless integration.update(integration_params[:integration])
          return {
            error: true,
            message: _('Validations failed.'),
            service_response: integration.errors.full_messages.join(','),
            test_failed: false
          }
        end

        result = ::Integrations::Test::ProjectService.new(integration, current_user, params[:event]).execute

        unless result[:success]
          return {
            error: true,
            message: s_('Integrations|Connection failed. Check your integration settings.'),
            service_response: result[:message].to_s,
            test_failed: true
          }
        end

        result[:data].presence || {}
      rescue *Gitlab::HTTP::HTTP_ERRORS => e
        {
          error: true,
          message: s_('Integrations|Connection failed. Check your integration settings.'),
          service_response: e.message,
          test_failed: true
        }
      end

      def success_message
        if integration.active?
          format(s_('Integrations|%{integration} settings saved and active.'), integration: integration.title)
        else
          format(s_('Integrations|%{integration} settings saved, but not active.'), integration: integration.title)
        end
      end

      def integration
        @integration ||= project.find_or_initialize_integration(params[:id])
      end

      def default_integration
        @default_integration ||= Integration.default_integration(integration.type, project)
      end

      def web_hook_logs
        return unless integration.try(:service_hook).present?

        @web_hook_logs ||= integration.service_hook.web_hook_logs.recent.page(params[:page]).without_count
      end

      def ensure_integration_enabled
        render_404 unless integration
      end

      def serialize_as_json
        integration
          .as_json(only: integration.json_fields)
          .merge(errors: integration.errors.as_json)
      end

      def use_inherited_settings?(attributes)
        default_integration && attributes[:inherit_from_id] == default_integration.id.to_s
      end

      def check_test_rate_limit!
        check_rate_limit!(:project_testing_integration, scope: [@project, current_user]) do
          render json: {
            error: true,
            message: _('This endpoint has been requested too many times. Try again later.')
          }, status: :ok
        end
      end
    end
  end
end