Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/lib/gitlab/audit')
-rw-r--r--spec/lib/gitlab/audit/auditor_spec.rb258
-rw-r--r--spec/lib/gitlab/audit/ci_runner_token_author_spec.rb2
-rw-r--r--spec/lib/gitlab/audit/deploy_key_author_spec.rb17
-rw-r--r--spec/lib/gitlab/audit/null_author_spec.rb9
-rw-r--r--spec/lib/gitlab/audit/null_target_spec.rb25
-rw-r--r--spec/lib/gitlab/audit/target_spec.rb47
6 files changed, 357 insertions, 1 deletions
diff --git a/spec/lib/gitlab/audit/auditor_spec.rb b/spec/lib/gitlab/audit/auditor_spec.rb
new file mode 100644
index 00000000000..fc5917ca583
--- /dev/null
+++ b/spec/lib/gitlab/audit/auditor_spec.rb
@@ -0,0 +1,258 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Audit::Auditor do
+ let(:name) { 'audit_operation' }
+ let(:author) { create(:user) }
+ let(:group) { create(:group) }
+ let(:provider) { 'standard' }
+ let(:context) do
+ { name: name,
+ author: author,
+ scope: group,
+ target: group,
+ authentication_event: true,
+ authentication_provider: provider,
+ message: "Signed in using standard authentication" }
+ end
+
+ let(:logger) { instance_spy(Gitlab::AuditJsonLogger) }
+
+ subject(:auditor) { described_class }
+
+ describe '.audit' do
+ context 'when authentication event' do
+ let(:audit!) { auditor.audit(context) }
+
+ it 'creates an authentication event' do
+ expect(AuthenticationEvent).to receive(:new).with(
+ {
+ user: author,
+ user_name: author.name,
+ ip_address: author.current_sign_in_ip,
+ result: AuthenticationEvent.results[:success],
+ provider: provider
+ }
+ ).and_call_original
+
+ audit!
+ end
+
+ it 'logs audit events to database', :aggregate_failures do
+ freeze_time do
+ audit!
+
+ audit_event = AuditEvent.last
+
+ expect(audit_event.author_id).to eq(author.id)
+ expect(audit_event.entity_id).to eq(group.id)
+ expect(audit_event.entity_type).to eq(group.class.name)
+ expect(audit_event.created_at).to eq(Time.zone.now)
+ expect(audit_event.details[:target_id]).to eq(group.id)
+ expect(audit_event.details[:target_type]).to eq(group.class.name)
+ end
+ end
+
+ it 'logs audit events to file' do
+ expect(::Gitlab::AuditJsonLogger).to receive(:build).and_return(logger)
+
+ audit!
+
+ expect(logger).to have_received(:info).with(
+ hash_including(
+ 'author_id' => author.id,
+ 'author_name' => author.name,
+ 'entity_id' => group.id,
+ 'entity_type' => group.class.name,
+ 'details' => kind_of(Hash)
+ )
+ )
+ end
+
+ context 'when overriding the create datetime' do
+ let(:context) do
+ { name: name,
+ author: author,
+ scope: group,
+ target: group,
+ created_at: 3.weeks.ago,
+ authentication_event: true,
+ authentication_provider: provider,
+ message: "Signed in using standard authentication" }
+ end
+
+ it 'logs audit events to database', :aggregate_failures do
+ freeze_time do
+ audit!
+
+ audit_event = AuditEvent.last
+
+ expect(audit_event.author_id).to eq(author.id)
+ expect(audit_event.entity_id).to eq(group.id)
+ expect(audit_event.entity_type).to eq(group.class.name)
+ expect(audit_event.created_at).to eq(3.weeks.ago)
+ expect(audit_event.details[:target_id]).to eq(group.id)
+ expect(audit_event.details[:target_type]).to eq(group.class.name)
+ end
+ end
+
+ it 'logs audit events to file' do
+ freeze_time do
+ expect(::Gitlab::AuditJsonLogger).to receive(:build).and_return(logger)
+
+ audit!
+
+ expect(logger).to have_received(:info).with(
+ hash_including(
+ 'author_id' => author.id,
+ 'author_name' => author.name,
+ 'entity_id' => group.id,
+ 'entity_type' => group.class.name,
+ 'details' => kind_of(Hash),
+ 'created_at' => 3.weeks.ago.iso8601(3)
+ )
+ )
+ end
+ end
+ end
+
+ context 'when overriding the additional_details' do
+ additional_details = { action: :custom, from: false, to: true }
+ let(:context) do
+ { name: name,
+ author: author,
+ scope: group,
+ target: group,
+ created_at: Time.zone.now,
+ additional_details: additional_details,
+ authentication_event: true,
+ authentication_provider: provider,
+ message: "Signed in using standard authentication" }
+ end
+
+ it 'logs audit events to database' do
+ freeze_time do
+ audit!
+
+ expect(AuditEvent.last.details).to include(additional_details)
+ end
+ end
+
+ it 'logs audit events to file' do
+ freeze_time do
+ expect(::Gitlab::AuditJsonLogger).to receive(:build).and_return(logger)
+
+ audit!
+
+ expect(logger).to have_received(:info).with(
+ hash_including(
+ 'details' => hash_including('action' => 'custom', 'from' => 'false', 'to' => 'true'),
+ 'action' => 'custom',
+ 'from' => 'false',
+ 'to' => 'true'
+ )
+ )
+ end
+ end
+ end
+
+ context 'when overriding the target_details' do
+ target_details = "this is my target details"
+ let(:context) do
+ {
+ name: name,
+ author: author,
+ scope: group,
+ target: group,
+ created_at: Time.zone.now,
+ target_details: target_details,
+ authentication_event: true,
+ authentication_provider: provider,
+ message: "Signed in using standard authentication"
+ }
+ end
+
+ it 'logs audit events to database' do
+ freeze_time do
+ audit!
+
+ audit_event = AuditEvent.last
+ expect(audit_event.details).to include({ target_details: target_details })
+ expect(audit_event.target_details).to eq(target_details)
+ end
+ end
+
+ it 'logs audit events to file' do
+ freeze_time do
+ expect(::Gitlab::AuditJsonLogger).to receive(:build).and_return(logger)
+
+ audit!
+
+ expect(logger).to have_received(:info).with(
+ hash_including(
+ 'details' => hash_including('target_details' => target_details),
+ 'target_details' => target_details
+ )
+ )
+ end
+ end
+ end
+ end
+
+ context 'when authentication event is false' do
+ let(:context) do
+ { name: name, author: author, scope: group,
+ target: group, authentication_event: false, message: "sample message" }
+ end
+
+ it 'does not create an authentication event' do
+ expect { auditor.audit(context) }.not_to change(AuthenticationEvent, :count)
+ end
+ end
+
+ context 'when authentication event is invalid' do
+ let(:audit!) { auditor.audit(context) }
+
+ before do
+ allow(AuthenticationEvent).to receive(:new).and_raise(ActiveRecord::RecordInvalid)
+ allow(Gitlab::ErrorTracking).to receive(:track_exception)
+ end
+
+ it 'tracks error' do
+ audit!
+
+ expect(Gitlab::ErrorTracking).to have_received(:track_exception).with(
+ kind_of(ActiveRecord::RecordInvalid),
+ { audit_operation: name }
+ )
+ end
+
+ it 'does not throw exception' do
+ expect { auditor.audit(context) }.not_to raise_exception
+ end
+ end
+
+ context 'when audit events are invalid' do
+ let(:audit!) { auditor.audit(context) }
+
+ before do
+ allow(AuditEvent).to receive(:bulk_insert!).and_raise(ActiveRecord::RecordInvalid)
+ allow(Gitlab::ErrorTracking).to receive(:track_exception)
+ end
+
+ it 'tracks error' do
+ audit!
+
+ expect(Gitlab::ErrorTracking).to have_received(:track_exception).with(
+ kind_of(ActiveRecord::RecordInvalid),
+ { audit_operation: name }
+ )
+ end
+
+ it 'does not throw exception' do
+ expect { auditor.audit(context) }.not_to raise_exception
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/audit/ci_runner_token_author_spec.rb b/spec/lib/gitlab/audit/ci_runner_token_author_spec.rb
index f55e1b44936..89664c57084 100644
--- a/spec/lib/gitlab/audit/ci_runner_token_author_spec.rb
+++ b/spec/lib/gitlab/audit/ci_runner_token_author_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe Gitlab::Audit::CiRunnerTokenAuthor do
describe '.initialize' do
subject { described_class.new(audit_event) }
- let(:details) { }
+ let(:details) {}
let(:audit_event) { instance_double(AuditEvent, details: details, entity_type: 'Project', entity_path: 'd/e') }
context 'with runner_authentication_token' do
diff --git a/spec/lib/gitlab/audit/deploy_key_author_spec.rb b/spec/lib/gitlab/audit/deploy_key_author_spec.rb
new file mode 100644
index 00000000000..72444f77c91
--- /dev/null
+++ b/spec/lib/gitlab/audit/deploy_key_author_spec.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Audit::DeployKeyAuthor do
+ describe '#initialize' do
+ it 'sets correct attributes' do
+ expect(described_class.new(name: 'Lorem deploy key'))
+ .to have_attributes(id: -3, name: 'Lorem deploy key')
+ end
+
+ it 'sets default name when it is not provided' do
+ expect(described_class.new)
+ .to have_attributes(id: -3, name: 'Deploy Key')
+ end
+ end
+end
diff --git a/spec/lib/gitlab/audit/null_author_spec.rb b/spec/lib/gitlab/audit/null_author_spec.rb
index 2045139a5f7..e2f71a34534 100644
--- a/spec/lib/gitlab/audit/null_author_spec.rb
+++ b/spec/lib/gitlab/audit/null_author_spec.rb
@@ -57,6 +57,15 @@ RSpec.describe Gitlab::Audit::NullAuthor do
expect(subject.for(-2, audit_event)).to be_a(Gitlab::Audit::DeployTokenAuthor)
expect(subject.for(-2, audit_event)).to have_attributes(id: -2, name: 'Test deploy token')
end
+
+ it 'returns DeployKeyAuthor when id equals -3', :aggregate_failures do
+ allow(audit_event).to receive(:[]).with(:author_name).and_return('Test deploy key')
+ allow(audit_event).to receive(:details).and_return({})
+ allow(audit_event).to receive(:target_type)
+
+ expect(subject.for(-3, audit_event)).to be_a(Gitlab::Audit::DeployKeyAuthor)
+ expect(subject.for(-3, audit_event)).to have_attributes(id: -3, name: 'Test deploy key')
+ end
end
describe '#current_sign_in_ip' do
diff --git a/spec/lib/gitlab/audit/null_target_spec.rb b/spec/lib/gitlab/audit/null_target_spec.rb
new file mode 100644
index 00000000000..f192e0cd8db
--- /dev/null
+++ b/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/spec/lib/gitlab/audit/target_spec.rb b/spec/lib/gitlab/audit/target_spec.rb
new file mode 100644
index 00000000000..5c06cd117a9
--- /dev/null
+++ b/spec/lib/gitlab/audit/target_spec.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Audit::Target do
+ let(:object) { double('object') } # rubocop:disable RSpec/VerifiedDoubles
+
+ subject { described_class.new(object) }
+
+ describe '#id' do
+ it 'returns object id' do
+ allow(object).to receive(:id).and_return(object_id)
+
+ expect(subject.id).to eq(object_id)
+ end
+ end
+
+ describe '#type' do
+ it 'returns object class name' do
+ allow(object).to receive_message_chain(:class, :name).and_return('User')
+
+ expect(subject.type).to eq('User')
+ end
+ end
+
+ describe '#details' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:name, :audit_details, :details) do
+ 'jackie' | 'wanderer' | 'jackie'
+ 'jackie' | nil | 'jackie'
+ nil | 'wanderer' | 'wanderer'
+ nil | nil | 'unknown'
+ end
+
+ before do
+ allow(object).to receive(:name).and_return(name) if name
+ allow(object).to receive(:audit_details).and_return(audit_details) if audit_details
+ end
+
+ with_them do
+ it 'returns details' do
+ expect(subject.details).to eq(details)
+ end
+ end
+ end
+end