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 +4 -4
- data/.github/workflows/buildlight.yml +15 -0
- data/.github/workflows/ci.yml +128 -0
- data/Appraisals +11 -1
- data/CHANGELOG.md +54 -0
- data/README.md +37 -12
- data/gemfiles/rails50.gemfile +1 -0
- data/gemfiles/rails51.gemfile +1 -0
- data/gemfiles/rails52.gemfile +2 -1
- data/gemfiles/rails70.gemfile +10 -0
- data/lib/audited/audit.rb +3 -3
- data/lib/audited/auditor.rb +51 -23
- data/lib/audited/version.rb +1 -1
- data/lib/audited.rb +9 -2
- data/lib/generators/audited/migration.rb +10 -2
- data/spec/audited/audit_spec.rb +1 -1
- data/spec/audited/auditor_spec.rb +31 -5
- data/spec/rails_app/config/application.rb +6 -0
- data/spec/rails_app/config/database.yml +3 -2
- data/spec/rails_app/config/environments/test.rb +5 -0
- data/spec/support/active_record/models.rb +8 -0
- metadata +14 -12
- data/.travis.yml +0 -67
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 86131fd51439ffb0e1e16fd0b3bdd770c0cdf6de5bc8df5f234377d9ef0aeddb
|
4
|
+
data.tar.gz: 4729941ef95dc9e6e542eb705ac12ff4876999c61f210a50d8ef460a02d71078
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 27d6c2bd685eaca06093e7b8352aa942b83163a09be96fade16cc39ac46502697ca264a54f7a99a4390afe6cc07fbca0d345cb4ad35d7a11d98fa8da9aa262dd
|
7
|
+
data.tar.gz: 615ffae5d0fe3a44ffde034ddd60a2074cdff6679b1a8d59b23adfa2fed557023ffd786516997627aaf3de7916c39666d85abd24b38b1562976678472bbc85a9
|
@@ -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.
|
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
|
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](
|
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
|
18
|
-
* 2.4
|
19
|
-
* 2.5
|
20
|
-
* 2.6
|
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", "~>
|
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:
|
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
|
|
data/gemfiles/rails50.gemfile
CHANGED
data/gemfiles/rails51.gemfile
CHANGED
data/gemfiles/rails52.gemfile
CHANGED
@@ -2,9 +2,10 @@
|
|
2
2
|
|
3
3
|
source "https://rubygems.org"
|
4
4
|
|
5
|
-
gem "rails", ">= 5.2.
|
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: "../"
|
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
|
data/lib/audited/auditor.rb
CHANGED
@@ -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
|
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(
|
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
|
-
|
194
|
-
|
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
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
filtered_changes
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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 =
|
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 =
|
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
|
-
|
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
|
data/lib/audited/version.rb
CHANGED
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
|
-
|
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)
|
7
|
+
def next_migration_number(dirname) # :nodoc:
|
8
8
|
next_migration_number = current_migration_number(dirname) + 1
|
9
|
-
if
|
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
|
data/spec/audited/audit_spec.rb
CHANGED
@@ -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
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
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
|
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:
|
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: '
|
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: '
|
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: '
|
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: '
|
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:
|
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:
|
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.
|
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
|