Commit 6038dc0d authored by Max Woolf's avatar Max Woolf

Fix impersonation created_at audit event field

Uses time impersonation occurred, rather than
time the audit event was created in a background
job as the timestamp on the audit event.

Changelog: fixed
EE: true
parent bd70ef16
......@@ -44,7 +44,7 @@ module EE
end
def log_audit_event
::AuditEvents::UserImpersonationEventCreateWorker.perform_async(current_user.id, user.id, request.remote_ip, 'started')
::AuditEvents::UserImpersonationEventCreateWorker.perform_async(current_user.id, user.id, request.remote_ip, 'started', DateTime.current)
end
def allowed_user_params
......
......@@ -38,7 +38,7 @@ module EE
end
def log_audit_event
::AuditEvents::UserImpersonationEventCreateWorker.perform_async(impersonator.id, current_user.id, request.remote_ip, 'stopped')
::AuditEvents::UserImpersonationEventCreateWorker.perform_async(impersonator.id, current_user.id, request.remote_ip, 'stopped', DateTime.current)
end
def set_current_ip_address(&block)
......
......@@ -2,12 +2,12 @@
module AuditEvents
class ImpersonationAuditEventService < ::AuditEventService
def initialize(author, ip_address, message)
def initialize(author, ip_address, message, created_at)
super(author, author, {
action: :custom,
custom_message: message,
ip_address: ip_address
})
}, :database_and_stream, created_at)
end
end
end
......@@ -4,11 +4,12 @@
# and for all of a user's groups when the user is impersonated.
module AuditEvents
class UserImpersonationGroupAuditEventService
def initialize(impersonator:, user:, remote_ip:, action: :started)
def initialize(impersonator:, user:, remote_ip:, action: :started, created_at:)
@impersonator = impersonator
@user = user
@remote_ip = remote_ip
@action = action.to_s
@created_at = created_at
end
def execute
......@@ -17,7 +18,7 @@ module AuditEvents
end
def log_instance_audit_event
AuditEvents::ImpersonationAuditEventService.new(@impersonator, @remote_ip, "#{@action.capitalize} Impersonation")
AuditEvents::ImpersonationAuditEventService.new(@impersonator, @remote_ip, "#{@action.capitalize} Impersonation", @created_at)
.for_user(full_path: @user.username, entity_id: @user.id).security_event
end
......@@ -30,7 +31,8 @@ module AuditEvents
author: @impersonator,
scope: group,
target: @user,
message: "Instance administrator #{@action} impersonation of #{@user.username}"
message: "Instance administrator #{@action} impersonation of #{@user.username}",
created_at: @created_at
}
::Gitlab::Audit::Auditor.audit(audit_context)
......
......@@ -7,11 +7,12 @@ module AuditEvents
data_consistency :sticky
feature_category :audit_events
def perform(impersonator_id, user_id, remote_ip, action)
def perform(impersonator_id, user_id, remote_ip, action, created_at)
::AuditEvents::UserImpersonationGroupAuditEventService.new(impersonator: User.find_by_id(impersonator_id),
user: User.find_by_id(user_id),
remote_ip: remote_ip,
action: action).execute
action: action,
created_at: created_at).execute
end
end
end
......@@ -19,7 +19,7 @@ RSpec.describe Admin::ImpersonationsController do
end
it 'enqueues a new worker' do
expect(AuditEvents::UserImpersonationEventCreateWorker).to receive(:perform_async).with(impersonator.id, user.id, anything, 'stopped').once
expect(AuditEvents::UserImpersonationEventCreateWorker).to receive(:perform_async).with(impersonator.id, user.id, anything, 'stopped', DateTime.current).once
delete :destroy
end
......
......@@ -109,7 +109,7 @@ RSpec.describe Admin::UsersController do
end
it 'enqueues a new worker' do
expect(AuditEvents::UserImpersonationEventCreateWorker).to receive(:perform_async).with(admin.id, user.id, anything, 'started').once
expect(AuditEvents::UserImpersonationEventCreateWorker).to receive(:perform_async).with(admin.id, user.id, anything, 'started', DateTime.current).once
post :impersonate, params: { id: user.username }
end
......
......@@ -7,7 +7,7 @@ RSpec.describe AuditEvents::ImpersonationAuditEventService do
let(:ip_address) { '127.0.0.1' }
let(:message) { 'Impersonation Started' }
let(:logger) { instance_double(Gitlab::AuditJsonLogger) }
let(:service) { described_class.new(impersonator, ip_address, message) }
let(:service) { described_class.new(impersonator, ip_address, message, 3.weeks.ago) }
describe '#security_event' do
before do
......
......@@ -7,7 +7,7 @@ RSpec.describe AuditEvents::UserImpersonationGroupAuditEventService do
let_it_be(:user) { create(:user) }
let_it_be(:admin) { create(:admin) }
let(:service) { described_class.new(impersonator: admin, user: user, remote_ip: '111.112.11.2', action: :started) }
let(:service) { described_class.new(impersonator: admin, user: user, remote_ip: '111.112.11.2', action: :started, created_at: 3.weeks.ago) }
before do
stub_licensed_features(audit_events: true)
......@@ -21,13 +21,17 @@ RSpec.describe AuditEvents::UserImpersonationGroupAuditEventService do
end
it 'creates audit events for both the instance and group level' do
expect { service.execute }.to change { AuditEvent.count }.by(2)
freeze_time do
expect { service.execute }.to change { AuditEvent.count }.by(2)
event = AuditEvent.first
expect(event.details[:custom_message]).to eq("Started Impersonation")
event = AuditEvent.first
expect(event.details[:custom_message]).to eq("Started Impersonation")
expect(event.created_at).to eq(3.weeks.ago)
group_audit_event = AuditEvent.last
expect(group_audit_event.details[:custom_message]).to eq("Instance administrator started impersonation of #{user.username}")
group_audit_event = AuditEvent.last
expect(group_audit_event.details[:custom_message]).to eq("Instance administrator started impersonation of #{user.username}")
expect(group_audit_event.created_at).to eq(3.weeks.ago)
end
end
end
......
......@@ -12,14 +12,17 @@ RSpec.describe AuditEvents::UserImpersonationEventCreateWorker do
subject(:worker) { described_class.new }
it 'invokes the UserImpersonationGroupAuditEventService' do
expect(::AuditEvents::UserImpersonationGroupAuditEventService).to receive(:new).with(
impersonator: impersonator,
user: user,
remote_ip: '111.112.11.2',
action: action
).and_call_original
freeze_time do
expect(::AuditEvents::UserImpersonationGroupAuditEventService).to receive(:new).with(
impersonator: impersonator,
user: user,
remote_ip: '111.112.11.2',
action: action,
created_at: 2.weeks.ago
).and_call_original
subject.perform(impersonator.id, user.id, '111.112.11.2', action)
subject.perform(impersonator.id, user.id, '111.112.11.2', action, 2.weeks.ago)
end
end
end
end
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