-
Notifications
You must be signed in to change notification settings - Fork 124
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2693 from cyberark/audit-list-memberships
Add: audit event to GET /roles/:account/:kind/*identifier?memberships
- Loading branch information
Showing
5 changed files
with
240 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
module Audit | ||
module Event | ||
class Memberships | ||
def initialize( | ||
user_id:, | ||
client_ip:, | ||
success:, | ||
subject:, | ||
error_message: nil | ||
) | ||
@user_id = user_id | ||
@client_ip = client_ip | ||
@subject = subject | ||
@success = success | ||
@error_message = error_message | ||
|
||
# Implements `==` for audit events | ||
@comparable_evt = ComparableEvent.new(self) | ||
end | ||
|
||
# NOTE: We want this class to be responsible for providing `progname`. | ||
# At the same time, `progname` is currently always "conjur" and this is | ||
# unlikely to change. Moving `progname` into the constructor now | ||
# feels like premature optimization, so we ignore reek here. | ||
# :reek:UtilityFunction | ||
def progname | ||
Event.progname | ||
end | ||
|
||
def severity | ||
attempted_action.severity | ||
end | ||
|
||
def to_s | ||
message | ||
end | ||
|
||
# action_sd means "action structured data" | ||
def action_sd | ||
attempted_action.action_sd | ||
end | ||
|
||
def message | ||
attempted_action.message( | ||
success_msg: "#{@user_id} successfully listed memberships with parameters: #{@subject}", | ||
failure_msg: "#{@user_id} failed to list memberships with parameters: #{@subject}", | ||
error_msg: @error_message | ||
) | ||
end | ||
|
||
def message_id | ||
'membership' | ||
end | ||
|
||
def structured_data | ||
{ | ||
SDID::AUTH => { user: @user_id }, | ||
SDID::SUBJECT => @subject, | ||
SDID::CLIENT => { ip: @client_ip } | ||
}.merge( | ||
attempted_action.action_sd | ||
) | ||
end | ||
|
||
def facility | ||
# Security or authorization messages which should be kept private. See: | ||
# https://github.com/ruby/ruby/blob/master/ext/syslog/syslog.c#L109 | ||
# Note: Changed this to from LOG_AUTH to LOG_AUTHPRIV because the former | ||
# is deprecated. | ||
Syslog::LOG_AUTHPRIV | ||
end | ||
|
||
def ==(other) | ||
@comparable_evt == other | ||
end | ||
|
||
private | ||
|
||
def attempted_action | ||
@attempted_action ||= AttemptedAction.new( | ||
success: @success, | ||
operation: 'list' | ||
) | ||
end | ||
end | ||
|
||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
require 'spec_helper' | ||
|
||
describe Audit::Event::Memberships do | ||
let(:user_id) { 'rspec:user:my_user' } | ||
let(:client_ip) { 'my-client-ip' } | ||
let(:list_param) { { "limit"=> "1000" } } | ||
let(:success) { true } | ||
let(:error_message) { nil } | ||
|
||
|
||
subject do | ||
Audit::Event::Memberships.new( | ||
user_id: user_id, | ||
client_ip: client_ip, | ||
subject: list_param, | ||
success: success, | ||
error_message: error_message | ||
) | ||
end | ||
|
||
context 'when successful' do | ||
it 'produces the expected message' do | ||
expect(subject.message).to eq( | ||
'rspec:user:my_user successfully listed memberships with parameters: {"limit"=>"1000"}' | ||
) | ||
end | ||
|
||
it 'uses the INFO log level' do | ||
expect(subject.severity).to eq(Syslog::LOG_INFO) | ||
end | ||
|
||
it 'renders to string correctly' do | ||
expect(subject.to_s).to eq( | ||
'rspec:user:my_user successfully listed memberships with parameters: {"limit"=>"1000"}' | ||
) | ||
end | ||
|
||
it 'contains the user field' do | ||
expect(subject.structured_data).to match(hash_including({ | ||
Audit::SDID::AUTH => { user: user_id } | ||
})) | ||
end | ||
|
||
it 'contains the ip field' do | ||
expect(subject.structured_data).to match(hash_including({ | ||
Audit::SDID::CLIENT => { ip: client_ip } | ||
})) | ||
end | ||
|
||
it 'produces the expected action_sd' do | ||
expect(subject.action_sd).to eq({ "action@43868": { operation: "list", result: "success" } }) | ||
end | ||
|
||
it_behaves_like 'structured data includes client IP address' | ||
end | ||
|
||
context 'when a failure occurs' do | ||
let(:success) { false } | ||
|
||
it 'produces the expected message' do | ||
expect(subject.message).to eq( | ||
'rspec:user:my_user failed to list memberships with parameters: {"limit"=>"1000"}' | ||
) | ||
end | ||
|
||
it 'uses the WARNING log level' do | ||
expect(subject.severity).to eq(Syslog::LOG_WARNING) | ||
end | ||
|
||
it 'produces the expected action_sd' do | ||
expect(subject.action_sd).to eq({ "action@43868": { operation: "list", result: "failure" } }) | ||
end | ||
|
||
it_behaves_like 'structured data includes client IP address' | ||
end | ||
|
||
|
||
|
||
end |