File: project_hooks.rb

package info (click to toggle)
gitlab 17.6.5-19
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 629,368 kB
  • sloc: ruby: 1,915,304; javascript: 557,307; sql: 60,639; xml: 6,509; sh: 4,567; makefile: 1,239; python: 406
file content (167 lines) | stat: -rw-r--r-- 6,399 bytes parent folder | download
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
155
156
157
158
159
160
161
162
163
164
165
166
167
# frozen_string_literal: true

module API
  class ProjectHooks < ::API::Base
    include PaginationParams

    project_hooks_tags = %w[project_hooks]

    before { authenticate! }
    before do
      ability = route.request_method == 'GET' ? :read_web_hook : :admin_web_hook
      authorize! ability, user_project
    end

    feature_category :webhooks

    helpers ::API::Helpers::WebHooksHelpers

    helpers do
      def hook_scope
        user_project.hooks
      end

      params :common_hook_parameters do
        optional :name, type: String, desc: 'Name of the hook'
        optional :description, type: String, desc: 'Description of the hook'
        optional :push_events, type: Boolean, desc: "Trigger hook on push events"
        optional :issues_events, type: Boolean, desc: "Trigger hook on issues events"
        optional :confidential_issues_events, type: Boolean, desc: "Trigger hook on confidential issues events"
        optional :merge_requests_events, type: Boolean, desc: "Trigger hook on merge request events"
        optional :tag_push_events, type: Boolean, desc: "Trigger hook on tag push events"
        optional :note_events, type: Boolean, desc: "Trigger hook on note (comment) events"
        optional :confidential_note_events, type: Boolean, desc: "Trigger hook on confidential note (comment) events"
        optional :job_events, type: Boolean, desc: "Trigger hook on job events"
        optional :pipeline_events, type: Boolean, desc: "Trigger hook on pipeline events"
        optional :wiki_page_events, type: Boolean, desc: "Trigger hook on wiki events"
        optional :deployment_events, type: Boolean, desc: "Trigger hook on deployment events"
        optional :feature_flag_events, type: Boolean, desc: "Trigger hook on feature flag events"
        optional :releases_events, type: Boolean, desc: "Trigger hook on release events"
        optional :emoji_events, type: Boolean, desc: "Trigger hook on emoji events"
        optional :resource_access_token_events, type: Boolean, desc: "Trigger hook on project access token expiry events"
        optional :enable_ssl_verification, type: Boolean, desc: "Do SSL verification when triggering the hook"
        optional :token, type: String, desc: "Secret token to validate received payloads; this will not be returned in the response"
        optional :push_events_branch_filter, type: String, desc: "Trigger hook on specified branch only"
        optional :custom_webhook_template, type: String, desc: "Custom template for the request payload"
        optional :branch_filter_strategy, type: String, values: WebHook.branch_filter_strategies.keys,
          desc: "Filter push events by branch. Possible values are `wildcard` (default), `regex`, and `all_branches`"
        use :url_variables
        use :custom_headers
      end
    end

    params do
      requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
    end
    resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
      namespace ':id/hooks' do
        mount ::API::Hooks::UrlVariables
        mount ::API::Hooks::CustomHeaders
      end

      desc 'List project hooks' do
        detail 'Get a list of project hooks'
        success Entities::ProjectHook
        is_array true
        tags project_hooks_tags
      end
      params do
        use :pagination
      end
      get ":id/hooks" do
        present paginate(user_project.hooks), with: Entities::ProjectHook, with_url_variables: false, with_custom_headers: false
      end

      namespace ":id/hooks/:hook_id/" do
        desc 'Get project hook' do
          detail 'Get a specific hook for a project'
          success Entities::ProjectHook
          failure [
            { code: 404, message: 'Not found' }
          ]
          tags project_hooks_tags
        end
        params do
          requires :hook_id, type: Integer, desc: 'The ID of a project hook'
        end
        get do
          hook = user_project.hooks.find(params[:hook_id])
          present hook, with: Entities::ProjectHook
        end

        desc 'Edit project hook' do
          detail 'Edits a hook for a specified project.'
          success Entities::ProjectHook
          failure [
            { code: 400, message: 'Validation error' },
            { code: 404, message: 'Not found' },
            { code: 422, message: 'Unprocessable entity' }
          ]
          tags project_hooks_tags
        end
        params do
          requires :hook_id, type: Integer, desc: 'The ID of the project hook'
          use :optional_url
          use :common_hook_parameters
        end
        put do
          update_hook(entity: Entities::ProjectHook)
        end

        desc 'Delete a project hook' do
          detail 'Removes a hook from a project. This is an idempotent method and can be called multiple times. Either the hook is available or not.'
          success Entities::ProjectHook
          failure [
            { code: 404, message: 'Not found' }
          ]
          tags project_hooks_tags
        end
        params do
          requires :hook_id, type: Integer, desc: 'The ID of the project hook'
        end
        delete do
          hook = find_hook

          destroy_conditionally!(hook) do
            WebHooks::DestroyService.new(current_user).execute(hook)
          end
        end

        mount ::API::Hooks::Events
      end

      desc 'Add project hook' do
        detail 'Adds a hook to a specified project'
        success Entities::ProjectHook
        failure [
          { code: 400, message: 'Validation error' },
          { code: 404, message: 'Not found' },
          { code: 422, message: 'Unprocessable entity' }
        ]
        tags project_hooks_tags
      end
      params do
        use :requires_url
        use :common_hook_parameters
      end
      post ":id/hooks" do
        hook_params = create_hook_params

        result = WebHooks::CreateService.new(current_user).execute(hook_params, hook_scope)

        if result[:status] == :success
          present result[:hook], with: Entities::ProjectHook
        else
          error!(result.message, result.http_status || 422)
        end
      end

      namespace ':id/hooks/' do
        mount ::API::Hooks::TriggerTest, with: {
          entity: ProjectHook
        }
        mount ::API::Hooks::ResendHook
      end
    end
  end
end