Skip to content
/ cia Public

Central Internal Auditing: Audit model events like update/create/delete + attribute changes + grouped them by transaction, in normalized table layout for easy query access.

Notifications You must be signed in to change notification settings

grosser/cia

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Central Internal Auditing

Audit model actions like update/create/destroy/ + attribute changes.

  • normalized and queryable through table layout
  • actors and subjects are polymorphic
  • works on ActiveRecord 4.2+

Table layout:

Event (actor/ip/time/updated subject + message) -> has many attribute changes (changed password from foo to bar on subject)

Install

gem install cia

rails g migration add_cia + paste Migration

Usage

class User < ActiveRecord::Base
  include CIA::Auditable
  audit_attribute :email, :crypted_password
end

class ApplicationController < ActionController::Base
  around_action :scope_auditing

  def scope_auditing(&block)
    CIA.audit actor: current_user, ip_address: request.remote_ip, &block
  end
end

# quick access
User.last.cia_events
changes = User.last.cia_attribute_changes
last_passwords = changes.where(attribute_name: "crypted_password").map(&:new_value)

# exceptions (raised by default)
CIA.exception_handler = -> (e) { raise e unless Rails.env.production? }

# conditional auditing
class User < ActiveRecord::Base
  audit_attribute :email, if: :interesting?

  def interesting?
    ...
  end
end

# adding an actor e.g. for user creation
CIA.current_actor = @user

# custom changes
class User < ActiveRecord::Base
  def cia_changes
    super.merge("this" => ["always", "changes"])
  end
end

# using after_commit, useful if the CIA::Event is stored in a different database then the audited class
class User < ActiveRecord::Base
  include CIA::Auditable
  audit_attribute :email, :crypted_password, callback: :after_commit
end

# passing arbitrary attributes into the .audit method
CIA.non_recordable_attributes = [:my_pretty_audit_property]
CIA.audit(actor: current_user, my_pretty_audit_property: "12345") do
  ...
end

# storing complex objects in old/new and reducing it's size if it's to big (serialized via json)
value = CIA::AttributeChange.serialize_for_storage(["some", "complex"*1000, "object"]){|too_big| too_big.delete_at(1); too_big }
CIA::AttributeChange.create!(old_value: value)

# add something to current transaction or start a new audit
CIA.audit bar: :baz, foo: :bang do
  CIA.amend_audit foo: :bar do
    puts CIA.current_transaction
  end
end
-> {foo: :bar, bar: :baz}

TODO

  • reuse AR3+ previous_changes in a nice way

Author

Michael Grosser
michael@grosser.it
License: MIT
CI

About

Central Internal Auditing: Audit model events like update/create/delete + attribute changes + grouped them by transaction, in normalized table layout for easy query access.

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages