audited 5.4.1 → 5.4.3
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|