Commit 698882cf authored by Thong Kuah's avatar Thong Kuah

Merge branch 'group-member-webhook-ui' into 'master'

Fire webhook on add group member

See merge request gitlab-org/gitlab!49285
parents 96460346 dce89c37
......@@ -15,7 +15,8 @@ module TriggerableHooks
wiki_page_hooks: :wiki_page_events,
deployment_hooks: :deployment_events,
feature_flag_hooks: :feature_flag_events,
release_hooks: :releases_events
release_hooks: :releases_events,
member_hooks: :member_events
}.freeze
extend ActiveSupport::Concern
......
......@@ -13,86 +13,88 @@
%ul.list-unstyled.gl-ml-6
%li
= form.check_box :push_events, class: 'form-check-input'
= form.label :push_events, class: 'list-label form-check-label ml-1' do
= form.label :push_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Push events')
= form.text_field :push_events_branch_filter, class: 'form-control', placeholder: 'Branch name or wildcard pattern to trigger on (leave blank for all)'
%p.text-muted.ml-1
%p.text-muted.gl-ml-1
= s_('Webhooks|This URL will be triggered by a push to the repository')
%li
= form.check_box :tag_push_events, class: 'form-check-input'
= form.label :tag_push_events, class: 'list-label form-check-label ml-1' do
= form.label :tag_push_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Tag push events')
%p.text-muted.ml-1
%p.text-muted.gl-ml-1
= s_('Webhooks|This URL will be triggered when a new tag is pushed to the repository')
%li
= form.check_box :note_events, class: 'form-check-input'
= form.label :note_events, class: 'list-label form-check-label ml-1' do
= form.label :note_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Comments')
%p.text-muted.ml-1
%p.text-muted.gl-ml-1
= s_('Webhooks|This URL will be triggered when someone adds a comment')
%li
= form.check_box :confidential_note_events, class: 'form-check-input'
= form.label :confidential_note_events, class: 'list-label form-check-label ml-1' do
= form.label :confidential_note_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Confidential Comments')
%p.text-muted.ml-1
%p.text-muted.gl-ml-1
= s_('Webhooks|This URL will be triggered when someone adds a comment on a confidential issue')
%li
= form.check_box :issues_events, class: 'form-check-input'
= form.label :issues_events, class: 'list-label form-check-label ml-1' do
= form.label :issues_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Issues events')
%p.text-muted.ml-1
%p.text-muted.gl-ml-1
= s_('Webhooks|This URL will be triggered when an issue is created/updated/merged')
%li
= form.check_box :confidential_issues_events, class: 'form-check-input'
= form.label :confidential_issues_events, class: 'list-label form-check-label ml-1' do
= form.label :confidential_issues_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Confidential Issues events')
%p.text-muted.ml-1
%p.text-muted.gl-ml-1
= s_('Webhooks|This URL will be triggered when a confidential issue is created/updated/merged')
- if @group
= render_if_exists 'groups/hooks/member_events', form: form
%li
= form.check_box :merge_requests_events, class: 'form-check-input'
= form.label :merge_requests_events, class: 'list-label form-check-label ml-1' do
= form.label :merge_requests_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Merge request events')
%p.text-muted.ml-1
%p.text-muted.gl-ml-1
= s_('Webhooks|This URL will be triggered when a merge request is created/updated/merged')
%li
= form.check_box :job_events, class: 'form-check-input'
= form.label :job_events, class: 'list-label form-check-label ml-1' do
= form.label :job_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Job events')
%p.text-muted.ml-1
%p.text-muted.gl-ml-1
= s_('Webhooks|This URL will be triggered when the job status changes')
%li
= form.check_box :pipeline_events, class: 'form-check-input'
= form.label :pipeline_events, class: 'list-label form-check-label ml-1' do
= form.label :pipeline_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Pipeline events')
%p.text-muted.ml-1
%p.text-muted.gl-ml-1
= s_('Webhooks|This URL will be triggered when the pipeline status changes')
%li
= form.check_box :wiki_page_events, class: 'form-check-input'
= form.label :wiki_page_events, class: 'list-label form-check-label ml-1' do
= form.label :wiki_page_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Wiki Page events')
%p.text-muted.ml-1
%p.text-muted.gl-ml-1
= s_('Webhooks|This URL will be triggered when a wiki page is created/updated')
%li
= form.check_box :deployment_events, class: 'form-check-input'
= form.label :deployment_events, class: 'list-label form-check-label ml-1' do
= form.label :deployment_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Deployment events')
%p.text-muted.ml-1
%p.text-muted.gl-ml-1
= s_('Webhooks|This URL is triggered when a deployment starts, finishes, fails, or is canceled')
%li
= form.check_box :feature_flag_events, class: 'form-check-input'
= form.label :feature_flag_events, class: 'list-label form-check-label ml-1' do
= form.label :feature_flag_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Feature Flag events')
%p.text-muted.ml-1
%p.text-muted.gl-ml-1
= s_('Webhooks|This URL is triggered when a feature flag is turned on or off')
%li
= form.check_box :releases_events, class: 'form-check-input'
= form.label :releases_events, class: 'list-label form-check-label ml-1' do
= form.label :releases_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Releases events')
%p.text-muted.ml-1
%p.text-muted.gl-ml-1
= s_('Webhooks|This URL is triggered when a release is created/updated')
.form-group
= form.label :enable_ssl_verification, s_('Webhooks|SSL verification'), class: 'label-bold checkbox'
.form-check
= form.check_box :enable_ssl_verification, class: 'form-check-input'
= form.label :enable_ssl_verification, class: 'form-check-label ml-1' do
= form.label :enable_ssl_verification, class: 'form-check-label gl-ml-1' do
%strong= s_('Webhooks|Enable SSL verification')
......@@ -448,6 +448,18 @@ module EE
)
end
override :execute_hooks
def execute_hooks(data, hooks_scope)
super
return unless feature_available?(:group_webhooks)
self_and_ancestor_hooks = GroupHook.where(group_id: self.self_and_ancestors)
self_and_ancestor_hooks.hooks_for(hooks_scope).each do |hook|
hook.async_execute(data, hooks_scope.to_s)
end
end
private
def custom_project_templates_group_allowed
......
......@@ -108,5 +108,18 @@ module EE
allowed_email_domain.email_matches_domain?(email)
end
end
override :post_create_hook
def post_create_hook
super
return unless self.source.feature_available?(:group_webhooks)
return unless GroupHook.where(group_id: self.source.self_and_ancestors).exists?
run_after_commit do
data = ::Gitlab::HookData::GroupMemberBuilder.new(self).build(:create)
self.source.execute_hooks(data, :member_hooks)
end
end
end
end
......@@ -20,7 +20,8 @@ class GroupHook < WebHook
:pipeline_hooks,
:wiki_page_hooks,
:deployment_hooks,
:release_hooks
:release_hooks,
:member_hooks
]
belongs_to :group
......
%li
= form.check_box :member_events, class: 'form-check-input'
= form.label :member_events, class: 'list-label form-check-label gl-ml-1' do
%strong= s_('Webhooks|Member events')
%p.text-muted.gl-ml-1
= s_('Webhooks|This URL will be triggered when a member is added to a group')
---
title: Fire webhook on add group member
merge_request: 49285
author:
type: added
......@@ -39,7 +39,8 @@ RSpec.describe Groups::HooksController do
token: 'TEST TOKEN',
url: 'http://example.com',
wiki_page_events: true,
deployment_events: true
deployment_events: true,
member_events: true
}
post :create, params: { group_id: group.to_param, hook: hook_params }
......@@ -81,7 +82,8 @@ RSpec.describe Groups::HooksController do
url: 'http://example.com',
wiki_page_events: true,
deployment_events: true,
releases_events: true
releases_events: true,
member_events: true
}
end
......
......@@ -237,4 +237,86 @@ RSpec.describe GroupMember do
end
end
end
context 'group member webhooks', :sidekiq_inline do
let_it_be(:group) { create(:group_with_plan, plan: :gold_plan) }
let_it_be(:group_hook) { create(:group_hook, group: group, member_events: true) }
let(:user) { create(:user) }
context 'fires the webhook when a member is added' do
before do
WebMock.stub_request(:post, group_hook.url)
end
it 'execute webhooks' do
member = group.add_guest(user)
expect(WebMock).to have_requested(:post, group_hook.url).with(
headers: { 'Content-Type' => 'application/json', 'User-Agent' => "GitLab/#{Gitlab::VERSION}", 'X-Gitlab-Event' => 'Member Hook' },
body: {
created_at: member.created_at&.xmlschema,
updated_at: member.updated_at&.xmlschema,
group_name: group.name,
group_path: group.path,
group_id: group.id,
user_username: user.username,
user_name: user.name,
user_email: user.email,
user_id: user.id,
group_access: 'Guest',
expires_at: member.expires_at&.xmlschema,
group_plan: 'gold',
event_name: 'user_add_to_group'
}.to_json
)
end
context 'ancestor groups' do
let_it_be(:subgroup) { create(:group, parent: group) }
let_it_be(:subgroup_hook) { create(:group_hook, group: subgroup, member_events: true) }
it 'fires webhook twice when parent group has member_events webhook enabled' do
WebMock.stub_request(:post, subgroup_hook.url)
subgroup.add_guest(user)
expect(WebMock).to have_requested(:post, subgroup_hook.url)
expect(WebMock).to have_requested(:post, group_hook.url)
end
it 'fires webhook once when parent group has member_events webhook disabled' do
group_hook = create(:group_hook, group: group, member_events: false)
WebMock.stub_request(:post, subgroup_hook.url)
subgroup.add_guest(user)
expect(WebMock).to have_requested(:post, subgroup_hook.url)
expect(WebMock).not_to have_requested(:post, group_hook.url)
end
end
end
context 'does not execute webhook' do
before do
WebMock.stub_request(:post, group_hook.url)
end
it 'does not execute webhooks if group member events webhook is disabled' do
group_hook = create(:group_hook, group: group, member_events: false)
group.add_guest(user)
expect(WebMock).not_to have_requested(:post, group_hook.url)
end
it 'does not execute webhooks if feature flag is disabled' do
stub_feature_flags(group_webhooks: false)
group.add_guest(user)
expect(WebMock).not_to have_requested(:post, group_hook.url)
end
end
end
end
......@@ -31055,6 +31055,9 @@ msgstr ""
msgid "Webhooks|Job events"
msgstr ""
msgid "Webhooks|Member events"
msgstr ""
msgid "Webhooks|Merge request events"
msgstr ""
......@@ -31091,6 +31094,9 @@ msgstr ""
msgid "Webhooks|This URL will be triggered when a confidential issue is created/updated/merged"
msgstr ""
msgid "Webhooks|This URL will be triggered when a member is added to a group"
msgstr ""
msgid "Webhooks|This URL will be triggered when a merge request is created/updated/merged"
msgstr ""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment