Commit 39d59e2a authored by Harsimar Sandhu's avatar Harsimar Sandhu Committed by Tetiana Chupryna

Stream audit event on merge request approval

Stream audit events that relate to merge
approval actions performed within a project.

Changelog: added
EE: true
parent ac28e3ae
...@@ -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