audited 5.0.1 → 5.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of audited might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f924caa522dc6d65c88066c2d28416dfcef844efa85bdef056da226db12a8984
4
- data.tar.gz: 63bdef3cd4aefea080eb36e6b7c394f5d97b465e3376027a68e3c28f1b278d5c
3
+ metadata.gz: 86131fd51439ffb0e1e16fd0b3bdd770c0cdf6de5bc8df5f234377d9ef0aeddb
4
+ data.tar.gz: 4729941ef95dc9e6e542eb705ac12ff4876999c61f210a50d8ef460a02d71078
5
5
  SHA512:
6
- metadata.gz: acbc5581e27594c84ad817ac7e2f90e02d34786106689a943177552890205d4acfaa5a7ac5489b1a0fbdbc5196028d462e4540d5253ee78b2612bc8f03abfcad
7
- data.tar.gz: 532724043c0c57659a3c3f3d0eaf21c832a6c3863a8607bb802d882bf13b4579e8b051265e6c4082a51bdbc2291f7466508e03c7cb67df90bda6b8c234a6d7a4
6
+ metadata.gz: 27d6c2bd685eaca06093e7b8352aa942b83163a09be96fade16cc39ac46502697ca264a54f7a99a4390afe6cc07fbca0d345cb4ad35d7a11d98fa8da9aa262dd
7
+ data.tar.gz: 615ffae5d0fe3a44ffde034ddd60a2074cdff6679b1a8d59b23adfa2fed557023ffd786516997627aaf3de7916c39666d85abd24b38b1562976678472bbc85a9
@@ -0,0 +1,15 @@
1
+ name: Buildlight
2
+
3
+ on:
4
+ workflow_run:
5
+ workflows:
6
+ - CI
7
+ branches:
8
+ - main
9
+
10
+ jobs:
11
+ webhook:
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - name: Webhook
15
+ uses: collectiveidea/buildlight@main
@@ -0,0 +1,128 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches:
7
+ - main
8
+
9
+ jobs:
10
+ build:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ ruby: [2.3, 2.4, 2.5, 2.6, 2.7, 3.0, 3.1]
16
+ appraisal:
17
+ - rails50
18
+ - rails51
19
+ - rails52
20
+ - rails60
21
+ - rails61
22
+ - rails70
23
+ db: [POSTGRES, MYSQL, SQLITE]
24
+ exclude:
25
+ # MySQL has issues on Ruby 2.3
26
+ # https://github.com/ruby/setup-ruby/issues/150
27
+ - ruby: 2.3
28
+ db: MYSQL
29
+
30
+ # PostgreSQL is segfaulting on 2.3
31
+ # Doesn't seem worth solving.
32
+ - ruby: 2.3
33
+ db: POSTGRES
34
+
35
+ # Rails 5.0 supports Ruby 2.2-2.4
36
+ - appraisal: rails50
37
+ ruby: 2.5
38
+ - appraisal: rails50
39
+ ruby: 2.6
40
+ - appraisal: rails50
41
+ ruby: 2.7
42
+ - appraisal: rails50
43
+ ruby: 3.0
44
+ - appraisal: rails50
45
+ ruby: 3.1
46
+
47
+ # Rails 5.1 supports Ruby 2.2-2.5
48
+ - appraisal: rails51
49
+ ruby: 2.6
50
+ - appraisal: rails51
51
+ ruby: 2.7
52
+ - appraisal: rails51
53
+ ruby: 3.0
54
+ - appraisal: rails51
55
+ ruby: 3.1
56
+
57
+ # Rails 5.2 supports Ruby 2.2-2.5
58
+ - appraisal: rails52
59
+ ruby: 2.6
60
+ - appraisal: rails52
61
+ ruby: 2.7
62
+ - appraisal: rails52
63
+ ruby: 3.0
64
+ - appraisal: rails52
65
+ ruby: 3.1
66
+
67
+ # Rails 6.0 supports Ruby 2.5-2.7
68
+ - appraisal: rails60
69
+ ruby: 2.3
70
+ - appraisal: rails60
71
+ ruby: 2.4
72
+ - appraisal: rails60
73
+ ruby: 3.0
74
+ - appraisal: rails60
75
+ ruby: 3.1
76
+
77
+ # Rails 6.1 supports Ruby 2.5+
78
+ - appraisal: rails61
79
+ ruby: 2.3
80
+ - appraisal: rails61
81
+ ruby: 2.4
82
+
83
+ # Rails 7 supports Ruby 2.7+
84
+ - appraisal: rails70
85
+ ruby: 2.3
86
+ - appraisal: rails70
87
+ ruby: 2.4
88
+ - appraisal: rails70
89
+ ruby: 2.5
90
+ - appraisal: rails70
91
+ ruby: 2.6
92
+
93
+ services:
94
+ postgres:
95
+ image: postgres
96
+ env:
97
+ POSTGRES_USER: postgres
98
+ POSTGRES_PASSWORD: postgres
99
+ POSTGRES_DB: audited_test
100
+ ports:
101
+ - 5432:5432
102
+ # needed because the postgres container does not provide a healthcheck
103
+ options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
104
+
105
+ env:
106
+ DB_DATABASE: audited_test
107
+ DB_USER: root
108
+ DB_PASSWORD: 'root'
109
+ DB_HOST: localhost
110
+
111
+ steps:
112
+ - name: Setup MySQL
113
+ run: |
114
+ sudo /etc/init.d/mysql start
115
+ mysql -e 'CREATE DATABASE audited_test;' -uroot -proot
116
+ mysql -e 'SHOW DATABASES;' -uroot -proot
117
+ - uses: actions/checkout@v3
118
+ - name: Copy Gemfile
119
+ run: sed 's/\.\././' gemfiles/${{ matrix.appraisal }}.gemfile > Gemfile
120
+ - name: Set up Ruby ${{ matrix.ruby }}
121
+ uses: ruby/setup-ruby@v1
122
+ with:
123
+ ruby-version: ${{ matrix.ruby }}
124
+ bundler-cache: true
125
+ - name: Run tests
126
+ env:
127
+ DB: ${{ matrix.db }}
128
+ run: bundle exec rake
data/Appraisals CHANGED
@@ -6,6 +6,7 @@ appraise "rails50" do
6
6
  gem "mysql2", ">= 0.3.18", "< 0.6.0"
7
7
  gem "pg", ">= 0.18", "< 2.0"
8
8
  gem "sqlite3", "~> 1.3.6"
9
+ gem "psych", "~> 3.1"
9
10
  end
10
11
 
11
12
  appraise "rails51" do
@@ -13,13 +14,15 @@ appraise "rails51" do
13
14
  gem "mysql2", ">= 0.3.18", "< 0.6.0"
14
15
  gem "pg", ">= 0.18", "< 2.0"
15
16
  gem "sqlite3", "~> 1.3.6"
17
+ gem "psych", "~> 3.1"
16
18
  end
17
19
 
18
20
  appraise "rails52" do
19
- gem "rails", ">= 5.2.0", "< 5.3"
21
+ gem "rails", ">= 5.2.8.1", "< 5.3"
20
22
  gem "mysql2", ">= 0.4.4", "< 0.6.0"
21
23
  gem "pg", ">= 0.18", "< 2.0"
22
24
  gem "sqlite3", "~> 1.3.6"
25
+ gem "psych", "~> 3.1"
23
26
  end
24
27
 
25
28
  appraise "rails60" do
@@ -35,3 +38,10 @@ appraise "rails61" do
35
38
  gem "pg", ">= 1.1", "< 2.0"
36
39
  gem "sqlite3", "~> 1.4"
37
40
  end
41
+
42
+ appraise "rails70" do
43
+ gem "rails", ">= 7.0.0", "< 7.1"
44
+ gem "mysql2", ">= 0.4.4"
45
+ gem "pg", ">= 1.1"
46
+ gem "sqlite3", ">= 1.4"
47
+ end
data/CHANGELOG.md CHANGED
@@ -1,5 +1,59 @@
1
1
  # Audited ChangeLog
2
2
 
3
+ ## 5.2.0 (2023-01-23)
4
+
5
+ Improved
6
+
7
+ - config.audit_class can take a string or constant - @rocket-turtle
8
+ Fixes overzealous change in 5.1.0 where it only took a string.
9
+ [#648](https://github.com/collectiveidea/audited/pull/648)
10
+ - README link fix - @jeremiahlukus
11
+ [#646](https://github.com/collectiveidea/audited/pull/646)
12
+ - Typo fix in GitHub Actions - @jdufresne
13
+ [#644](https://github.com/collectiveidea/audited/pull/644)
14
+
15
+ ## 5.1.0 (2022-12-23)
16
+
17
+ Changed
18
+
19
+ - config.audit_class takes a string - @simmerz
20
+ [#609](https://github.com/collectiveidea/audited/pull/609)
21
+ - Filter encrypted attributes automatically - @vlad-psh
22
+ [#630](https://github.com/collectiveidea/audited/pull/630)
23
+
24
+ Improved
25
+
26
+ - README improvements - @jess, @mstroming
27
+ [#605](https://github.com/collectiveidea/audited/pull/605)
28
+ [#640](https://github.com/collectiveidea/audited/issues/640)
29
+ - Ignore deadlocks in concurrent audit combinations - @Crammaman
30
+ [#621](https://github.com/collectiveidea/audited/pull/621)
31
+ - Fix timestamped_migrations deprecation warning - @shouichi
32
+ [#624](https://github.com/collectiveidea/audited/pull/624)
33
+ - Ensure audits are re-enabled after blocks - @dcorlett
34
+ [#632](https://github.com/collectiveidea/audited/pull/632)
35
+ - Replace raw string where clause with query methods - @macowie
36
+ [#642](https://github.com/collectiveidea/audited/pull/642)
37
+ - Test against more Ruby/Rails Versions - @enomotodev, @danielmorrison
38
+ [#610](https://github.com/collectiveidea/audited/pull/610)
39
+ [#643](https://github.com/collectiveidea/audited/pull/643)
40
+
41
+ ## 5.0.2 (2021-09-16)
42
+
43
+ Added
44
+
45
+ - Relax ActiveRecord version constraint to support Rails 7
46
+ [#597](https://github.com/collectiveidea/audited/pull/597)
47
+
48
+ Improved
49
+
50
+ - Improve loading - @mvastola
51
+ [#592](https://github.com/collectiveidea/audited/pull/592)
52
+ - Update README - @danirod, @clement1234
53
+ [#596](https://github.com/collectiveidea/audited/pull/596)
54
+ [#594](https://github.com/collectiveidea/audited/pull/594)
55
+
56
+
3
57
  ## 5.0.1 (2021-06-11)
4
58
 
5
59
  Improved
data/README.md CHANGED
@@ -1,23 +1,29 @@
1
- Audited [![Build Status](https://secure.travis-ci.org/collectiveidea/audited.svg)](http://travis-ci.org/collectiveidea/audited) [![Code Climate](https://codeclimate.com/github/collectiveidea/audited.svg)](https://codeclimate.com/github/collectiveidea/audited) [![Security](https://hakiri.io/github/collectiveidea/audited/master.svg)](https://hakiri.io/github/collectiveidea/audited/master)
1
+ Audited
2
+ [![Gem Version](https://img.shields.io/gem/v/audited.svg)](http://rubygems.org/gems/audited)
3
+ ![Build Status](https://github.com/collectiveidea/audited/actions/workflows/ci.yml/badge.svg)
4
+ [![Code Climate](https://codeclimate.com/github/collectiveidea/audited.svg)](https://codeclimate.com/github/collectiveidea/audited)
2
5
  [![Ruby Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://github.com/testdouble/standard)
3
6
  =======
4
7
 
5
8
  **Audited** (previously acts_as_audited) is an ORM extension that logs all changes to your models. Audited can also record who made those changes, save comments and associate models related to the changes.
6
9
 
7
10
 
8
- Audited currently (5.x) works with Rails 6.1, 6.0, 5.2, 5.1, and 5.0.
11
+ Audited currently (5.x) works with Rails 7.0, 6.1, 6.0, 5.2, 5.1, and 5.0.
9
12
 
10
13
  For Rails 4, use gem version 4.x
11
14
  For Rails 3, use gem version 3.0 or see the [3.0-stable branch](https://github.com/collectiveidea/audited/tree/3.0-stable).
12
15
 
13
16
  ## Supported Rubies
14
17
 
15
- Audited supports and is [tested against](http://travis-ci.org/collectiveidea/audited) the following Ruby versions:
18
+ Audited supports and is [tested against](https://github.com/collectiveidea/audited/actions/workflows/ci.yml) the following Ruby versions:
16
19
 
17
- * 2.3.7
18
- * 2.4.4
19
- * 2.5.1
20
- * 2.6.3
20
+ * 2.3 (only tested on Sqlite due to testing issues with other DBs)
21
+ * 2.4
22
+ * 2.5
23
+ * 2.6
24
+ * 2.7
25
+ * 3.0
26
+ * 3.1
21
27
 
22
28
  Audited may work just fine with a Ruby version not listed above, but we can't guarantee that it will. If you'd like to maintain a Ruby that isn't listed, please let us know with a [pull request](https://github.com/collectiveidea/audited/pulls).
23
29
 
@@ -30,7 +36,16 @@ Audited is currently ActiveRecord-only. In a previous life, Audited worked with
30
36
  Add the gem to your Gemfile:
31
37
 
32
38
  ```ruby
33
- gem "audited", "~> 4.9"
39
+ gem "audited", "~> 5.0"
40
+ ```
41
+
42
+ And if you're using ```require: false``` you must add initializers like this:
43
+
44
+ ```ruby
45
+ #./config/initializers/audited.rb
46
+ require "audited"
47
+
48
+ Audited::Railtie.initializers.each(&:run)
34
49
  ```
35
50
 
36
51
  Then, from your Rails app directory, create the `audits` table:
@@ -271,6 +286,7 @@ class User < ActiveRecord::Base
271
286
  end
272
287
 
273
288
  class Company < ActiveRecord::Base
289
+ audited
274
290
  has_many :users
275
291
  has_associated_audits
276
292
  end
@@ -299,8 +315,6 @@ If you want to audit only under specific conditions, you can provide conditional
299
315
  class User < ActiveRecord::Base
300
316
  audited if: :active?
301
317
 
302
- private
303
-
304
318
  def active?
305
319
  last_login > 6.months.ago
306
320
  end
@@ -371,6 +385,17 @@ User.auditing_enabled = false
371
385
  end
372
386
  ```
373
387
 
388
+ ### Encrypted attributes
389
+
390
+ If you're using ActiveRecord's encryption (available from Rails 7) to encrypt some attributes, Audited will automatically filter values of these attributes. No additional configuration is required. Changes to encrypted attributes will be logged as `[FILTERED]`.
391
+
392
+ ```ruby
393
+ class User < ActiveRecord::Base
394
+ audited
395
+ encrypts :password
396
+ end
397
+ ```
398
+
374
399
  ### Custom `Audit` model
375
400
 
376
401
  If you want to extend or modify the audit model, create a new class that
@@ -387,7 +412,7 @@ Then set it in an initializer:
387
412
  # config/initializers/audited.rb
388
413
 
389
414
  Audited.config do |config|
390
- config.audit_class = CustomAudit
415
+ config.audit_class = "CustomAudit"
391
416
  end
392
417
  ```
393
418
 
@@ -403,7 +428,7 @@ Audited.store_synthesized_enums = true
403
428
 
404
429
  ## Support
405
430
 
406
- You can find documentation at: http://rdoc.info/github/collectiveidea/audited
431
+ You can find documentation at: https://www.rubydoc.info/gems/audited
407
432
 
408
433
  Or join the [mailing list](http://groups.google.com/group/audited) to get help or offer suggestions.
409
434
 
@@ -6,5 +6,6 @@ gem "rails", "~> 5.0.0"
6
6
  gem "mysql2", ">= 0.3.18", "< 0.6.0"
7
7
  gem "pg", ">= 0.18", "< 2.0"
8
8
  gem "sqlite3", "~> 1.3.6"
9
+ gem "psych", "~> 3.1"
9
10
 
10
11
  gemspec name: "audited", path: "../"
@@ -6,5 +6,6 @@ gem "rails", "~> 5.1.4"
6
6
  gem "mysql2", ">= 0.3.18", "< 0.6.0"
7
7
  gem "pg", ">= 0.18", "< 2.0"
8
8
  gem "sqlite3", "~> 1.3.6"
9
+ gem "psych", "~> 3.1"
9
10
 
10
11
  gemspec name: "audited", path: "../"
@@ -2,9 +2,10 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "rails", ">= 5.2.0", "< 5.3"
5
+ gem "rails", ">= 5.2.8.1", "< 5.3"
6
6
  gem "mysql2", ">= 0.4.4", "< 0.6.0"
7
7
  gem "pg", ">= 0.18", "< 2.0"
8
8
  gem "sqlite3", "~> 1.3.6"
9
+ gem "psych", "~> 3.1"
9
10
 
10
11
  gemspec name: "audited", path: "../"
@@ -0,0 +1,10 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", ">= 7.0.0", "< 7.1"
6
+ gem "mysql2", ">= 0.4.4"
7
+ gem "pg", ">= 1.1"
8
+ gem "sqlite3", ">= 1.4"
9
+
10
+ gemspec name: "audited", path: "../"
data/lib/audited/audit.rb CHANGED
@@ -78,14 +78,14 @@ module Audited
78
78
  # Returns a hash of the changed attributes with the new values
79
79
  def new_attributes
80
80
  (audited_changes || {}).each_with_object({}.with_indifferent_access) do |(attr, values), attrs|
81
- attrs[attr] = (action == "update" ? values.last : values)
81
+ attrs[attr] = (action == "update") ? values.last : values
82
82
  end
83
83
  end
84
84
 
85
85
  # Returns a hash of the changed attributes with the old values
86
86
  def old_attributes
87
87
  (audited_changes || {}).each_with_object({}.with_indifferent_access) do |(attr, values), attrs|
88
- attrs[attr] = (action == "update" ? values.first : values)
88
+ attrs[attr] = (action == "update") ? values.first : values
89
89
  end
90
90
  end
91
91
 
@@ -174,7 +174,7 @@ module Audited
174
174
  if action == "create"
175
175
  self.version = 1
176
176
  else
177
- collection = Rails::VERSION::MAJOR >= 6 ? self.class.unscoped : self.class
177
+ collection = (Rails::VERSION::MAJOR >= 6) ? self.class.unscoped : self.class
178
178
  max = collection.auditable_finder(auditable_id, auditable_type).maximum(:version) || 0
179
179
  self.version = max + 1
180
180
  end
@@ -13,7 +13,7 @@ module Audited
13
13
  #
14
14
  # See <tt>Audited::Auditor::ClassMethods#audited</tt>
15
15
  # for configuration options
16
- module Auditor #:nodoc:
16
+ module Auditor # :nodoc:
17
17
  extend ActiveSupport::Concern
18
18
 
19
19
  CALLBACKS = [:audit_create, :audit_update, :audit_destroy]
@@ -172,14 +172,15 @@ module Audited
172
172
  # List of attributes that are audited.
173
173
  def audited_attributes
174
174
  audited_attributes = attributes.except(*self.class.non_audited_columns)
175
+ audited_attributes = redact_values(audited_attributes)
176
+ audited_attributes = filter_encrypted_attrs(audited_attributes)
175
177
  normalize_enum_changes(audited_attributes)
176
178
  end
177
179
 
178
180
  # Returns a list combined of record audits and associated audits.
179
181
  def own_and_associated_audits
180
- Audited.audit_class.unscoped
181
- .where("(auditable_type = :type AND auditable_id = :id) OR (associated_type = :type AND associated_id = :id)",
182
- type: self.class.base_class.name, id: id)
182
+ Audited.audit_class.unscoped.where(auditable: self)
183
+ .or(Audited.audit_class.unscoped.where(associated: self))
183
184
  .order(created_at: :desc)
184
185
  end
185
186
 
@@ -190,8 +191,13 @@ module Audited
190
191
  combine_target.comment = "#{combine_target.comment}\nThis audit is the result of multiple audits being combined."
191
192
 
192
193
  transaction do
193
- combine_target.save!
194
- audits_to_combine.unscope(:limit).where("version < ?", combine_target.version).delete_all
194
+ begin
195
+ combine_target.save!
196
+ audits_to_combine.unscope(:limit).where("version < ?", combine_target.version).delete_all
197
+ rescue ActiveRecord::Deadlocked
198
+ # Ignore Deadlocks, if the same record is getting its old audits combined more than once at the same time then
199
+ # both combining operations will be the same. Ignoring this error allows one of the combines to go through successfully.
200
+ end
195
201
  end
196
202
  end
197
203
 
@@ -234,6 +240,7 @@ module Audited
234
240
  end
235
241
 
236
242
  filtered_changes = redact_values(filtered_changes)
243
+ filtered_changes = filter_encrypted_attrs(filtered_changes)
237
244
  filtered_changes = normalize_enum_changes(filtered_changes)
238
245
  filtered_changes.to_hash
239
246
  end
@@ -257,19 +264,36 @@ module Audited
257
264
  end
258
265
 
259
266
  def redact_values(filtered_changes)
260
- [audited_options[:redacted]].flatten.compact.each do |option|
261
- changes = filtered_changes[option.to_s]
262
- new_value = audited_options[:redaction_value] || REDACTED
263
- values = if changes.is_a? Array
264
- changes.map { new_value }
265
- else
266
- new_value
267
- end
268
- hash = {option.to_s => values}
269
- filtered_changes.merge!(hash)
267
+ filter_attr_values(
268
+ audited_changes: filtered_changes,
269
+ attrs: Array(audited_options[:redacted]).map(&:to_s),
270
+ placeholder: audited_options[:redaction_value] || REDACTED
271
+ )
272
+ end
273
+
274
+ def filter_encrypted_attrs(filtered_changes)
275
+ filter_attr_values(
276
+ audited_changes: filtered_changes,
277
+ attrs: respond_to?(:encrypted_attributes) ? Array(encrypted_attributes).map(&:to_s) : []
278
+ )
279
+ end
280
+
281
+ # Replace values for given attrs to a placeholder and return modified hash
282
+ #
283
+ # @param audited_changes [Hash] Hash of changes to be saved to audited version record
284
+ # @param attrs [Array<String>] Array of attrs, values of which will be replaced to placeholder value
285
+ # @param placeholder [String] Placeholder to replace original attr values
286
+ def filter_attr_values(audited_changes: {}, attrs: [], placeholder: "[FILTERED]")
287
+ attrs.each do |attr|
288
+ next unless audited_changes.key?(attr)
289
+
290
+ changes = audited_changes[attr]
291
+ values = changes.is_a?(Array) ? changes.map { placeholder } : placeholder
292
+
293
+ audited_changes[attr] = values
270
294
  end
271
295
 
272
- filtered_changes
296
+ audited_changes
273
297
  end
274
298
 
275
299
  def rails_below?(rails_version)
@@ -290,20 +314,20 @@ module Audited
290
314
 
291
315
  def audit_create
292
316
  write_audit(action: "create", audited_changes: audited_attributes,
293
- comment: audit_comment)
317
+ comment: audit_comment)
294
318
  end
295
319
 
296
320
  def audit_update
297
321
  unless (changes = audited_changes).empty? && (audit_comment.blank? || audited_options[:update_with_comment_only] == false)
298
322
  write_audit(action: "update", audited_changes: changes,
299
- comment: audit_comment)
323
+ comment: audit_comment)
300
324
  end
301
325
  end
302
326
 
303
327
  def audit_destroy
304
328
  unless new_record?
305
329
  write_audit(action: "destroy", audited_changes: audited_attributes,
306
- comment: audit_comment)
330
+ comment: audit_comment)
307
331
  end
308
332
  end
309
333
 
@@ -397,7 +421,7 @@ module Audited
397
421
  # end
398
422
  #
399
423
  def without_auditing
400
- auditing_was_enabled = auditing_enabled
424
+ auditing_was_enabled = class_auditing_enabled
401
425
  disable_auditing
402
426
  yield
403
427
  ensure
@@ -411,7 +435,7 @@ module Audited
411
435
  # end
412
436
  #
413
437
  def with_auditing
414
- auditing_was_enabled = auditing_enabled
438
+ auditing_was_enabled = class_auditing_enabled
415
439
  enable_auditing
416
440
  yield
417
441
  ensure
@@ -435,7 +459,7 @@ module Audited
435
459
  end
436
460
 
437
461
  def auditing_enabled
438
- Audited.store.fetch("#{table_name}_auditing_enabled", true) && Audited.auditing_enabled
462
+ class_auditing_enabled && Audited.auditing_enabled
439
463
  end
440
464
 
441
465
  def auditing_enabled=(val)
@@ -466,6 +490,10 @@ module Audited
466
490
  default_ignored_attributes
467
491
  end
468
492
  end
493
+
494
+ def class_auditing_enabled
495
+ Audited.store.fetch("#{table_name}_auditing_enabled", true)
496
+ end
469
497
  end
470
498
  end
471
499
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Audited
4
- VERSION = "5.0.1"
4
+ VERSION = "5.2.0"
5
5
  end
data/lib/audited.rb CHANGED
@@ -13,9 +13,16 @@ module Audited
13
13
  attr_writer :audit_class
14
14
 
15
15
  def audit_class
16
- @audit_class ||= Audit
16
+ # The audit_class is set as String in the initializer. It can not be constantized during initialization and must
17
+ # be constantized at runtime. See https://github.com/collectiveidea/audited/issues/608
18
+ @audit_class = @audit_class.safe_constantize if @audit_class.is_a?(String)
19
+ @audit_class ||= Audited::Audit
17
20
  end
18
21
 
22
+ # remove audit_model in next major version it was only shortly present in 5.1.0
23
+ alias_method :audit_model, :audit_class
24
+ deprecate audit_model: "use Audited.audit_class instead of Audited.audit_model. This method will be removed."
25
+
19
26
  def store
20
27
  current_store_value = Thread.current.thread_variable_get(:audited_store)
21
28
 
@@ -39,9 +46,9 @@ module Audited
39
46
  end
40
47
 
41
48
  require "audited/auditor"
42
- require "audited/audit"
43
49
 
44
50
  ActiveSupport.on_load :active_record do
51
+ require "audited/audit"
45
52
  include Audited::Auditor
46
53
  end
47
54
 
@@ -4,14 +4,22 @@ module Audited
4
4
  module Generators
5
5
  module Migration
6
6
  # Implement the required interface for Rails::Generators::Migration.
7
- def next_migration_number(dirname) #:nodoc:
7
+ def next_migration_number(dirname) # :nodoc:
8
8
  next_migration_number = current_migration_number(dirname) + 1
9
- if ::ActiveRecord::Base.timestamped_migrations
9
+ if timestamped_migrations?
10
10
  [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % next_migration_number].max
11
11
  else
12
12
  "%.3d" % next_migration_number
13
13
  end
14
14
  end
15
+
16
+ private
17
+
18
+ def timestamped_migrations?
19
+ (Rails.version >= "7.0") ?
20
+ ::ActiveRecord.timestamped_migrations :
21
+ ::ActiveRecord::Base.timestamped_migrations
22
+ end
15
23
  end
16
24
  end
17
25
  end
@@ -37,7 +37,7 @@ describe Audited::Audit do
37
37
 
38
38
  context "when a custom audit class is configured" do
39
39
  it "should be used in place of #{described_class}" do
40
- Audited.config { |config| config.audit_class = CustomAudit }
40
+ Audited.config { |config| config.audit_class = "CustomAudit" }
41
41
  TempModel1.audited
42
42
 
43
43
  record = TempModel1.create
@@ -234,6 +234,14 @@ describe Audited::Auditor do
234
234
  expect(user.audits.last.audited_changes["password"]).to eq(["My", "Custom", "Value", 7])
235
235
  end
236
236
 
237
+ if ::ActiveRecord::VERSION::MAJOR >= 7
238
+ it "should filter encrypted attributes" do
239
+ user = Models::ActiveRecord::UserWithEncryptedPassword.create(password: "password")
240
+ user.save
241
+ expect(user.audits.last.audited_changes["password"]).to eq("[FILTERED]")
242
+ end
243
+ end
244
+
237
245
  if ActiveRecord::Base.connection.adapter_name == "PostgreSQL"
238
246
  describe "'json' and 'jsonb' audited_changes column type" do
239
247
  let(:migrations_path) { SPEC_ROOT.join("support/active_record/postgres") }
@@ -272,11 +280,11 @@ describe Audited::Auditor do
272
280
  yesterday = 1.day.ago
273
281
 
274
282
  u = Models::ActiveRecord::NoAttributeProtectionUser.new(name: "name",
275
- username: "username",
276
- password: "password",
277
- activated: true,
278
- suspended_at: yesterday,
279
- logins: 2)
283
+ username: "username",
284
+ password: "password",
285
+ activated: true,
286
+ suspended_at: yesterday,
287
+ logins: 2)
280
288
 
281
289
  expect(u.name).to eq("name")
282
290
  expect(u.username).to eq("username")
@@ -814,6 +822,15 @@ describe Audited::Auditor do
814
822
  }.to_not change(Audited::Audit, :count)
815
823
  end
816
824
 
825
+ context "when global audits are disabled" do
826
+ it "should re-enable class audits after #without_auditing block" do
827
+ Audited.auditing_enabled = false
828
+ Models::ActiveRecord::User.without_auditing {}
829
+ Audited.auditing_enabled = true
830
+ expect(Models::ActiveRecord::User.auditing_enabled).to eql(true)
831
+ end
832
+ end
833
+
817
834
  it "should reset auditing status even it raises an exception" do
818
835
  begin
819
836
  Models::ActiveRecord::User.without_auditing { raise }
@@ -884,6 +901,15 @@ describe Audited::Auditor do
884
901
  }.to change(Audited::Audit, :count).by(1)
885
902
  end
886
903
 
904
+ context "when global audits are disabled" do
905
+ it "should re-enable class audits after #with_auditing block" do
906
+ Audited.auditing_enabled = false
907
+ Models::ActiveRecord::User.with_auditing {}
908
+ Audited.auditing_enabled = true
909
+ expect(Models::ActiveRecord::User.auditing_enabled).to eql(true)
910
+ end
911
+ end
912
+
887
913
  it "should reset auditing status even it raises an exception" do
888
914
  Models::ActiveRecord::User.disable_auditing
889
915
  begin
@@ -4,6 +4,12 @@ module RailsApp
4
4
  class Application < Rails::Application
5
5
  config.root = File.expand_path("../../", __FILE__)
6
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
7
13
  end
8
14
  end
9
15
 
@@ -9,7 +9,8 @@ sqlite3: &SQLITE
9
9
  postgresql: &POSTGRES
10
10
  adapter: postgresql
11
11
  username: postgres
12
- password:
12
+ password: postgres
13
+ host: localhost
13
14
  database: audited_test
14
15
  min_messages: ERROR
15
16
 
@@ -17,7 +18,7 @@ mysql: &MYSQL
17
18
  adapter: mysql2
18
19
  host: localhost
19
20
  username: root
20
- password:
21
+ password: root
21
22
  database: audited_test
22
23
  charset: utf8
23
24
 
@@ -44,4 +44,9 @@ RailsApp::Application.configure do
44
44
 
45
45
  # Raises error for missing translations
46
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
47
52
  end
@@ -41,6 +41,14 @@ module Models
41
41
  audited redacted: :password, redaction_value: ["My", "Custom", "Value", 7]
42
42
  end
43
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
+
44
52
  class CommentRequiredUser < ::ActiveRecord::Base
45
53
  self.table_name = :users
46
54
  audited except: :password, comment_required: true
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: audited
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.1
4
+ version: 5.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandon Keepers
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2021-06-11 00:00:00.000000000 Z
16
+ date: 2023-01-23 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: activerecord
@@ -24,7 +24,7 @@ dependencies:
24
24
  version: '5.0'
25
25
  - - "<"
26
26
  - !ruby/object:Gem::Version
27
- version: '6.2'
27
+ version: '7.1'
28
28
  type: :runtime
29
29
  prerelease: false
30
30
  version_requirements: !ruby/object:Gem::Requirement
@@ -34,7 +34,7 @@ dependencies:
34
34
  version: '5.0'
35
35
  - - "<"
36
36
  - !ruby/object:Gem::Version
37
- version: '6.2'
37
+ version: '7.1'
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: appraisal
40
40
  requirement: !ruby/object:Gem::Requirement
@@ -58,7 +58,7 @@ dependencies:
58
58
  version: '5.0'
59
59
  - - "<"
60
60
  - !ruby/object:Gem::Version
61
- version: '6.2'
61
+ version: '7.1'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
@@ -68,7 +68,7 @@ dependencies:
68
68
  version: '5.0'
69
69
  - - "<"
70
70
  - !ruby/object:Gem::Version
71
- version: '6.2'
71
+ version: '7.1'
72
72
  - !ruby/object:Gem::Dependency
73
73
  name: rspec-rails
74
74
  requirement: !ruby/object:Gem::Requirement
@@ -115,16 +115,16 @@ dependencies:
115
115
  name: sqlite3
116
116
  requirement: !ruby/object:Gem::Requirement
117
117
  requirements:
118
- - - "~>"
118
+ - - ">="
119
119
  - !ruby/object:Gem::Version
120
- version: '1.3'
120
+ version: 1.3.6
121
121
  type: :development
122
122
  prerelease: false
123
123
  version_requirements: !ruby/object:Gem::Requirement
124
124
  requirements:
125
- - - "~>"
125
+ - - ">="
126
126
  - !ruby/object:Gem::Version
127
- version: '1.3'
127
+ version: 1.3.6
128
128
  - !ruby/object:Gem::Dependency
129
129
  name: mysql2
130
130
  requirement: !ruby/object:Gem::Requirement
@@ -165,9 +165,10 @@ executables: []
165
165
  extensions: []
166
166
  extra_rdoc_files: []
167
167
  files:
168
+ - ".github/workflows/buildlight.yml"
169
+ - ".github/workflows/ci.yml"
168
170
  - ".gitignore"
169
171
  - ".standard.yml"
170
- - ".travis.yml"
171
172
  - ".yardopts"
172
173
  - Appraisals
173
174
  - CHANGELOG.md
@@ -180,6 +181,7 @@ files:
180
181
  - gemfiles/rails52.gemfile
181
182
  - gemfiles/rails60.gemfile
182
183
  - gemfiles/rails61.gemfile
184
+ - gemfiles/rails70.gemfile
183
185
  - lib/audited-rspec.rb
184
186
  - lib/audited.rb
185
187
  - lib/audited/audit.rb
@@ -250,7 +252,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
250
252
  - !ruby/object:Gem::Version
251
253
  version: '0'
252
254
  requirements: []
253
- rubygems_version: 3.1.6
255
+ rubygems_version: 3.3.7
254
256
  signing_key:
255
257
  specification_version: 4
256
258
  summary: Log all changes to your models
data/.travis.yml DELETED
@@ -1,67 +0,0 @@
1
- language: ruby
2
- cache: bundler
3
- rvm:
4
- - 2.3.8
5
- - 2.4.10
6
- - 2.5.9
7
- - 2.6.7
8
- - 2.7.3
9
- - 3.0.1
10
- - ruby-head
11
- env:
12
- - DB=SQLITE
13
- - DB=POSTGRES
14
- - DB=MYSQL
15
- addons:
16
- postgresql: "9.4"
17
- services:
18
- - mysql
19
- before_install:
20
- # https://github.com/travis-ci/travis-ci/issues/8978
21
- - "travis_retry gem update --system"
22
- gemfile:
23
- - gemfiles/rails50.gemfile
24
- - gemfiles/rails51.gemfile
25
- - gemfiles/rails52.gemfile
26
- - gemfiles/rails60.gemfile
27
- - gemfiles/rails61.gemfile
28
- matrix:
29
- include:
30
- - rvm: 2.6.7
31
- script: bundle exec standardrb
32
- env: DB=standard # make travis build display nicer
33
- exclude:
34
- - rvm: 2.3.8
35
- gemfile: gemfiles/rails61.gemfile
36
- - rvm: 2.4.10
37
- gemfile: gemfiles/rails61.gemfile
38
- - rvm: 2.3.8
39
- gemfile: gemfiles/rails60.gemfile
40
- - rvm: 2.4.10
41
- gemfile: gemfiles/rails60.gemfile
42
- - rvm: 2.6.7
43
- gemfile: gemfiles/rails42.gemfile
44
- - rvm: 2.7.3
45
- gemfile: gemfiles/rails42.gemfile
46
- - rvm: 3.0.1
47
- gemfile: gemfiles/rails42.gemfile
48
- - rvm: 3.0.1
49
- gemfile: gemfiles/rails50.gemfile
50
- - rvm: 3.0.1
51
- gemfile: gemfiles/rails51.gemfile
52
- - rvm: 3.0.1
53
- gemfile: gemfiles/rails52.gemfile
54
- - rvm: ruby-head
55
- gemfile: gemfiles/rails42.gemfile
56
- allow_failures:
57
- - rvm: ruby-head
58
- fast_finish: true
59
- branches:
60
- only:
61
- - master
62
- - /.*-stable$/
63
- notifications:
64
- webhooks:
65
- urls:
66
- - https://buildlight.collectiveidea.com/
67
- on_start: always