Module: Legion::Audit

Defined in:
lib/legion/audit.rb,
lib/legion/audit/archiver.rb,
lib/legion/audit/hash_chain.rb,
lib/legion/audit/siem_export.rb,
lib/legion/audit/cold_storage.rb,
lib/legion/audit/archiver_actor.rb

Defined Under Namespace

Modules: Archiver, ColdStorage, HashChain, SiemExport Classes: ArchiverActor

Class Method Summary collapse

Class Method Details

.count_for(principal_id:, window: 3600, event_type: nil, status: nil) ⇒ Object



37
38
39
40
41
42
43
44
45
46
# File 'lib/legion/audit.rb', line 37

def count_for(principal_id:, window: 3600, event_type: nil, status: nil)
  return 0 unless defined?(Legion::Data::Model::AuditLog)

  ds = Legion::Data::Model::AuditLog
       .where(principal_id: principal_id)
       .where { created_at >= Time.now.utc - window }
  ds = ds.where(event_type: event_type) unless event_type.nil?
  ds = ds.where(status: status) unless status.nil?
  ds.count
end

.failure_count_for(principal_id:, window: 3600) ⇒ Object



48
49
50
# File 'lib/legion/audit.rb', line 48

def failure_count_for(principal_id:, window: 3600)
  count_for(principal_id: principal_id, window: window, status: 'failure')
end

.recent(limit: 50, **filters) ⇒ Object



66
67
68
69
70
71
72
# File 'lib/legion/audit.rb', line 66

def recent(limit: 50, **filters)
  return [] unless defined?(Legion::Data::Model::AuditLog)

  ds = Legion::Data::Model::AuditLog.order(Sequel.desc(:created_at)).limit(limit)
  filters.each { |col, val| ds = ds.where(col => val) }
  ds.all
end

.recent_for(principal_id:, window: 3600, event_type: nil, status: nil) ⇒ Object



26
27
28
29
30
31
32
33
34
35
# File 'lib/legion/audit.rb', line 26

def recent_for(principal_id:, window: 3600, event_type: nil, status: nil)
  return [] unless defined?(Legion::Data::Model::AuditLog)

  ds = Legion::Data::Model::AuditLog
       .where(principal_id: principal_id)
       .where { created_at >= Time.now.utc - window }
  ds = ds.where(event_type: event_type) unless event_type.nil?
  ds = ds.where(status: status) unless status.nil?
  ds.all
end

.record(event_type:, principal_id:, action:, resource:, **opts) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/legion/audit.rb', line 6

def record(event_type:, principal_id:, action:, resource:, **opts)
  return unless transport_available?

  Legion::Extensions::Audit::Transport::Messages::Audit.new(
    event_type:     event_type,
    principal_id:   principal_id,
    principal_type: opts[:principal_type] || 'system',
    action:         action,
    resource:       resource,
    source:         opts[:source] || 'unknown',
    node:           node_name,
    status:         opts[:status] || 'success',
    duration_ms:    opts[:duration_ms],
    detail:         opts[:detail],
    created_at:     Time.now.utc.iso8601
  ).publish
rescue StandardError => e
  Legion::Logging.error "[Audit] publish failed event_type=#{event_type} resource=#{resource}: #{e.message}" if defined?(Legion::Logging)
end

.resources_for(principal_id:, window: 3600) ⇒ Object



56
57
58
59
60
61
62
63
64
# File 'lib/legion/audit.rb', line 56

def resources_for(principal_id:, window: 3600)
  return [] unless defined?(Legion::Data::Model::AuditLog)

  Legion::Data::Model::AuditLog
    .where(principal_id: principal_id)
    .where { created_at >= Time.now.utc - window }
    .select_map(:resource)
    .uniq
end

.success_count_for(principal_id:, window: 3600) ⇒ Object



52
53
54
# File 'lib/legion/audit.rb', line 52

def success_count_for(principal_id:, window: 3600)
  count_for(principal_id: principal_id, window: window, status: 'success')
end