Commit 17b3cb6c authored by manojmj's avatar manojmj

Log impersonation actions in audit log

This change adds audit logs for user impersonation
when an admin starts/stops impersonating
another user.
parent b52d9c6c
...@@ -39,7 +39,7 @@ class Admin::UsersController < Admin::ApplicationController ...@@ -39,7 +39,7 @@ class Admin::UsersController < Admin::ApplicationController
warden.set_user(user, scope: :user) warden.set_user(user, scope: :user)
Gitlab::AppLogger.info(_("User %{current_user_username} has started impersonating %{username}") % { current_user_username: current_user.username, username: user.username }) log_impersonation_event
flash[:alert] = _("You are now impersonating %{username}") % { username: user.username } flash[:alert] = _("You are now impersonating %{username}") % { username: user.username }
...@@ -236,6 +236,10 @@ class Admin::UsersController < Admin::ApplicationController ...@@ -236,6 +236,10 @@ class Admin::UsersController < Admin::ApplicationController
def check_impersonation_availability def check_impersonation_availability
access_denied! unless Gitlab.config.gitlab.impersonation_enabled access_denied! unless Gitlab.config.gitlab.impersonation_enabled
end end
def log_impersonation_event
Gitlab::AppLogger.info(_("User %{current_user_username} has started impersonating %{username}") % { current_user_username: current_user.username, username: user.username })
end
end end
Admin::UsersController.prepend(EE::Admin::UsersController) Admin::UsersController.prepend(EE::Admin::UsersController)
...@@ -499,9 +499,7 @@ class ApplicationController < ActionController::Base ...@@ -499,9 +499,7 @@ class ApplicationController < ActionController::Base
end end
def stop_impersonation def stop_impersonation
impersonated_user = current_user log_impersonation_event
Gitlab::AppLogger.info("User #{impersonator.username} has stopped impersonating #{impersonated_user.username}")
warden.set_user(impersonator, scope: :user) warden.set_user(impersonator, scope: :user)
session[:impersonator_id] = nil session[:impersonator_id] = nil
...@@ -509,6 +507,14 @@ class ApplicationController < ActionController::Base ...@@ -509,6 +507,14 @@ class ApplicationController < ActionController::Base
impersonated_user impersonated_user
end end
def impersonated_user
current_user
end
def log_impersonation_event
Gitlab::AppLogger.info("User #{impersonator.username} has stopped impersonating #{impersonated_user.username}")
end
def impersonator def impersonator
@impersonator ||= User.find(session[:impersonator_id]) if session[:impersonator_id] @impersonator ||= User.find(session[:impersonator_id]) if session[:impersonator_id]
end end
......
...@@ -94,6 +94,7 @@ recorded: ...@@ -94,6 +94,7 @@ recorded:
- Changed password - Changed password
- Ask for password reset - Ask for password reset
- Grant OAuth access - Grant OAuth access
- Started/stopped user impersonation
It is possible to filter particular actions by choosing an audit data type from It is possible to filter particular actions by choosing an audit data type from
the filter drop-down. You can further filter by specific group, project or user the filter drop-down. You can further filter by specific group, project or user
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
module EE module EE
module Admin module Admin
module UsersController module UsersController
extend ::Gitlab::Utils::Override
def reset_runners_minutes def reset_runners_minutes
user user
...@@ -17,6 +19,17 @@ module EE ...@@ -17,6 +19,17 @@ module EE
private private
override :log_impersonation_event
def log_impersonation_event
super
log_audit_event
end
def log_audit_event
AuditEvents::ImpersonationAuditEventService.new(current_user, request.remote_ip, 'Started Impersonation').for_user(user.username).security_event
end
def allowed_user_params def allowed_user_params
super + [ super + [
:note, :note,
......
...@@ -24,6 +24,17 @@ module EE ...@@ -24,6 +24,17 @@ module EE
private private
override :log_impersonation_event
def log_impersonation_event
super
log_audit_event
end
def log_audit_event
AuditEvents::ImpersonationAuditEventService.new(impersonator, request.remote_ip, 'Stopped Impersonation').for_user(impersonated_user.username).security_event
end
def set_current_ip_address(&block) def set_current_ip_address(&block)
::Gitlab::IpAddressState.with(request.ip, &block) # rubocop: disable CodeReuse/ActiveRecord ::Gitlab::IpAddressState.with(request.ip, &block) # rubocop: disable CodeReuse/ActiveRecord
end end
......
# frozen_string_literal: true
module EE
module AuditEvents
class ImpersonationAuditEventService < ::AuditEventService
def initialize(author, ip_address, message)
super(author, author, {
action: :custom,
custom_message: message,
ip_address: ip_address
})
end
end
end
end
---
title: Log impersonation actions in audit log
merge_request: 14740
author:
type: added
# frozen_string_literal: true
require 'spec_helper'
describe Admin::ImpersonationsController do
let(:impersonator) { create(:admin) }
let(:user) { create(:user) }
describe "DELETE destroy" do
context "when signed in" do
before do
sign_in(user)
end
context "when impersonating" do
before do
session[:impersonator_id] = impersonator.id
stub_licensed_features(extended_audit_events: true)
end
it 'creates an audit log record' do
expect { delete :destroy }.to change { SecurityEvent.count }.by(1)
end
end
end
end
end
...@@ -38,4 +38,14 @@ describe Admin::UsersController do ...@@ -38,4 +38,14 @@ describe Admin::UsersController do
end end
end end
end end
describe "POST #impersonate" do
before do
stub_licensed_features(extended_audit_events: true)
end
it 'creates an audit log record' do
expect { post :impersonate, params: { id: user.username } }.to change { SecurityEvent.count }.by(1)
end
end
end end
# frozen_string_literal: true
require 'spec_helper'
describe EE::AuditEvents::ImpersonationAuditEventService do
let(:impersonator) { create(:user) }
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) }
describe '#security_event' do
before do
stub_licensed_features(extended_audit_events: true)
end
it 'creates an event and logs to a file with the provided details' do
expect(service).to receive(:file_logger).and_return(logger)
expect(logger).to receive(:info).with(author_id: impersonator.id,
entity_id: impersonator.id,
entity_type: "User",
action: :custom,
ip_address: ip_address,
custom_message: message)
expect { service.security_event }.to change(SecurityEvent, :count).by(1)
security_event = SecurityEvent.last
expect(security_event.details).to eq(custom_message: message,
ip_address: ip_address,
action: :custom)
expect(security_event.author_id).to eq(impersonator.id)
expect(security_event.entity_id).to eq(impersonator.id)
expect(security_event.entity_type).to eq('User')
end
end
end
...@@ -279,6 +279,12 @@ describe Admin::UsersController do ...@@ -279,6 +279,12 @@ describe Admin::UsersController do
expect(warden.user).to eq(user) expect(warden.user).to eq(user)
end end
it 'logs the beginning of the impersonation event' do
expect(Gitlab::AppLogger).to receive(:info).with("User #{admin.username} has started impersonating #{user.username}").and_call_original
post :impersonate, params: { id: user.username }
end
it "redirects to root" do it "redirects to root" do
post :impersonate, params: { id: user.username } post :impersonate, params: { id: user.username }
......
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