diff --git a/ee/app/services/audit_events/build_service.rb b/ee/app/services/audit_events/build_service.rb index c3ac3584cc208648ba1e43bf104248bd92733ce1..ae071529fb2ff69ec71edb5b80f8694324b35ec9 100644 --- a/ee/app/services/audit_events/build_service.rb +++ b/ee/app/services/audit_events/build_service.rb @@ -78,6 +78,8 @@ def build_author(author) end def build_target(target) + return target if target.is_a? ::Gitlab::Audit::NullTarget + ::Gitlab::Audit::Target.new(target) end diff --git a/ee/app/services/ee/resource_access_tokens/create_service.rb b/ee/app/services/ee/resource_access_tokens/create_service.rb index 8962483dd524a1cc3d6c154a365982743e66a1ea..875e6ab2d56a437ba42dad5fea7380d32aa91aae 100644 --- a/ee/app/services/ee/resource_access_tokens/create_service.rb +++ b/ee/app/services/ee/resource_access_tokens/create_service.rb @@ -26,15 +26,25 @@ def audit_event_service(token, response) "Attempted to create #{resource_type} access token but failed with message: #{response.message}" end - ::AuditEventService.new( - current_user, - resource, - target_id: token&.id, - target_type: token&.class&.name, + audit_context = { + name: event_type(response), + author: current_user, + scope: resource, + target: token || ::Gitlab::Audit::NullTarget.new, + message: message, target_details: token&.user&.name, - action: :custom, - custom_message: message - ).security_event + additional_details: { action: :custom } + } + + ::Gitlab::Audit::Auditor.audit(audit_context) + end + + def event_type(response) + if response.success? + "#{resource.class.name.downcase}_access_token_created" + else + "#{resource.class.name.downcase}_access_token_creation_failed" + end end end end diff --git a/ee/app/services/ee/resource_access_tokens/revoke_service.rb b/ee/app/services/ee/resource_access_tokens/revoke_service.rb index b39ac0f238c93b3d9f8331539292cb3b57b9e799..c1f9041eaeae81880632fdeadefac546597baaac 100644 --- a/ee/app/services/ee/resource_access_tokens/revoke_service.rb +++ b/ee/app/services/ee/resource_access_tokens/revoke_service.rb @@ -19,15 +19,25 @@ def audit_event_service(token, response) "but failed with message: #{response.message}" end - ::AuditEventService.new( - current_user, - resource, - target_id: token.id, - target_type: token.class.name, + audit_context = { + name: event_type(response), + author: current_user, + scope: resource, + target: token, + message: message, target_details: token.user.name, - action: :custom, - custom_message: message - ).security_event + additional_details: { action: :custom } + } + + ::Gitlab::Audit::Auditor.audit(audit_context) + end + + def event_type(response) + if response.success? + "#{resource.class.name.downcase}_access_token_deleted" + else + "#{resource.class.name.downcase}_access_token_deletion_failed" + end end end end diff --git a/ee/lib/gitlab/audit/null_target.rb b/ee/lib/gitlab/audit/null_target.rb new file mode 100644 index 0000000000000000000000000000000000000000..ed3a50e90671a29d09001c2bd5819be324620aac --- /dev/null +++ b/ee/lib/gitlab/audit/null_target.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Gitlab + module Audit + class NullTarget + def id + nil + end + + def type + nil + end + + def details + nil + end + end + end +end diff --git a/ee/spec/lib/gitlab/audit/null_target_spec.rb b/ee/spec/lib/gitlab/audit/null_target_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..f192e0cd8db43ca7780207c3c24eff8bc8a32918 --- /dev/null +++ b/ee/spec/lib/gitlab/audit/null_target_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Audit::NullTarget do + subject { described_class.new } + + describe '#id' do + it 'returns nil' do + expect(subject.id).to eq(nil) + end + end + + describe '#type' do + it 'returns nil' do + expect(subject.type).to eq(nil) + end + end + + describe '#details' do + it 'returns nil' do + expect(subject.details).to eq(nil) + end + end +end diff --git a/ee/spec/services/resource_access_tokens/create_service_spec.rb b/ee/spec/services/resource_access_tokens/create_service_spec.rb index ecb06187edd94f970821af44f32cf2988d47e0c1..194f3f6e16f171db852f46c6276825d0d164b3ce 100644 --- a/ee/spec/services/resource_access_tokens/create_service_spec.rb +++ b/ee/spec/services/resource_access_tokens/create_service_spec.rb @@ -7,6 +7,11 @@ let_it_be(:user) { create(:user) } + before do + stub_licensed_features(audit_events: true) + stub_licensed_features(external_audit_events: true) + end + shared_examples 'token creation succeeds' do let(:resource) { create(:project, group: group)} @@ -71,7 +76,9 @@ end context 'project access token audit events' do - let(:resource) { create(:project) } + let(:group) { create(:group) } + let!(:destination) { create(:external_audit_event_destination, group: group) } + let(:resource) { create(:project, group: group) } context 'when project access token is successfully created' do before do @@ -96,6 +103,10 @@ target_details: access_token.user.name ) end + + it_behaves_like 'sends correct event type in audit event stream' do + let_it_be(:event_type) { "project_access_token_created" } + end end context 'when project access token is unsuccessfully created' do @@ -122,6 +133,10 @@ target_details: nil ) end + + it_behaves_like 'sends correct event type in audit event stream' do + let_it_be(:event_type) { "project_access_token_creation_failed" } + end end context "when access provisioning fails" do @@ -156,6 +171,10 @@ target_details: nil ) end + + it_behaves_like 'sends correct event type in audit event stream' do + let_it_be(:event_type) { "project_access_token_creation_failed" } + end end end end diff --git a/ee/spec/services/resource_access_tokens/revoke_service_spec.rb b/ee/spec/services/resource_access_tokens/revoke_service_spec.rb index 8f4db24d57c3bab02eb7c58a851ecaafd3a3f27f..4122c8ed96bc9b7a18032d9cac6e312696aa4932 100644 --- a/ee/spec/services/resource_access_tokens/revoke_service_spec.rb +++ b/ee/spec/services/resource_access_tokens/revoke_service_spec.rb @@ -10,6 +10,11 @@ let(:access_token) { create(:personal_access_token, user: resource_bot) } + before do + stub_licensed_features(audit_events: true) + stub_licensed_features(external_audit_events: true) + end + shared_examples 'audit event details' do it 'creates an audit event' do expect { subject }.to change { AuditEvent.count }.from(0).to(1) @@ -26,7 +31,9 @@ end context 'project access token audit events' do - let(:resource) { create(:project) } + let(:group) { create(:group) } + let!(:destination) { create(:external_audit_event_destination, group: group) } + let(:resource) { create(:project, group: group) } context 'when project access token is successfully revoked' do before do @@ -48,6 +55,10 @@ target_details: access_token.user.name ) end + + it_behaves_like 'sends correct event type in audit event stream' do + let_it_be(:event_type) { "project_access_token_deleted" } + end end context 'when project access token is unsuccessfully revoked' do @@ -74,6 +85,10 @@ target_details: access_token.user.name ) end + + it_behaves_like 'sends correct event type in audit event stream' do + let_it_be(:event_type) { "project_access_token_deletion_failed" } + end end context 'with inadequate permissions' do @@ -100,6 +115,10 @@ target_details: access_token.user.name ) end + + it_behaves_like 'sends correct event type in audit event stream' do + let_it_be(:event_type) { "project_access_token_deletion_failed" } + end end end end