audited 5.4.2 → 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 +9 -0
- 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 +2 -0
- data/lib/generators/audited/migration.rb +1 -1
- data/spec/audited/auditor_spec.rb +37 -0
- 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 +7 -6
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,5 +1,14 @@
|
|
1
1
|
# Audited ChangeLog
|
2
2
|
|
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
|
+
|
3
12
|
## 5.4.2 (2023-11-30)
|
4
13
|
|
5
14
|
- Revert replacing RequetStore with ActiveSupport::CurrentAttributes until it is fully tested.
|
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
@@ -9,6 +9,7 @@ module Audited
|
|
9
9
|
:auditing_enabled,
|
10
10
|
:current_user_method,
|
11
11
|
:ignored_attributes,
|
12
|
+
:ignored_default_callbacks,
|
12
13
|
:max_audits,
|
13
14
|
:store_synthesized_enums
|
14
15
|
attr_writer :audit_class
|
@@ -35,6 +36,7 @@ module Audited
|
|
35
36
|
end
|
36
37
|
|
37
38
|
@ignored_attributes = %w[lock_version created_at updated_at created_on updated_on]
|
39
|
+
@ignored_default_callbacks = []
|
38
40
|
|
39
41
|
@current_user_method = :current_user
|
40
42
|
@auditing_enabled = true
|
@@ -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 {
|
@@ -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
|
@@ -181,6 +181,7 @@ extra_rdoc_files: []
|
|
181
181
|
files:
|
182
182
|
- ".github/workflows/buildlight.yml"
|
183
183
|
- ".github/workflows/ci.yml"
|
184
|
+
- ".github/workflows/publish_gem.yml"
|
184
185
|
- ".gitignore"
|
185
186
|
- ".standard.yml"
|
186
187
|
- ".yardopts"
|
@@ -252,7 +253,7 @@ homepage: https://github.com/collectiveidea/audited
|
|
252
253
|
licenses:
|
253
254
|
- MIT
|
254
255
|
metadata: {}
|
255
|
-
post_install_message:
|
256
|
+
post_install_message:
|
256
257
|
rdoc_options: []
|
257
258
|
require_paths:
|
258
259
|
- lib
|
@@ -267,8 +268,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
267
268
|
- !ruby/object:Gem::Version
|
268
269
|
version: '0'
|
269
270
|
requirements: []
|
270
|
-
rubygems_version: 3.
|
271
|
-
signing_key:
|
271
|
+
rubygems_version: 3.5.3
|
272
|
+
signing_key:
|
272
273
|
specification_version: 4
|
273
274
|
summary: Log all changes to your models
|
274
275
|
test_files: []
|