audited 5.4.1 → 5.4.3
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.
- checksums.yaml +4 -4
- data/.github/workflows/publish_gem.yml +28 -0
- data/CHANGELOG.md +14 -1
- data/README.md +8 -2
- data/Rakefile +1 -3
- data/lib/audited/audit.rb +1 -1
- data/lib/audited/auditor.rb +6 -4
- data/lib/audited/version.rb +1 -1
- data/lib/audited.rb +4 -2
- data/lib/generators/audited/migration.rb +1 -1
- data/spec/audited/auditor_spec.rb +37 -0
- data/spec/audited_spec.rb +1 -5
- data/spec/audited_spec_helpers.rb +4 -0
- data/spec/rails_app/config/application.rb +1 -1
- data/spec/support/active_record/models.rb +9 -3
- metadata +16 -22
- data/lib/audited/request_store.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 32e366c7864b72cc3729bd15673e391ff3f45fee1b6ab0f2789ed8499588002f
|
4
|
+
data.tar.gz: 6a3f24da58730f880eaa1e7e607f33ef5bf74a035b477249e7d34f827e36728c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb1332090ad6d301af3d61a2948b8376f33dad8bea9c431ad480432f3c8d80837b9202f718e69be2dcdb0bb7bab8a329d77ae45e2fc50c533b6c79979e5d2b49
|
7
|
+
data.tar.gz: 632aae39c6307342b8430308f2f093e03a1b172f8ce0c08a3ed87f380f48b39e5fff63b2132fa93f9a5d0dec4a08b391671f52b5d2173a680c951aa27b4537f9
|
@@ -0,0 +1,28 @@
|
|
1
|
+
name: Publish Gem
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
tags:
|
6
|
+
- v*
|
7
|
+
|
8
|
+
jobs:
|
9
|
+
push:
|
10
|
+
if: github.repository == 'collectiveidea/audited'
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
environment: publishing
|
13
|
+
|
14
|
+
permissions:
|
15
|
+
contents: write
|
16
|
+
id-token: write
|
17
|
+
|
18
|
+
steps:
|
19
|
+
# Set up
|
20
|
+
- uses: actions/checkout@v4
|
21
|
+
- name: Set up Ruby
|
22
|
+
uses: ruby/setup-ruby@v1
|
23
|
+
with:
|
24
|
+
bundler-cache: true
|
25
|
+
ruby-version: ruby
|
26
|
+
|
27
|
+
# Release
|
28
|
+
- uses: rubygems/release-gem@v1
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,19 @@
|
|
1
1
|
# Audited ChangeLog
|
2
2
|
|
3
|
-
|
3
|
+
### 5.4.3 (2024-01-11)
|
4
|
+
|
5
|
+
- Ignore readonly columns in audit - @sriddbs
|
6
|
+
[#692](https://github.com/collectiveidea/audited/pull/692)
|
7
|
+
- Robustify Rails version checks - @blaet
|
8
|
+
[#689](https://github.com/collectiveidea/audited/pull/689)
|
9
|
+
- Ignore callbacks if not specifed on the model
|
10
|
+
[#679](https://github.com/collectiveidea/audited/pull/679)
|
11
|
+
|
12
|
+
## 5.4.2 (2023-11-30)
|
13
|
+
|
14
|
+
- Revert replacing RequetStore with ActiveSupport::CurrentAttributes until it is fully tested.
|
15
|
+
|
16
|
+
## 5.4.1 (2023-11-30)
|
4
17
|
|
5
18
|
- Replace RequestStore with ActiveSupport::CurrentAttributes - @the-spectator
|
6
19
|
[#673](https://github.com/collectiveidea/audited/pull/673/)
|
data/README.md
CHANGED
@@ -133,18 +133,24 @@ end
|
|
133
133
|
|
134
134
|
### Specifying callbacks
|
135
135
|
|
136
|
-
By default, a new audit is created for any Create, Update or Destroy action. You can, however, limit the actions audited.
|
136
|
+
By default, a new audit is created for any Create, Update, Touch (Rails 6+) or Destroy action. You can, however, limit the actions audited.
|
137
137
|
|
138
138
|
```ruby
|
139
139
|
class User < ActiveRecord::Base
|
140
140
|
# All fields and actions
|
141
141
|
# audited
|
142
142
|
|
143
|
-
# Single field, only audit Update and Destroy (not Create)
|
143
|
+
# Single field, only audit Update and Destroy (not Create or Touch)
|
144
144
|
# audited only: :name, on: [:update, :destroy]
|
145
145
|
end
|
146
146
|
```
|
147
147
|
|
148
|
+
You can ignore the default callbacks globally unless the callback action is specified in your model using the `:on` option. To configure default callback exclusion, put the following in an initializer file (`config/initializers/audited.rb`):
|
149
|
+
|
150
|
+
```ruby
|
151
|
+
Audited.ignored_default_callbacks = [:create, :update] # ignore callbacks create and update
|
152
|
+
```
|
153
|
+
|
148
154
|
### Comments
|
149
155
|
|
150
156
|
You can attach comments to each audit using an `audit_comment` attribute on your model.
|
data/Rakefile
CHANGED
@@ -1,12 +1,10 @@
|
|
1
1
|
#!/usr/bin/env rake
|
2
2
|
|
3
|
-
require "bundler/
|
3
|
+
require "bundler/gem_tasks"
|
4
4
|
require "rspec/core/rake_task"
|
5
5
|
require "rake/testtask"
|
6
6
|
require "appraisal"
|
7
7
|
|
8
|
-
Bundler::GemHelper.install_tasks(name: "audited")
|
9
|
-
|
10
8
|
RSpec::Core::RakeTask.new(:spec)
|
11
9
|
|
12
10
|
Rake::TestTask.new do |t|
|
data/lib/audited/audit.rb
CHANGED
@@ -49,7 +49,7 @@ module Audited
|
|
49
49
|
cattr_accessor :audited_class_names
|
50
50
|
self.audited_class_names = Set.new
|
51
51
|
|
52
|
-
if Rails.
|
52
|
+
if Rails.gem_version >= Gem::Version.new("7.1")
|
53
53
|
serialize :audited_changes, coder: YAMLIfTextColumnType
|
54
54
|
else
|
55
55
|
serialize :audited_changes, YAMLIfTextColumnType
|
data/lib/audited/auditor.rb
CHANGED
@@ -231,7 +231,7 @@ module Audited
|
|
231
231
|
|
232
232
|
private
|
233
233
|
|
234
|
-
def audited_changes(for_touch: false)
|
234
|
+
def audited_changes(for_touch: false, exclude_readonly_attrs: false)
|
235
235
|
all_changes = if for_touch
|
236
236
|
previous_changes
|
237
237
|
elsif respond_to?(:changes_to_save)
|
@@ -240,6 +240,8 @@ module Audited
|
|
240
240
|
changes
|
241
241
|
end
|
242
242
|
|
243
|
+
all_changes = all_changes.except(*self.class.readonly_attributes.to_a) if exclude_readonly_attrs
|
244
|
+
|
243
245
|
filtered_changes = \
|
244
246
|
if audited_options[:only].present?
|
245
247
|
all_changes.slice(*self.class.audited_columns)
|
@@ -333,14 +335,14 @@ module Audited
|
|
333
335
|
end
|
334
336
|
|
335
337
|
def audit_update
|
336
|
-
unless (changes = audited_changes).empty? && (audit_comment.blank? || audited_options[:update_with_comment_only] == false)
|
338
|
+
unless (changes = audited_changes(exclude_readonly_attrs: true)).empty? && (audit_comment.blank? || audited_options[:update_with_comment_only] == false)
|
337
339
|
write_audit(action: "update", audited_changes: changes,
|
338
340
|
comment: audit_comment)
|
339
341
|
end
|
340
342
|
end
|
341
343
|
|
342
344
|
def audit_touch
|
343
|
-
unless (changes = audited_changes(for_touch: true)).empty?
|
345
|
+
unless (changes = audited_changes(for_touch: true, exclude_readonly_attrs: true)).empty?
|
344
346
|
write_audit(action: "update", audited_changes: changes,
|
345
347
|
comment: audit_comment)
|
346
348
|
end
|
@@ -496,7 +498,7 @@ module Audited
|
|
496
498
|
|
497
499
|
def normalize_audited_options
|
498
500
|
audited_options[:on] = Array.wrap(audited_options[:on])
|
499
|
-
audited_options[:on] = [:create, :update, :touch, :destroy] if audited_options[:on].empty?
|
501
|
+
audited_options[:on] = ([:create, :update, :touch, :destroy] - Audited.ignored_default_callbacks) if audited_options[:on].empty?
|
500
502
|
audited_options[:only] = Array.wrap(audited_options[:only]).map(&:to_s)
|
501
503
|
audited_options[:except] = Array.wrap(audited_options[:except]).map(&:to_s)
|
502
504
|
max_audits = audited_options[:max_audits] || Audited.max_audits
|
data/lib/audited/version.rb
CHANGED
data/lib/audited.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_record"
|
4
|
+
require "request_store"
|
4
5
|
|
5
6
|
module Audited
|
6
7
|
class << self
|
@@ -8,6 +9,7 @@ module Audited
|
|
8
9
|
:auditing_enabled,
|
9
10
|
:current_user_method,
|
10
11
|
:ignored_attributes,
|
12
|
+
:ignored_default_callbacks,
|
11
13
|
:max_audits,
|
12
14
|
:store_synthesized_enums
|
13
15
|
attr_writer :audit_class
|
@@ -25,7 +27,7 @@ module Audited
|
|
25
27
|
deprecator: ActiveSupport::Deprecation.new('6.0.0', 'Audited')
|
26
28
|
|
27
29
|
def store
|
28
|
-
|
30
|
+
RequestStore.store[:audited_store] ||= {}
|
29
31
|
end
|
30
32
|
|
31
33
|
def config
|
@@ -34,6 +36,7 @@ module Audited
|
|
34
36
|
end
|
35
37
|
|
36
38
|
@ignored_attributes = %w[lock_version created_at updated_at created_on updated_on]
|
39
|
+
@ignored_default_callbacks = []
|
37
40
|
|
38
41
|
@current_user_method = :current_user
|
39
42
|
@auditing_enabled = true
|
@@ -41,7 +44,6 @@ module Audited
|
|
41
44
|
end
|
42
45
|
|
43
46
|
require "audited/auditor"
|
44
|
-
require "audited/request_store"
|
45
47
|
|
46
48
|
ActiveSupport.on_load :active_record do
|
47
49
|
require "audited/audit"
|
@@ -245,6 +245,27 @@ describe Audited::Auditor do
|
|
245
245
|
expect(user.audits.last.audited_changes["password"]).to eq(["My", "Custom", "Value", 7])
|
246
246
|
end
|
247
247
|
|
248
|
+
context "when ignored_default_callbacks is set" do
|
249
|
+
before { Audited.ignored_default_callbacks = [:create] }
|
250
|
+
after { Audited.ignored_default_callbacks = [] }
|
251
|
+
|
252
|
+
it "should remove create callback" do
|
253
|
+
class DefaultCallback < ::ActiveRecord::Base
|
254
|
+
audited
|
255
|
+
end
|
256
|
+
|
257
|
+
expect(DefaultCallback.audited_options[:on]).to eq([:update, :touch, :destroy])
|
258
|
+
end
|
259
|
+
|
260
|
+
it "should keep create callback if specified" do
|
261
|
+
class CallbacksSpecified < ::ActiveRecord::Base
|
262
|
+
audited on: [:create, :update, :destroy]
|
263
|
+
end
|
264
|
+
|
265
|
+
expect(CallbacksSpecified.audited_options[:on]).to eq([:create, :update, :destroy])
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
248
269
|
if ::ActiveRecord::VERSION::MAJOR >= 7
|
249
270
|
it "should filter encrypted attributes" do
|
250
271
|
user = Models::ActiveRecord::UserWithEncryptedPassword.create(password: "password")
|
@@ -358,6 +379,12 @@ describe Audited::Auditor do
|
|
358
379
|
Models::ActiveRecord::OnUpdateDestroy.create!(name: "Bart")
|
359
380
|
}.to_not change(Audited::Audit, :count)
|
360
381
|
end
|
382
|
+
|
383
|
+
it "should save readonly columns" do
|
384
|
+
expect {
|
385
|
+
Models::ActiveRecord::UserWithReadOnlyAttrs.create!(name: "Bart")
|
386
|
+
}.to change(Audited::Audit, :count)
|
387
|
+
end
|
361
388
|
end
|
362
389
|
|
363
390
|
describe "on update" do
|
@@ -409,6 +436,16 @@ describe Audited::Auditor do
|
|
409
436
|
expect { @user.update_attribute :activated, "1" }.to_not change(Audited::Audit, :count)
|
410
437
|
end
|
411
438
|
|
439
|
+
context "with readonly attributes" do
|
440
|
+
before do
|
441
|
+
@user = create_user_with_readonly_attrs(status: "active")
|
442
|
+
end
|
443
|
+
|
444
|
+
it "should not save readonly columns" do
|
445
|
+
expect { @user.update! status: "banned" }.to_not change(Audited::Audit, :count)
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
412
449
|
describe "with no dirty changes" do
|
413
450
|
it "does not create an audit if the record is not changed" do
|
414
451
|
expect {
|
data/spec/audited_spec.rb
CHANGED
@@ -3,16 +3,12 @@ require "spec_helper"
|
|
3
3
|
describe Audited do
|
4
4
|
describe "#store" do
|
5
5
|
describe "maintains state of store" do
|
6
|
-
let(:current_user) {
|
6
|
+
let(:current_user) { RequestStore.store[:audited_store] }
|
7
7
|
before { Audited.store[:current_user] = current_user }
|
8
8
|
|
9
9
|
it "checks store is not nil" do
|
10
10
|
expect(Audited.store[:current_user]).to eq(current_user)
|
11
11
|
end
|
12
|
-
|
13
|
-
it "when executed with Fibers" do
|
14
|
-
Fiber.new { expect(Audited.store[:current_user]).to eq(current_user) }.resume
|
15
|
-
end
|
16
12
|
end
|
17
13
|
end
|
18
14
|
end
|
@@ -3,6 +3,10 @@ module AuditedSpecHelpers
|
|
3
3
|
Models::ActiveRecord::User.create({name: "Brandon", username: "brandon", password: "password", favourite_device: "Android Phone"}.merge(attrs))
|
4
4
|
end
|
5
5
|
|
6
|
+
def create_user_with_readonly_attrs(attrs = {})
|
7
|
+
Models::ActiveRecord::UserWithReadOnlyAttrs.create({name: "Brandon", username: "brandon", password: "password", favourite_device: "Android Phone"}.merge(attrs))
|
8
|
+
end
|
9
|
+
|
6
10
|
def build_user(attrs = {})
|
7
11
|
Models::ActiveRecord::User.new({name: "darth", username: "darth", password: "noooooooo"}.merge(attrs))
|
8
12
|
end
|
@@ -30,7 +30,7 @@ module RailsApp
|
|
30
30
|
ActiveSupport::TimeWithZone ActiveSupport::TimeZone ActiveSupport::HashWithIndifferentAccess]
|
31
31
|
end
|
32
32
|
|
33
|
-
if Rails.
|
33
|
+
if Rails.gem_version >= Gem::Version.new("7.1")
|
34
34
|
config.active_support.cache_format_version = 7.1
|
35
35
|
end
|
36
36
|
end
|
@@ -5,11 +5,11 @@ module Models
|
|
5
5
|
module ActiveRecord
|
6
6
|
class User < ::ActiveRecord::Base
|
7
7
|
audited except: :password
|
8
|
-
attribute :non_column_attr if Rails.
|
8
|
+
attribute :non_column_attr if Rails.gem_version >= Gem::Version.new("5.1")
|
9
9
|
attr_protected :logins if respond_to?(:attr_protected)
|
10
10
|
enum status: {active: 0, reliable: 1, banned: 2}
|
11
11
|
|
12
|
-
if Rails.
|
12
|
+
if Rails.gem_version >= Gem::Version.new("7.1")
|
13
13
|
serialize :phone_numbers, type: Array
|
14
14
|
else
|
15
15
|
serialize :phone_numbers, Array
|
@@ -27,7 +27,7 @@ module Models
|
|
27
27
|
|
28
28
|
class UserOnlyPassword < ::ActiveRecord::Base
|
29
29
|
self.table_name = :users
|
30
|
-
attribute :non_column_attr if Rails.
|
30
|
+
attribute :non_column_attr if Rails.gem_version >= Gem::Version.new("5.1")
|
31
31
|
audited only: :password
|
32
32
|
end
|
33
33
|
|
@@ -54,6 +54,12 @@ module Models
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
+
class UserWithReadOnlyAttrs < ::ActiveRecord::Base
|
58
|
+
self.table_name = :users
|
59
|
+
audited
|
60
|
+
attr_readonly :status
|
61
|
+
end
|
62
|
+
|
57
63
|
class CommentRequiredUser < ::ActiveRecord::Base
|
58
64
|
self.table_name = :users
|
59
65
|
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.4.
|
4
|
+
version: 5.4.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brandon Keepers
|
@@ -10,10 +10,10 @@ authors:
|
|
10
10
|
- Brian Ryckbost
|
11
11
|
- Steve Richert
|
12
12
|
- Ryan Glover
|
13
|
-
autorequire:
|
13
|
+
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date:
|
16
|
+
date: 2024-01-11 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: '7.
|
27
|
+
version: '7.2'
|
28
28
|
type: :runtime
|
29
29
|
prerelease: false
|
30
30
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -34,27 +34,21 @@ dependencies:
|
|
34
34
|
version: '5.0'
|
35
35
|
- - "<"
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version: '7.
|
37
|
+
version: '7.2'
|
38
38
|
- !ruby/object:Gem::Dependency
|
39
|
-
name:
|
39
|
+
name: request_store
|
40
40
|
requirement: !ruby/object:Gem::Requirement
|
41
41
|
requirements:
|
42
|
-
- - "
|
43
|
-
- !ruby/object:Gem::Version
|
44
|
-
version: '5.0'
|
45
|
-
- - "<"
|
42
|
+
- - "~>"
|
46
43
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
44
|
+
version: '1.2'
|
48
45
|
type: :runtime
|
49
46
|
prerelease: false
|
50
47
|
version_requirements: !ruby/object:Gem::Requirement
|
51
48
|
requirements:
|
52
|
-
- - "
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '5.0'
|
55
|
-
- - "<"
|
49
|
+
- - "~>"
|
56
50
|
- !ruby/object:Gem::Version
|
57
|
-
version: '
|
51
|
+
version: '1.2'
|
58
52
|
- !ruby/object:Gem::Dependency
|
59
53
|
name: appraisal
|
60
54
|
requirement: !ruby/object:Gem::Requirement
|
@@ -78,7 +72,7 @@ dependencies:
|
|
78
72
|
version: '5.0'
|
79
73
|
- - "<"
|
80
74
|
- !ruby/object:Gem::Version
|
81
|
-
version: '7.
|
75
|
+
version: '7.2'
|
82
76
|
type: :development
|
83
77
|
prerelease: false
|
84
78
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -88,7 +82,7 @@ dependencies:
|
|
88
82
|
version: '5.0'
|
89
83
|
- - "<"
|
90
84
|
- !ruby/object:Gem::Version
|
91
|
-
version: '7.
|
85
|
+
version: '7.2'
|
92
86
|
- !ruby/object:Gem::Dependency
|
93
87
|
name: rspec-rails
|
94
88
|
requirement: !ruby/object:Gem::Requirement
|
@@ -187,6 +181,7 @@ extra_rdoc_files: []
|
|
187
181
|
files:
|
188
182
|
- ".github/workflows/buildlight.yml"
|
189
183
|
- ".github/workflows/ci.yml"
|
184
|
+
- ".github/workflows/publish_gem.yml"
|
190
185
|
- ".gitignore"
|
191
186
|
- ".standard.yml"
|
192
187
|
- ".yardopts"
|
@@ -208,7 +203,6 @@ files:
|
|
208
203
|
- lib/audited/audit.rb
|
209
204
|
- lib/audited/auditor.rb
|
210
205
|
- lib/audited/railtie.rb
|
211
|
-
- lib/audited/request_store.rb
|
212
206
|
- lib/audited/rspec_matchers.rb
|
213
207
|
- lib/audited/sweeper.rb
|
214
208
|
- lib/audited/version.rb
|
@@ -259,7 +253,7 @@ homepage: https://github.com/collectiveidea/audited
|
|
259
253
|
licenses:
|
260
254
|
- MIT
|
261
255
|
metadata: {}
|
262
|
-
post_install_message:
|
256
|
+
post_install_message:
|
263
257
|
rdoc_options: []
|
264
258
|
require_paths:
|
265
259
|
- lib
|
@@ -274,8 +268,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
274
268
|
- !ruby/object:Gem::Version
|
275
269
|
version: '0'
|
276
270
|
requirements: []
|
277
|
-
rubygems_version: 3.
|
278
|
-
signing_key:
|
271
|
+
rubygems_version: 3.5.3
|
272
|
+
signing_key:
|
279
273
|
specification_version: 4
|
280
274
|
summary: Log all changes to your models
|
281
275
|
test_files: []
|