feat: add audit trail for sign_in and sign_out (#7158)

* feat: add audit_trail for sign_in event

* chore: ignore unrelated User model columns for auditing

* chore: fix prepend call for webhook/automation rule

* chore: add spec for sign_in event

* chore: refactor sign_in auditlog method to enterprise namespace

* feat: add sign_out audit trail

* feat: review comments
This commit is contained in:
Vishnu Narayanan
2023-05-25 14:27:30 +05:30
committed by GitHub
parent 88cef88d80
commit 123fc73394
8 changed files with 98 additions and 3 deletions

View File

@@ -784,8 +784,8 @@ GEM
PLATFORMS
arm64-darwin-20
arm64-darwin-22
arm64-darwin-21
arm64-darwin-22
ruby
x86_64-darwin-18
x86_64-darwin-20

View File

@@ -37,3 +37,5 @@ class DeviseOverrides::SessionsController < DeviseTokenAuth::SessionsController
@resource = user if user&.valid_sso_auth_token?(params[:sso_auth_token])
end
end
DeviseOverrides::SessionsController.prepend_mod_with('DeviseOverrides::SessionsController')

View File

@@ -77,4 +77,4 @@ class AutomationRule < ApplicationRecord
end
end
AutomationRule.include_mod_with('Audit::Inbox')
AutomationRule.include_mod_with('Audit::AutomationRule')

View File

@@ -166,3 +166,5 @@ class User < ApplicationRecord
macros.personal.destroy_all
end
end
User.include_mod_with('Audit::User')

View File

@@ -38,4 +38,4 @@ class Webhook < ApplicationRecord
end
end
Webhook.include_mod_with('Audit::Inbox')
Webhook.include_mod_with('Audit::Webhook')

View File

@@ -0,0 +1,25 @@
module Enterprise::DeviseOverrides::SessionsController
def render_create_success
create_audit_event('sign_in')
super
end
def destroy
create_audit_event('sign_out')
super
end
def create_audit_event(action)
return unless @resource
associated_type = 'Account'
@resource.accounts.each do |account|
@resource.audits.create(
action: action,
user_id: @resource.id,
associated_id: account.id,
associated_type: associated_type
)
end
end
end

View File

@@ -0,0 +1,13 @@
module Enterprise::Audit::User
extend ActiveSupport::Concern
included do
audited only: [
:availability,
:display_name,
:email,
:name
]
audited associated_with: :account
end
end

View File

@@ -0,0 +1,53 @@
require 'rails_helper'
RSpec.describe 'Enterprise Audit API', type: :request do
let!(:account) { create(:account) }
let!(:user) { create(:user, password: 'Password1!', account: account) }
describe 'POST /sign_in' do
it 'creates a sign_in audit event wwith valid credentials' do
params = { email: user.email, password: 'Password1!' }
expect do
post new_user_session_url,
params: params,
as: :json
end.to change(Enterprise::AuditLog, :count).by(1)
expect(response).to have_http_status(:success)
expect(response.body).to include(user.email)
# Check if the sign_in event is created
user.reload
expect(user.audits.last.action).to eq('sign_in')
expect(user.audits.last.associated_id).to eq(account.id)
expect(user.audits.last.associated_type).to eq('Account')
end
it 'will not create a sign_in audit event with invalid credentials' do
params = { email: user.email, password: 'invalid' }
expect do
post new_user_session_url,
params: params,
as: :json
end.not_to change(Enterprise::AuditLog, :count)
end
end
describe 'DELETE /sign_out' do
context 'when it is an authenticated user' do
it 'signs out the user and creates an audit event' do
expect do
delete '/auth/sign_out', headers: user.create_new_auth_token
end.to change(Enterprise::AuditLog, :count).by(1)
expect(response).to have_http_status(:success)
user.reload
expect(user.audits.last.action).to eq('sign_out')
expect(user.audits.last.associated_id).to eq(account.id)
expect(user.audits.last.associated_type).to eq('Account')
end
end
end
end