audited 5.3.3 → 5.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +33 -20
  3. data/CHANGELOG.md +52 -1
  4. data/README.md +11 -3
  5. data/Rakefile +1 -3
  6. data/audited.gemspec +38 -0
  7. data/lib/audited/audit.rb +5 -1
  8. data/lib/audited/auditor.rb +49 -14
  9. data/lib/audited/version.rb +1 -1
  10. data/lib/audited.rb +11 -4
  11. data/lib/generators/audited/migration.rb +1 -1
  12. metadata +26 -59
  13. data/.github/workflows/buildlight.yml +0 -15
  14. data/.github/workflows/ci.yml +0 -134
  15. data/.gitignore +0 -17
  16. data/.standard.yml +0 -5
  17. data/.yardopts +0 -3
  18. data/gemfiles/rails50.gemfile +0 -11
  19. data/gemfiles/rails51.gemfile +0 -11
  20. data/gemfiles/rails52.gemfile +0 -11
  21. data/gemfiles/rails60.gemfile +0 -10
  22. data/gemfiles/rails61.gemfile +0 -10
  23. data/gemfiles/rails70.gemfile +0 -10
  24. data/spec/audited/audit_spec.rb +0 -357
  25. data/spec/audited/auditor_spec.rb +0 -1227
  26. data/spec/audited/rspec_matchers_spec.rb +0 -69
  27. data/spec/audited/sweeper_spec.rb +0 -133
  28. data/spec/audited_spec.rb +0 -14
  29. data/spec/audited_spec_helpers.rb +0 -32
  30. data/spec/rails_app/app/assets/config/manifest.js +0 -2
  31. data/spec/rails_app/config/application.rb +0 -19
  32. data/spec/rails_app/config/database.yml +0 -26
  33. data/spec/rails_app/config/environment.rb +0 -5
  34. data/spec/rails_app/config/environments/test.rb +0 -52
  35. data/spec/rails_app/config/initializers/backtrace_silencers.rb +0 -7
  36. data/spec/rails_app/config/initializers/inflections.rb +0 -2
  37. data/spec/rails_app/config/initializers/secret_token.rb +0 -3
  38. data/spec/rails_app/config/routes.rb +0 -3
  39. data/spec/spec_helper.rb +0 -24
  40. data/spec/support/active_record/models.rb +0 -170
  41. data/spec/support/active_record/postgres/1_change_audited_changes_type_to_json.rb +0 -11
  42. data/spec/support/active_record/postgres/2_change_audited_changes_type_to_jsonb.rb +0 -11
  43. data/spec/support/active_record/schema.rb +0 -90
  44. data/test/db/version_1.rb +0 -17
  45. data/test/db/version_2.rb +0 -18
  46. data/test/db/version_3.rb +0 -18
  47. data/test/db/version_4.rb +0 -19
  48. data/test/db/version_5.rb +0 -17
  49. data/test/db/version_6.rb +0 -19
  50. data/test/install_generator_test.rb +0 -62
  51. data/test/test_helper.rb +0 -18
  52. data/test/upgrade_generator_test.rb +0 -97
@@ -1,69 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Models::ActiveRecord::UserExceptPassword do
4
- let(:non_audited_columns) { subject.class.non_audited_columns }
5
-
6
- it { should_not be_audited.only(non_audited_columns) }
7
- it { should be_audited.except(:password) }
8
- it { should_not be_audited.requires_comment }
9
- it { should be_audited.on(:create, :update, :destroy) }
10
- # test chaining
11
- it { should be_audited.except(:password).on(:create, :update, :destroy) }
12
- end
13
-
14
- describe Models::ActiveRecord::UserOnlyPassword do
15
- let(:audited_columns) { subject.class.audited_columns }
16
-
17
- it { should be_audited.only(:password) }
18
- it { should_not be_audited.except(audited_columns) }
19
- it { should_not be_audited.requires_comment }
20
- it { should be_audited.on(:create, :update, :destroy) }
21
- it { should be_audited.only(:password).on(:create, :update, :destroy) }
22
- end
23
-
24
- describe Models::ActiveRecord::CommentRequiredUser do
25
- let(:audited_columns) { subject.class.audited_columns }
26
- let(:non_audited_columns) { subject.class.non_audited_columns }
27
-
28
- it { should_not be_audited.only(non_audited_columns) }
29
- it { should_not be_audited.except(audited_columns) }
30
- it { should be_audited.requires_comment }
31
- it { should be_audited.on(:create, :update, :destroy) }
32
- it { should be_audited.requires_comment.on(:create, :update, :destroy) }
33
- end
34
-
35
- describe Models::ActiveRecord::OnCreateCommentRequiredUser do
36
- let(:audited_columns) { subject.class.audited_columns }
37
- let(:non_audited_columns) { subject.class.non_audited_columns }
38
-
39
- it { should_not be_audited.only(non_audited_columns) }
40
- it { should_not be_audited.except(audited_columns) }
41
- it { should be_audited.requires_comment }
42
- it { should be_audited.on(:create) }
43
- it { should_not be_audited.on(:update, :destroy) }
44
- it { should be_audited.requires_comment.on(:create) }
45
- end
46
-
47
- describe Models::ActiveRecord::OnUpdateCommentRequiredUser do
48
- let(:audited_columns) { subject.class.audited_columns }
49
- let(:non_audited_columns) { subject.class.non_audited_columns }
50
-
51
- it { should_not be_audited.only(non_audited_columns) }
52
- it { should_not be_audited.except(audited_columns) }
53
- it { should be_audited.requires_comment }
54
- it { should be_audited.on(:update) }
55
- it { should_not be_audited.on(:create, :destroy) }
56
- it { should be_audited.requires_comment.on(:update) }
57
- end
58
-
59
- describe Models::ActiveRecord::OnDestroyCommentRequiredUser do
60
- let(:audited_columns) { subject.class.audited_columns }
61
- let(:non_audited_columns) { subject.class.non_audited_columns }
62
-
63
- it { should_not be_audited.only(non_audited_columns) }
64
- it { should_not be_audited.except(audited_columns) }
65
- it { should be_audited.requires_comment }
66
- it { should be_audited.on(:destroy) }
67
- it { should_not be_audited.on(:create, :update) }
68
- it { should be_audited.requires_comment.on(:destroy) }
69
- end
@@ -1,133 +0,0 @@
1
- require "spec_helper"
2
-
3
- SingleCov.covered!
4
-
5
- class AuditsController < ActionController::Base
6
- before_action :populate_user
7
-
8
- attr_reader :company
9
-
10
- def create
11
- @company = Models::ActiveRecord::Company.create
12
- head :ok
13
- end
14
-
15
- def update
16
- current_user.update!(password: "foo")
17
- head :ok
18
- end
19
-
20
- private
21
-
22
- attr_accessor :current_user
23
- attr_accessor :custom_user
24
-
25
- def populate_user
26
- end
27
- end
28
-
29
- describe AuditsController do
30
- include RSpec::Rails::ControllerExampleGroup
31
- render_views
32
-
33
- before do
34
- Audited::Railtie.initializers.each(&:run)
35
- Audited.current_user_method = :current_user
36
- end
37
-
38
- let(:user) { create_user }
39
-
40
- describe "POST audit" do
41
- it "should audit user" do
42
- controller.send(:current_user=, user)
43
- expect {
44
- post :create
45
- }.to change(Audited::Audit, :count)
46
-
47
- expect(controller.company.audits.last.user).to eq(user)
48
- end
49
-
50
- it "does not audit when method is not found" do
51
- controller.send(:current_user=, user)
52
- Audited.current_user_method = :nope
53
- expect {
54
- post :create
55
- }.to change(Audited::Audit, :count)
56
- expect(controller.company.audits.last.user).to eq(nil)
57
- end
58
-
59
- it "should support custom users for sweepers" do
60
- controller.send(:custom_user=, user)
61
- Audited.current_user_method = :custom_user
62
-
63
- expect {
64
- post :create
65
- }.to change(Audited::Audit, :count)
66
-
67
- expect(controller.company.audits.last.user).to eq(user)
68
- end
69
-
70
- it "should record the remote address responsible for the change" do
71
- request.env["REMOTE_ADDR"] = "1.2.3.4"
72
- controller.send(:current_user=, user)
73
-
74
- post :create
75
-
76
- expect(controller.company.audits.last.remote_address).to eq("1.2.3.4")
77
- end
78
-
79
- it "should record a UUID for the web request responsible for the change" do
80
- allow_any_instance_of(ActionDispatch::Request).to receive(:uuid).and_return("abc123")
81
- controller.send(:current_user=, user)
82
-
83
- post :create
84
-
85
- expect(controller.company.audits.last.request_uuid).to eq("abc123")
86
- end
87
-
88
- it "should call current_user after controller callbacks" do
89
- expect(controller).to receive(:populate_user) do
90
- controller.send(:current_user=, user)
91
- end
92
-
93
- expect {
94
- post :create
95
- }.to change(Audited::Audit, :count)
96
-
97
- expect(controller.company.audits.last.user).to eq(user)
98
- end
99
- end
100
-
101
- describe "PUT update" do
102
- it "should not save blank audits" do
103
- controller.send(:current_user=, user)
104
-
105
- expect {
106
- put :update, params: {id: 123}
107
- }.to_not change(Audited::Audit, :count)
108
- end
109
- end
110
- end
111
-
112
- describe Audited::Sweeper do
113
- it "should be thread-safe" do
114
- instance = Audited::Sweeper.new
115
-
116
- t1 = Thread.new do
117
- sleep 0.5
118
- instance.controller = "thread1 controller instance"
119
- expect(instance.controller).to eq("thread1 controller instance")
120
- end
121
-
122
- t2 = Thread.new do
123
- instance.controller = "thread2 controller instance"
124
- sleep 1
125
- expect(instance.controller).to eq("thread2 controller instance")
126
- end
127
-
128
- t1.join
129
- t2.join
130
-
131
- expect(instance.controller).to be_nil
132
- end
133
- end
data/spec/audited_spec.rb DELETED
@@ -1,14 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Audited do
4
- describe "#store" do
5
- describe "maintains state of store" do
6
- let(:current_user) { RequestStore.store[:audited_store] }
7
- before { Audited.store[:current_user] = current_user }
8
-
9
- it "checks store is not nil" do
10
- expect(Audited.store[:current_user]).to eq(current_user)
11
- end
12
- end
13
- end
14
- end
@@ -1,32 +0,0 @@
1
- module AuditedSpecHelpers
2
- def create_user(attrs = {})
3
- Models::ActiveRecord::User.create({name: "Brandon", username: "brandon", password: "password", favourite_device: "Android Phone"}.merge(attrs))
4
- end
5
-
6
- def build_user(attrs = {})
7
- Models::ActiveRecord::User.new({name: "darth", username: "darth", password: "noooooooo"}.merge(attrs))
8
- end
9
-
10
- def create_versions(n = 2, attrs = {})
11
- Models::ActiveRecord::User.create(name: "Foobar 1", **attrs).tap do |u|
12
- (n - 1).times do |i|
13
- u.update_attribute :name, "Foobar #{i + 2}"
14
- end
15
- u.reload
16
- end
17
- end
18
-
19
- def run_migrations(direction, migrations_paths, target_version = nil)
20
- if rails_below?("5.2.0.rc1")
21
- ActiveRecord::Migrator.send(direction, migrations_paths, target_version)
22
- elsif rails_below?("6.0.0.rc1")
23
- ActiveRecord::MigrationContext.new(migrations_paths).send(direction, target_version)
24
- else
25
- ActiveRecord::MigrationContext.new(migrations_paths, ActiveRecord::SchemaMigration).send(direction, target_version)
26
- end
27
- end
28
-
29
- def rails_below?(rails_version)
30
- Gem::Version.new(Rails::VERSION::STRING) < Gem::Version.new(rails_version)
31
- end
32
- end
@@ -1,2 +0,0 @@
1
- //= link application.js
2
- //= link application.css
@@ -1,19 +0,0 @@
1
- require "active_record/railtie"
2
-
3
- module RailsApp
4
- class Application < Rails::Application
5
- config.root = File.expand_path("../../", __FILE__)
6
- config.i18n.enforce_available_locales = true
7
-
8
- if !Rails.version.start_with?("5.0") && !Rails.version.start_with?("5.1") && config.active_record.respond_to?(:yaml_column_permitted_classes=)
9
- config.active_record.yaml_column_permitted_classes =
10
- %w[String Symbol Integer NilClass Float Time Date FalseClass Hash Array DateTime TrueClass BigDecimal
11
- ActiveSupport::TimeWithZone ActiveSupport::TimeZone ActiveSupport::HashWithIndifferentAccess]
12
- end
13
- end
14
- end
15
-
16
- require "active_record/connection_adapters/sqlite3_adapter"
17
- if ActiveRecord::ConnectionAdapters::SQLite3Adapter.respond_to?(:represent_boolean_as_integer)
18
- ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer = true
19
- end
@@ -1,26 +0,0 @@
1
- sqlite3mem: &SQLITE3MEM
2
- adapter: sqlite3
3
- database: ":memory:"
4
-
5
- sqlite3: &SQLITE
6
- adapter: sqlite3
7
- database: audited_test.sqlite3.db
8
-
9
- postgresql: &POSTGRES
10
- adapter: postgresql
11
- username: postgres
12
- password: postgres
13
- host: localhost
14
- database: audited_test
15
- min_messages: ERROR
16
-
17
- mysql: &MYSQL
18
- adapter: mysql2
19
- host: localhost
20
- username: root
21
- password: root
22
- database: audited_test
23
- charset: utf8
24
-
25
- test:
26
- <<: *<%= ENV['DB'] || 'SQLITE3MEM' %>
@@ -1,5 +0,0 @@
1
- # Load the rails application
2
- require File.expand_path("../application", __FILE__)
3
-
4
- # Initialize the rails application
5
- RailsApp::Application.initialize!
@@ -1,52 +0,0 @@
1
- RailsApp::Application.configure do
2
- # Settings specified here will take precedence over those in config/application.rb.
3
-
4
- # The test environment is used exclusively to run your application's
5
- # test suite. You never need to work with it otherwise. Remember that
6
- # your test database is "scratch space" for the test suite and is wiped
7
- # and recreated between test runs. Don't rely on the data there!
8
- config.cache_classes = true
9
-
10
- # Do not eager load code on boot. This avoids loading your whole application
11
- # just for the purpose of running a single test. If you are using a tool that
12
- # preloads Rails for running tests, you may have to set it to true.
13
- config.eager_load = false
14
-
15
- # Configure static file server for tests with Cache-Control for performance.
16
- if config.respond_to?(:public_file_server)
17
- config.public_file_server.enabled = true
18
- config.public_file_server.headers = {"Cache-Control" => "public, max-age=3600"}
19
- else
20
- config.static_cache_control = "public, max-age=3600"
21
- config.serve_static_files = true
22
- end
23
-
24
- # Show full error reports and disable caching.
25
- config.consider_all_requests_local = true
26
- # config.action_controller.perform_caching = false
27
-
28
- # Raise exceptions instead of rendering exception templates.
29
- config.action_dispatch.show_exceptions = false
30
-
31
- # Disable request forgery protection in test environment.
32
- # config.action_controller.allow_forgery_protection = false
33
-
34
- # Tell Action Mailer not to deliver emails to the real world.
35
- # The :test delivery method accumulates sent emails in the
36
- # ActionMailer::Base.deliveries array.
37
- # config.action_mailer.delivery_method = :test
38
-
39
- # Randomize the order test cases are executed.
40
- config.active_support.test_order = :random
41
-
42
- # Print deprecation notices to the stderr.
43
- config.active_support.deprecation = :stderr
44
-
45
- # Raises error for missing translations
46
- # config.action_view.raise_on_missing_translations = true
47
-
48
- if ::ActiveRecord::VERSION::MAJOR >= 7
49
- config.active_record.encryption.key_derivation_salt = SecureRandom.hex
50
- config.active_record.encryption.primary_key = SecureRandom.hex
51
- end
52
- end
@@ -1,7 +0,0 @@
1
- # Be sure to restart your server when you modify this file.
2
-
3
- # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
4
- # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
5
-
6
- # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
7
- Rails.backtrace_cleaner.remove_silencers!
@@ -1,2 +0,0 @@
1
- ActiveSupport::Inflector.inflections do |inflect|
2
- end
@@ -1,3 +0,0 @@
1
- Rails.application.config.secret_token = "ea942c41850d502f2c8283e26bdc57829f471bb18224ddff0a192c4f32cdf6cb5aa0d82b3a7a7adbeb640c4b06f3aa1cd5f098162d8240f669b39d6b49680571"
2
- Rails.application.config.session_store :cookie_store, key: "_my_app"
3
- Rails.application.config.secret_key_base = "secret value"
@@ -1,3 +0,0 @@
1
- Rails.application.routes.draw do
2
- resources :audits
3
- end
data/spec/spec_helper.rb DELETED
@@ -1,24 +0,0 @@
1
- ENV["RAILS_ENV"] = "test"
2
- require "bundler/setup"
3
- require "single_cov"
4
- SingleCov.setup :rspec
5
-
6
- if Bundler.definition.dependencies.map(&:name).include?("protected_attributes")
7
- require "protected_attributes"
8
- end
9
- require "rails_app/config/environment"
10
- require "rspec/rails"
11
- require "audited"
12
- require "audited-rspec"
13
- require "audited_spec_helpers"
14
- require "support/active_record/models"
15
-
16
- SPEC_ROOT = Pathname.new(File.expand_path("../", __FILE__))
17
-
18
- Dir[SPEC_ROOT.join("support/*.rb")].sort.each { |f| require f }
19
-
20
- RSpec.configure do |config|
21
- config.include AuditedSpecHelpers
22
- config.use_transactional_fixtures = false if Rails.version.start_with?("4.")
23
- config.use_transactional_tests = false if config.respond_to?(:use_transactional_tests=)
24
- end
@@ -1,170 +0,0 @@
1
- require "cgi"
2
- require File.expand_path("../schema", __FILE__)
3
-
4
- module Models
5
- module ActiveRecord
6
- class User < ::ActiveRecord::Base
7
- audited except: :password
8
- attribute :non_column_attr if Rails.version >= "5.1"
9
- attr_protected :logins if respond_to?(:attr_protected)
10
- enum status: {active: 0, reliable: 1, banned: 2}
11
- serialize :phone_numbers, Array
12
-
13
- def name=(val)
14
- write_attribute(:name, CGI.escapeHTML(val))
15
- end
16
- end
17
-
18
- class UserExceptPassword < ::ActiveRecord::Base
19
- self.table_name = :users
20
- audited except: :password
21
- end
22
-
23
- class UserOnlyPassword < ::ActiveRecord::Base
24
- self.table_name = :users
25
- attribute :non_column_attr if Rails.version >= "5.1"
26
- audited only: :password
27
- end
28
-
29
- class UserRedactedPassword < ::ActiveRecord::Base
30
- self.table_name = :users
31
- audited redacted: :password
32
- end
33
-
34
- class UserMultipleRedactedAttributes < ::ActiveRecord::Base
35
- self.table_name = :users
36
- audited redacted: [:password, :ssn]
37
- end
38
-
39
- class UserRedactedPasswordCustomRedaction < ::ActiveRecord::Base
40
- self.table_name = :users
41
- audited redacted: :password, redaction_value: ["My", "Custom", "Value", 7]
42
- end
43
-
44
- if ::ActiveRecord::VERSION::MAJOR >= 7
45
- class UserWithEncryptedPassword < ::ActiveRecord::Base
46
- self.table_name = :users
47
- audited
48
- encrypts :password
49
- end
50
- end
51
-
52
- class CommentRequiredUser < ::ActiveRecord::Base
53
- self.table_name = :users
54
- audited except: :password, comment_required: true
55
- end
56
-
57
- class OnCreateCommentRequiredUser < ::ActiveRecord::Base
58
- self.table_name = :users
59
- audited comment_required: true, on: :create
60
- end
61
-
62
- class OnUpdateCommentRequiredUser < ::ActiveRecord::Base
63
- self.table_name = :users
64
- audited comment_required: true, on: :update
65
- end
66
-
67
- class OnDestroyCommentRequiredUser < ::ActiveRecord::Base
68
- self.table_name = :users
69
- audited comment_required: true, on: :destroy
70
- end
71
-
72
- class NoUpdateWithCommentOnlyUser < ::ActiveRecord::Base
73
- self.table_name = :users
74
- audited update_with_comment_only: false
75
- end
76
-
77
- class AccessibleAfterDeclarationUser < ::ActiveRecord::Base
78
- self.table_name = :users
79
- audited
80
- attr_accessible :name, :username, :password if respond_to?(:attr_accessible)
81
- end
82
-
83
- class AccessibleBeforeDeclarationUser < ::ActiveRecord::Base
84
- self.table_name = :users
85
- attr_accessible :name, :username, :password if respond_to?(:attr_accessible) # declare attr_accessible before calling aaa
86
- audited
87
- end
88
-
89
- class NoAttributeProtectionUser < ::ActiveRecord::Base
90
- self.table_name = :users
91
- audited
92
- end
93
-
94
- class UserWithAfterAudit < ::ActiveRecord::Base
95
- self.table_name = :users
96
- audited
97
- attr_accessor :bogus_attr, :around_attr
98
-
99
- private
100
-
101
- def after_audit
102
- self.bogus_attr = "do something"
103
- end
104
-
105
- def around_audit
106
- self.around_attr = yield
107
- end
108
- end
109
-
110
- class MaxAuditsUser < ::ActiveRecord::Base
111
- self.table_name = :users
112
- audited max_audits: 5
113
- end
114
-
115
- class Company < ::ActiveRecord::Base
116
- audited
117
- end
118
-
119
- class Company::STICompany < Company
120
- end
121
-
122
- class Owner < ::ActiveRecord::Base
123
- self.table_name = "users"
124
- audited
125
- has_associated_audits
126
- has_many :companies, class_name: "OwnedCompany", dependent: :destroy
127
- accepts_nested_attributes_for :companies
128
- end
129
-
130
- class OwnedCompany < ::ActiveRecord::Base
131
- self.table_name = "companies"
132
- belongs_to :owner, class_name: "Owner", touch: true
133
- attr_accessible :name, :owner if respond_to?(:attr_accessible) # declare attr_accessible before calling aaa
134
- audited associated_with: :owner
135
- end
136
-
137
- class OwnedCompany::STICompany < OwnedCompany
138
- end
139
-
140
- class OnUpdateDestroy < ::ActiveRecord::Base
141
- self.table_name = "companies"
142
- audited on: [:update, :destroy]
143
- end
144
-
145
- class OnCreateDestroy < ::ActiveRecord::Base
146
- self.table_name = "companies"
147
- audited on: [:create, :destroy]
148
- end
149
-
150
- class OnCreateDestroyUser < ::ActiveRecord::Base
151
- self.table_name = "users"
152
- audited on: [:create, :destroy]
153
- end
154
-
155
- class OnCreateDestroyExceptName < ::ActiveRecord::Base
156
- self.table_name = "companies"
157
- audited except: :name, on: [:create, :destroy]
158
- end
159
-
160
- class OnCreateUpdate < ::ActiveRecord::Base
161
- self.table_name = "companies"
162
- audited on: [:create, :update]
163
- end
164
-
165
- class OnTouchOnly < ::ActiveRecord::Base
166
- self.table_name = "users"
167
- audited on: [:touch]
168
- end
169
- end
170
- end
@@ -1,11 +0,0 @@
1
- class ChangeAuditedChangesTypeToJson < ActiveRecord::Migration[5.0]
2
- def self.up
3
- remove_column :audits, :audited_changes
4
- add_column :audits, :audited_changes, :json
5
- end
6
-
7
- def self.down
8
- remove_column :audits, :audited_changes
9
- add_column :audits, :audited_changes, :text
10
- end
11
- end
@@ -1,11 +0,0 @@
1
- class ChangeAuditedChangesTypeToJsonb < ActiveRecord::Migration[5.0]
2
- def self.up
3
- remove_column :audits, :audited_changes
4
- add_column :audits, :audited_changes, :jsonb
5
- end
6
-
7
- def self.down
8
- remove_column :audits, :audited_changes
9
- add_column :audits, :audited_changes, :text
10
- end
11
- end