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:
@@ -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
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -77,4 +77,4 @@ class AutomationRule < ApplicationRecord
|
||||
end
|
||||
end
|
||||
|
||||
AutomationRule.include_mod_with('Audit::Inbox')
|
||||
AutomationRule.include_mod_with('Audit::AutomationRule')
|
||||
|
||||
@@ -166,3 +166,5 @@ class User < ApplicationRecord
|
||||
macros.personal.destroy_all
|
||||
end
|
||||
end
|
||||
|
||||
User.include_mod_with('Audit::User')
|
||||
|
||||
@@ -38,4 +38,4 @@ class Webhook < ApplicationRecord
|
||||
end
|
||||
end
|
||||
|
||||
Webhook.include_mod_with('Audit::Inbox')
|
||||
Webhook.include_mod_with('Audit::Webhook')
|
||||
|
||||
@@ -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
|
||||
13
enterprise/app/models/enterprise/audit/user.rb
Normal file
13
enterprise/app/models/enterprise/audit/user.rb
Normal 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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user