Commit 8179bf9b authored by Tetiana Chupryna's avatar Tetiana Chupryna

Merge branch '271162-audit-events-on-mr-approval-actions' into 'master'

Stream audit event on merge request approval

See merge request gitlab-org/gitlab!82471
parents 46ed5480 39d59e2a
...@@ -11,6 +11,7 @@ module MergeRequests ...@@ -11,6 +11,7 @@ module MergeRequests
reset_approvals_cache(merge_request) reset_approvals_cache(merge_request)
create_event(merge_request) create_event(merge_request)
stream_audit_event(merge_request)
create_approval_note(merge_request) create_approval_note(merge_request)
mark_pending_todos_as_done(merge_request) mark_pending_todos_as_done(merge_request)
execute_approval_hooks(merge_request, current_user) execute_approval_hooks(merge_request, current_user)
...@@ -52,6 +53,10 @@ module MergeRequests ...@@ -52,6 +53,10 @@ module MergeRequests
def create_event(merge_request) def create_event(merge_request)
event_service.approve_mr(merge_request, current_user) event_service.approve_mr(merge_request, current_user)
end end
def stream_audit_event(merge_request)
# Defined in EE
end
end end
end end
......
...@@ -259,3 +259,47 @@ Fetch: ...@@ -259,3 +259,47 @@ Fetch:
"target_id": 29 "target_id": 29
} }
``` ```
## Audit event streaming on merge request approval actions
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/271162) in GitLab 14.9.
Stream audit events that relate to merge approval actions performed within a project.
### Request headers
Request headers are formatted as follows:
```plaintext
POST /logs HTTP/1.1
Host: <DESTINATION_HOST>
Content-Type: application/x-www-form-urlencoded
X-Gitlab-Event-Streaming-Token: <DESTINATION_TOKEN>
```
### Example request body
```json
{
"id": 1,
"author_id": 1,
"entity_id": 6,
"entity_type": "Project",
"details": {
"author_name": "example_username",
"target_id": 20,
"target_type": "MergeRequest",
"target_details": "merge request title",
"custom_message": "Approved merge request",
"ip_address": "127.0.0.1",
"entity_path": "example-group/example-project"
},
"ip_address": "127.0.0.1",
"author_name": "example_username",
"entity_path": "example-group/example-project",
"target_details": "merge request title",
"created_at": "2022-03-09T06:53:11.181Z",
"target_type": "MergeRequest",
"target_id": 20
}
```
...@@ -302,6 +302,10 @@ module EE ...@@ -302,6 +302,10 @@ module EE
project.security_reports_up_to_date_for_ref?(target_branch) project.security_reports_up_to_date_for_ref?(target_branch)
end end
def audit_details
title
end
private private
def has_approved_license_check? def has_approved_license_check?
......
...@@ -46,6 +46,16 @@ module EE ...@@ -46,6 +46,16 @@ module EE
end end
end end
override :stream_audit_event
def stream_audit_event(merge_request)
AuditEvents::BuildService.new(
author: current_user,
scope: merge_request.project,
target: merge_request,
message: 'Approved merge request'
).execute.stream_to_external_destinations(use_json: true)
end
def incorrect_approval_password?(merge_request) def incorrect_approval_password?(merge_request)
merge_request.project.require_password_to_approve? && merge_request.project.require_password_to_approve? &&
!::Gitlab::Auth.find_with_user_password(current_user.username, params[:approval_password]) !::Gitlab::Auth.find_with_user_password(current_user.username, params[:approval_password])
......
...@@ -1362,4 +1362,12 @@ RSpec.describe MergeRequest do ...@@ -1362,4 +1362,12 @@ RSpec.describe MergeRequest do
it { is_expected.to be false } it { is_expected.to be false }
end end
end end
describe '#audit_details' do
it 'equals to the title' do
merge_request = create(:merge_request, title: 'I am a title')
expect(merge_request.audit_details).to eq(merge_request.title)
end
end
end end
...@@ -65,6 +65,14 @@ RSpec.describe MergeRequests::ApprovalService do ...@@ -65,6 +65,14 @@ RSpec.describe MergeRequests::ApprovalService do
service.execute(merge_request) service.execute(merge_request)
end end
it 'sends the audit streaming event' do
expect_next_instance_of(AuditEvent) do |instance|
expect(instance).to receive(:stream_to_external_destinations).with(use_json: true)
end
service.execute(merge_request)
end
context 'with remaining approvals' do context 'with remaining approvals' do
it 'fires an approval webhook' do it 'fires an approval webhook' do
expect(merge_request).to receive(:approvals_left).and_return(5) expect(merge_request).to receive(:approvals_left).and_return(5)
......
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