appmospheres_audit 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ tmp/*
6
+ log/*
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/CHANGELOG ADDED
@@ -0,0 +1,8 @@
1
+ == 0.1.0
2
+ First release.
3
+
4
+ == 0.1.1
5
+ Also track ID of the changed record on update.
6
+
7
+ == 0.1.2
8
+ Added configuration options - it can filter out parameters/attributes and actions before logging.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in appmospheres_audit.gemspec
4
+ gemspec
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Appmospheres
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,24 @@
1
+ A gem for tracking model changes and controller actions.
2
+
3
+ USAGE
4
+ Run 'rails generate appmospheres_audit:migration' to generate the migration for the log events.
5
+ Run 'rails sappmospheres_audit:config' to generate a configuration initializer (in config/initializers/appmospheres_audit.rb).
6
+
7
+ Track models with enable_record_tracking:
8
+ class User < ActiveRecord::Base
9
+ enable_record_tracking
10
+ ...
11
+ end
12
+
13
+ Track actions with enable_action_tracking:
14
+ class MyController < ApplicationController
15
+ enable_action_tracking
16
+ ...
17
+ end
18
+
19
+ The payload of any event log record will be a YAML string. An event log tracking a model will record:
20
+ * on create: ID of the newly created record
21
+ * on update: list of changes (keys and values), excluding those explicitely filtered by setting Rails.application.config.filter_parameters and/or AppmospheresAudit.filter_parameters.
22
+ * on destroy: serialized record, excluding the attributes filtered by setting Rails.application.config.filter_parameters and/or AppmospheresAudit.filter_parameters.
23
+
24
+ Tracking actions in a controller will create an event log record with the name of the action and the parameters passed to the action, except those filtered by setting Rails.application.config.filter_parameters and/or AppmospheresAudit.filter_parameters.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/TODO ADDED
@@ -0,0 +1,3 @@
1
+ * Track the name of the controller, too
2
+ * Add some use cases, with code.
3
+
@@ -0,0 +1,32 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "appmospheres_audit/version"
4
+
5
+ Gem::Specification.new do |s|
6
+
7
+ s.name = "appmospheres_audit"
8
+ s.version = AppmospheresAudit::VERSION
9
+ s.authors = ["eugen neagoe", "Koen Handekyn"]
10
+ s.email = ["eugen.neagoe@appmospheres.com", "koen.handekyn@appmospheres.com"]
11
+ s.homepage = "https://github.com/appmospheres/appmospheres_audit"
12
+ s.summary = %q{A gem for tracking record changes and controller actions}
13
+ s.description = %q{A gem for tracking record changes and controller actions}
14
+
15
+ s.rubyforge_project = "appmospheres_audit"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.licenses = ['MIT']
23
+
24
+ s.add_dependency "rails", ">= 3.0.0"
25
+
26
+ s.add_development_dependency "ammeter"
27
+ s.add_development_dependency "database_cleaner"
28
+ s.add_development_dependency "rails", ">= 3.0.0"
29
+ s.add_development_dependency "rspec"
30
+ s.add_development_dependency "sqlite3"
31
+
32
+ end
@@ -0,0 +1,129 @@
1
+ require "active_record"
2
+ require "action_controller"
3
+
4
+ require "appmospheres_audit/version"
5
+ require "appmospheres_audit/event_log"
6
+
7
+ module AppmospheresAudit
8
+
9
+ def self.configure
10
+ yield(self) if block_given?
11
+ end
12
+
13
+ class << self
14
+
15
+ # stores a hash of options given to the +configure+ block.
16
+ def options
17
+ @options ||= {}
18
+ end
19
+
20
+ # set or get the configuration parameters
21
+ def method_missing(symbol, *args)
22
+ if (method = symbol.to_s).sub!(/\=$/, '')
23
+ options[method.to_sym] = args.first
24
+ else
25
+ options[method.to_sym]
26
+ end
27
+ end
28
+
29
+ end
30
+
31
+ module SupportTrail
32
+
33
+ def log_exception(ex)
34
+ begin
35
+ EventLog.create!(:event_type => ex.class.to_s, :action => "exception", :payload => ex.backtrace.to_yaml)
36
+ rescue
37
+ Rails.logger.warn "Could not log event 'exception' for #{ex.class.to_s}:#{ex.backtrace.inspect}" rescue nil
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ module RecordTrail
44
+
45
+ extend ActiveSupport::Concern
46
+
47
+ module ClassMethods
48
+
49
+ def enable_record_tracking
50
+ # set up after filters for create/update/destroy
51
+ after_create :track_create
52
+ after_update :track_update
53
+ after_destroy :track_destroy
54
+ end
55
+
56
+ end
57
+
58
+ def track_create
59
+ begin
60
+ EventLog.create!(:event_type => self.class.to_s, :action => "create", :payload => self.id.to_yaml)
61
+ rescue
62
+ Rails.logger.warn "Could not log event 'create' for #{self.class.to_s}:#{self.id}" rescue true
63
+ end
64
+ end
65
+
66
+ def track_update
67
+ begin
68
+ filtered_params = Rails.application.config.filter_parameters + (AppmospheresAudit.filter_parameters || [])
69
+ EventLog.create!(:event_type => self.class.to_s, :action => "update",
70
+ :payload => self.changes.merge({:id => self.id}).except(*filtered_params).to_yaml)
71
+ rescue
72
+ Rails.logger.warn "Could not log event 'update' for #{self.class.to_s}:#{self.changes.inspect}" rescue true
73
+ end
74
+ end
75
+
76
+ def track_destroy
77
+ begin
78
+ filtered_params = Rails.application.config.filter_parameters + (AppmospheresAudit.filter_parameters || [])
79
+ EventLog.create!(:event_type => self.class.to_s, :action => "destroy", :payload => self.serializable_hash.except(*filtered_params.map(&:to_s)).to_yaml)
80
+ rescue
81
+ Rails.logger.warn "Could not log event 'destroy' for #{self.class.to_s}:#{self.inspect}" rescue true
82
+ end
83
+ end
84
+
85
+ end
86
+
87
+ module ControllerTrail
88
+
89
+ def self.included(base)
90
+ base.extend ClassMethods
91
+ base.send :include, AppmospheresAudit::SupportTrail
92
+ end
93
+
94
+ module ClassMethods
95
+
96
+ def enable_action_tracking
97
+ around_filter do |controller, action|
98
+ begin
99
+ begin
100
+ filtered_actions = AppmospheresAudit.filter_actions || []
101
+ unless filtered_actions.include?(controller.action_name.to_sym) || filtered_actions.include?(controller.action_name)
102
+ filtered_params = Rails.application.config.filter_parameters + (AppmospheresAudit.filter_parameters || [])
103
+ EventLog.create!(:event_type => 'controller', :action => controller.request.parameters[:action],
104
+ :payload => controller.request.parameters.except(*filtered_params).to_yaml)
105
+ end
106
+ rescue
107
+ Rails.logger.warn "tracked #{controller.request.parameters.inspect}" rescue nil
108
+ end
109
+ action.call
110
+ rescue Exception => e
111
+ log_exception(e)
112
+ raise # again, so the execution continues as intended by the app
113
+ end
114
+ end
115
+ end
116
+
117
+ end
118
+
119
+ end
120
+
121
+ end
122
+
123
+ ActiveRecord::Base.class_eval do
124
+ include AppmospheresAudit::RecordTrail
125
+ end
126
+
127
+ ActionController::Base.class_eval do
128
+ include AppmospheresAudit::ControllerTrail
129
+ end
@@ -0,0 +1,5 @@
1
+ class EventLog < ActiveRecord::Base
2
+
3
+ attr_accessible :event_type, :action, :payload
4
+
5
+ end
@@ -0,0 +1,3 @@
1
+ module AppmospheresAudit
2
+ VERSION = "0.1.2"
3
+ end
@@ -0,0 +1,16 @@
1
+ require 'rails/generators'
2
+
3
+ module AppmospheresAudit
4
+
5
+ class ConfigGenerator < Rails::Generators::Base
6
+
7
+ source_root File.expand_path(File.dirname(__FILE__))
8
+
9
+ desc "Adds a config initializer to config/initializers/appmospheres.rb"
10
+ def copy_files
11
+ template 'templates/config/appmospheres.rb', 'config/initializers/appmospheres_audit.rb'
12
+ end
13
+
14
+ end
15
+
16
+ end
@@ -0,0 +1,43 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/migration'
3
+
4
+ module AppmospheresAudit
5
+
6
+ class MigrationGenerator < Rails::Generators::Base
7
+
8
+ include Rails::Generators::Migration
9
+
10
+ desc "Generates migration for the EventLog model"
11
+
12
+ def self.orm
13
+ Rails::Generators.options[:rails][:orm]
14
+ end
15
+
16
+ def self.source_root
17
+ File.join(File.dirname(__FILE__), 'templates', (orm.to_s unless orm.class.eql?(String)) )
18
+ end
19
+
20
+ def self.orm_has_migration?
21
+ [:active_record].include? orm
22
+ end
23
+
24
+ def self.next_migration_number(dirname)
25
+ if ActiveRecord::Base.timestamped_migrations
26
+ migration_number = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
27
+ migration_number += 1
28
+ migration_number.to_s
29
+ else
30
+ "%.3d" % (current_migration_number(dirname) + 1)
31
+ end
32
+ end
33
+
34
+ def create_migration_file
35
+ if self.class.orm_has_migration?
36
+ migration_template 'migration.rb', 'db/migrate/appmospheres_audit_migration'
37
+ end
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+
@@ -0,0 +1,24 @@
1
+ class AppmospheresAuditMigration < ActiveRecord::Migration
2
+
3
+ def self.up
4
+
5
+ create_table :event_logs do |t|
6
+ t.string :event_type
7
+ t.string :action
8
+ t.text :payload
9
+
10
+ t.datetime :reported_at
11
+ t.timestamps
12
+ end
13
+
14
+ add_index :event_logs, :event_type
15
+ add_index :event_logs, :action
16
+ add_index :event_logs, :reported_at
17
+
18
+ end
19
+
20
+ def self.down
21
+ drop_table :event_logs
22
+ end
23
+
24
+ end
@@ -0,0 +1,6 @@
1
+ AppmospheresAudit.configure do |config|
2
+ # the parameters listed here will not be serialized in the event logs
3
+ config.filter_parameters = [:password]
4
+ # the actions listed here will not be recorded in the event logs
5
+ #config.filter_actions = [:edit, :new]
6
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe AppmospheresAudit::ControllerTrail do
4
+
5
+ describe "enable_action_tracking", :type => :request do
6
+
7
+ it "should record every controller action when enabled" do
8
+ expect { get '/users' }.to change(EventLog, :count).by(1)
9
+ end
10
+
11
+ it "should not track filtered actions" do
12
+ AppmospheresAudit.filter_actions = [:index]
13
+ expect { get '/users' }.not_to change(EventLog, :count)
14
+ end
15
+
16
+ end
17
+
18
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe AppmospheresAudit::SupportTrail do
4
+
5
+ describe 'log_exception' do
6
+
7
+ include AppmospheresAudit::SupportTrail
8
+
9
+ it "should create an event log record" do
10
+ expect { log_exception(Exception.new) }.to change(EventLog, :count).by(1)
11
+ end
12
+
13
+ end
14
+
15
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe AppmospheresAudit::RecordTrail do
4
+
5
+ describe "enable_record_tracking" do
6
+
7
+ before(:each) { User.create! }
8
+
9
+ describe "create" do
10
+ it "should create an event log when a new record is created" do
11
+ expect { User.create! }.to change(EventLog, :count).by(1)
12
+ end
13
+ end
14
+
15
+ describe "update" do
16
+
17
+ it "should create an event log when a record is updated" do
18
+ expect { User.first.update_attribute(:name, "") }.to change(EventLog, :count).by(1)
19
+ end
20
+
21
+ it "should not include filtered parameters in the event log payload" do
22
+ AppmospheresAudit.filter_parameters = [:name]
23
+ User.first.update_attribute(:name, "changed")
24
+ changes = YAML::load(EventLog.where(:event_type => 'User', :action => 'update').last.payload)
25
+ changes.should_not include(:name)
26
+ end
27
+
28
+ end
29
+
30
+ describe "destroy" do
31
+
32
+ it "should create an event log when a record is deleted" do
33
+ expect { User.first.destroy }.to change(EventLog, :count).by(1)
34
+ end
35
+
36
+ it "should not include filtered parameters in the event log payload" do
37
+ AppmospheresAudit.filter_parameters = [:name]
38
+ User.first.destroy
39
+ record = YAML::load(EventLog.where(:event_type => 'User', :action => 'destroy').last.payload)
40
+ record.should_not include(:name)
41
+ end
42
+
43
+ end
44
+
45
+ end
46
+
47
+ end
data/spec/fake_app.rb ADDED
@@ -0,0 +1,65 @@
1
+ require 'active_record'
2
+ require 'action_controller/railtie'
3
+ require 'action_view/railtie'
4
+
5
+ # database
6
+ ActiveRecord::Base.configurations = {'test' => {:adapter => 'sqlite3', :database => ':memory:'}}
7
+ ActiveRecord::Base.establish_connection('test')
8
+
9
+ # config
10
+ app = Class.new(Rails::Application)
11
+ app.config.secret_token = "fada08cee25221c8f94cd4469710c402fc40c4100a2f72f101f18233002f7016fc7004c09e68e201dbcf1bf92d5bfec98638ac239590980352e56b406dc50286"
12
+ app.config.session_store :cookie_store, :key => "_myfakeapp_session"
13
+ app.config.active_support.deprecation = :log
14
+ app.initialize!
15
+
16
+ # routes
17
+ app.routes.draw do
18
+ resources :users
19
+ end
20
+
21
+ # models
22
+ class User < ActiveRecord::Base
23
+ enable_record_tracking
24
+ end
25
+
26
+ # controllers
27
+ class ApplicationController < ActionController::Base
28
+ enable_action_tracking
29
+ end
30
+ class UsersController < ApplicationController
31
+ def index
32
+ @users = User.all
33
+ render :inline => <<-ERB
34
+ <%= @users.map(&:name).join("\n") %>
35
+ ERB
36
+ end
37
+ end
38
+
39
+ # helpers
40
+ Object.const_set(:ApplicationHelper, Module.new)
41
+
42
+ #migrations
43
+ class CreateAllTables < ActiveRecord::Migration
44
+
45
+ def self.up
46
+
47
+ create_table(:users) {|t| t.string :name }
48
+
49
+ create_table :event_logs do |t|
50
+ t.string :event_type
51
+ t.string :action
52
+ t.text :payload
53
+
54
+ t.datetime :reported_at
55
+ t.timestamps
56
+ end
57
+
58
+ end
59
+
60
+ def self.down
61
+ drop_table :event_logs
62
+ drop_table :users
63
+ end
64
+
65
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ # Generators are not automatically loaded by Rails
4
+ require 'generators/appmospheres_audit/migration_generator'
5
+
6
+ describe AppmospheresAudit::MigrationGenerator do
7
+
8
+ # Tell the generator where to put its output (what it thinks of as Rails.root)
9
+ destination File.expand_path("../../../../../tmp", __FILE__)
10
+
11
+ before do
12
+ prepare_destination
13
+ Rails::Generators.options[:rails][:orm] = :active_record
14
+ end
15
+
16
+ describe 'no arguments' do
17
+
18
+ before { run_generator }
19
+
20
+ describe 'db/migrate/appmospheres_audit_migration.rb' do
21
+ subject { file('db/migrate/appmospheres_audit_migration.rb') }
22
+ it { should be_a_migration }
23
+ end
24
+
25
+ end
26
+
27
+ end
@@ -0,0 +1,13 @@
1
+ $LOAD_PATH << "." unless $LOAD_PATH.include?(".")
2
+ require 'rails'
3
+ require File.expand_path('../../lib/appmospheres_audit', __FILE__)
4
+ require 'ammeter/init'
5
+ require 'database_cleaner'
6
+ require 'fake_app'
7
+ require 'rspec/rails'
8
+
9
+ RSpec.configure do |config|
10
+ config.before :all do
11
+ CreateAllTables.up unless ActiveRecord::Base.connection.table_exists? :users
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ DatabaseCleaner.strategy = :transaction
2
+
3
+ RSpec.configure do |config|
4
+ config.before :suite do
5
+ DatabaseCleaner.clean_with :truncation
6
+ end
7
+ config.before :each do
8
+ DatabaseCleaner.start
9
+ end
10
+ config.after :each do
11
+ DatabaseCleaner.clean
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,184 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: appmospheres_audit
3
+ version: !ruby/object:Gem::Version
4
+ hash: 31
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 2
10
+ version: 0.1.2
11
+ platform: ruby
12
+ authors:
13
+ - eugen neagoe
14
+ - Koen Handekyn
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2012-02-27 00:00:00 Z
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rails
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 7
30
+ segments:
31
+ - 3
32
+ - 0
33
+ - 0
34
+ version: 3.0.0
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: ammeter
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 3
46
+ segments:
47
+ - 0
48
+ version: "0"
49
+ type: :development
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ name: database_cleaner
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 3
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ type: :development
64
+ version_requirements: *id003
65
+ - !ruby/object:Gem::Dependency
66
+ name: rails
67
+ prerelease: false
68
+ requirement: &id004 !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ hash: 7
74
+ segments:
75
+ - 3
76
+ - 0
77
+ - 0
78
+ version: 3.0.0
79
+ type: :development
80
+ version_requirements: *id004
81
+ - !ruby/object:Gem::Dependency
82
+ name: rspec
83
+ prerelease: false
84
+ requirement: &id005 !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ hash: 3
90
+ segments:
91
+ - 0
92
+ version: "0"
93
+ type: :development
94
+ version_requirements: *id005
95
+ - !ruby/object:Gem::Dependency
96
+ name: sqlite3
97
+ prerelease: false
98
+ requirement: &id006 !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ hash: 3
104
+ segments:
105
+ - 0
106
+ version: "0"
107
+ type: :development
108
+ version_requirements: *id006
109
+ description: A gem for tracking record changes and controller actions
110
+ email:
111
+ - eugen.neagoe@appmospheres.com
112
+ - koen.handekyn@appmospheres.com
113
+ executables: []
114
+
115
+ extensions: []
116
+
117
+ extra_rdoc_files: []
118
+
119
+ files:
120
+ - .gitignore
121
+ - .rspec
122
+ - CHANGELOG
123
+ - Gemfile
124
+ - MIT-LICENSE
125
+ - README
126
+ - Rakefile
127
+ - TODO
128
+ - appmospheres_audit.gemspec
129
+ - lib/appmospheres_audit.rb
130
+ - lib/appmospheres_audit/event_log.rb
131
+ - lib/appmospheres_audit/version.rb
132
+ - lib/generators/appmospheres_audit/config_generator.rb
133
+ - lib/generators/appmospheres_audit/migration_generator.rb
134
+ - lib/generators/appmospheres_audit/templates/active_record/migration.rb
135
+ - lib/generators/appmospheres_audit/templates/config/appmospheres.rb
136
+ - spec/appmospheres_audit/action_tracking_spec.rb
137
+ - spec/appmospheres_audit/exception_logger_spec.rb
138
+ - spec/appmospheres_audit/record_tracking_spec.rb
139
+ - spec/fake_app.rb
140
+ - spec/generators/appmospheres_audit/migration/migration_generator_spec.rb
141
+ - spec/spec_helper.rb
142
+ - spec/support/database_cleaner.rb
143
+ homepage: https://github.com/appmospheres/appmospheres_audit
144
+ licenses:
145
+ - MIT
146
+ post_install_message:
147
+ rdoc_options: []
148
+
149
+ require_paths:
150
+ - lib
151
+ required_ruby_version: !ruby/object:Gem::Requirement
152
+ none: false
153
+ requirements:
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ hash: 3
157
+ segments:
158
+ - 0
159
+ version: "0"
160
+ required_rubygems_version: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ hash: 3
166
+ segments:
167
+ - 0
168
+ version: "0"
169
+ requirements: []
170
+
171
+ rubyforge_project: appmospheres_audit
172
+ rubygems_version: 1.8.17
173
+ signing_key:
174
+ specification_version: 3
175
+ summary: A gem for tracking record changes and controller actions
176
+ test_files:
177
+ - spec/appmospheres_audit/action_tracking_spec.rb
178
+ - spec/appmospheres_audit/exception_logger_spec.rb
179
+ - spec/appmospheres_audit/record_tracking_spec.rb
180
+ - spec/fake_app.rb
181
+ - spec/generators/appmospheres_audit/migration/migration_generator_spec.rb
182
+ - spec/spec_helper.rb
183
+ - spec/support/database_cleaner.rb
184
+ has_rdoc: