audited 4.9.0 → 4.10.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: 91cd155edfaec5e9cbe81994bdc5e12e8fd91b58886d8397a6f310ddade5ae03
4
- data.tar.gz: 5d7b4f209cf8d8803dff66e4f19b8f85c586373ea757f1e84c1422d56feee1c0
3
+ metadata.gz: e774f1f27e84aaa6f3ad9160eaba9b0e5eda0df9202cb5acaf405de13071c4d3
4
+ data.tar.gz: affeec219575b7032c73f03d69d839aeb7ad81ab7c53e2e636bea0243d66ac8f
5
5
  SHA512:
6
- metadata.gz: 48bab7914ba66c2e7e82bf1bb6936b113b4536ab1297e9d8cdad80036788506bc825594daf37d308b8acbff3321e7ea1936fe6bdb3481f48f311a8caaec9e4ec
7
- data.tar.gz: f30cdcce78fd2c9202d3147af5d6e6844fb77f5e81300b79261d29f0d931580e67dd3bb04799d0247d3a8b4893314996a05d3ff25d477c43dbc3cf713ecd59fd
6
+ metadata.gz: df852876685671788eeec0cd604a5771ed5bd096d466c10f1b9798774681c03749b2280bf4794d0cef707080c4f2e22464adbb90ac39f077132a0d3630c85c8c
7
+ data.tar.gz: bf555f179f6c33d4493aa984c1163e1ae2bcf7985b1ff7fecbe52012b3d2140c364098478aca57817c8991747a4009e4b184e63227621dc752cd8fe5ccf8a516
@@ -19,8 +19,8 @@ before_install:
19
19
  - "travis_retry gem update --system"
20
20
  # Rails 4.2 has a bundler 1.x requirement
21
21
  - if [ $BUNDLE_GEMFILE = $PWD/gemfiles/rails42.gemfile ]; then
22
- rvm @global do gem uninstall bundler -a -x;
23
- travis_retry gem install -v '< 2.0.0' bundler;
22
+ travis_retry gem install -v '1.17.3' bundler;
23
+ bundle _1.17.3_ install;
24
24
  else
25
25
  travis_retry gem install bundler;
26
26
  fi
@@ -30,12 +30,17 @@ gemfile:
30
30
  - gemfiles/rails51.gemfile
31
31
  - gemfiles/rails52.gemfile
32
32
  - gemfiles/rails60.gemfile
33
+ - gemfiles/rails61.gemfile
33
34
  matrix:
34
35
  include:
35
36
  - rvm: 2.6.3
36
37
  script: bundle exec rubocop --parallel
37
38
  env: DB=rubocop # make travis build display nicer
38
39
  exclude:
40
+ - rvm: 2.3.7
41
+ gemfile: gemfiles/rails61.gemfile
42
+ - rvm: 2.4.4
43
+ gemfile: gemfiles/rails61.gemfile
39
44
  - rvm: 2.3.7
40
45
  gemfile: gemfiles/rails60.gemfile
41
46
  - rvm: 2.4.4
data/Appraisals CHANGED
@@ -31,8 +31,15 @@ appraise 'rails52' do
31
31
  end
32
32
 
33
33
  appraise 'rails60' do
34
- gem 'rails', '>= 6.0.0.rc1', '< 6.1'
34
+ gem 'rails', '>= 6.0.0', '< 6.1'
35
35
  gem "mysql2", ">= 0.4.4"
36
36
  gem "pg", ">= 0.18", "< 2.0"
37
37
  gem "sqlite3", "~> 1.4"
38
38
  end
39
+
40
+ appraise 'rails61' do
41
+ gem 'rails', '>= 6.1.0', '< 6.2'
42
+ gem "mysql2", ">= 0.4.4"
43
+ gem "pg", ">= 1.1", "< 2.0"
44
+ gem "sqlite3", "~> 1.4"
45
+ end
@@ -2,6 +2,22 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 4.10.0 (2021-01-07)
6
+
7
+ Added
8
+
9
+ - Add redacted option
10
+ [#485](https://github.com/collectiveidea/audited/pull/485)
11
+ - Rails 6.1. support
12
+ [#554](https://github.com/collectiveidea/audited/pull/554)
13
+ [#559](https://github.com/collectiveidea/audited/pull/559)
14
+
15
+ Improved
16
+
17
+ - Avoid extra query on first audit version
18
+ [#513](https://github.com/collectiveidea/audited/pull/513)
19
+
20
+
5
21
  ## 4.9.0 (2019-07-17)
6
22
 
7
23
  Breaking changes
data/README.md CHANGED
@@ -3,7 +3,7 @@ Audited [![Build Status](https://secure.travis-ci.org/collectiveidea/audited.svg
3
3
 
4
4
  **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.
5
5
 
6
- Audited currently (4.x) works with Rails 6.0, 5.2, 5.1, 5.0 and 4.2.
6
+ Audited currently (4.x) works with Rails 6.1, Rails 6.0, 5.2, 5.1, 5.0 and 4.2.
7
7
 
8
8
  For Rails 3, use gem version 3.0 or see the [3.0-stable branch](https://github.com/collectiveidea/audited/tree/3.0-stable).
9
9
 
@@ -143,7 +143,7 @@ class User < ActiveRecord::Base
143
143
  end
144
144
  ```
145
145
 
146
- You can update an audit if only audit_comment is present. You can optionally add the `:update_with_comment_only` option set to `false` to your `audited` call to turn this behavior off for all audits.
146
+ You can update an audit only if audit_comment is present. You can optionally add the `:update_with_comment_only` option set to `false` to your `audited` call to turn this behavior off for all audits.
147
147
 
148
148
  ```ruby
149
149
  class User < ActiveRecord::Base
@@ -234,6 +234,16 @@ end
234
234
  post.audits.last.user # => 'console-user-username'
235
235
  ```
236
236
 
237
+ If you want to set a specific user as the auditor of the commands in a CLI environment, whether that is a string or an ActiveRecord object, you can use the following command:
238
+
239
+ ```rb
240
+ Audited.store[:audited_user] = "username"
241
+
242
+ # or
243
+
244
+ Audited.store[:audited_user] = User.find(1)
245
+ ```
246
+
237
247
  ### Associated Audits
238
248
 
239
249
  Sometimes it's useful to associate an audit with a model other than the one being changed. For instance, given the following models:
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "rails", ">= 6.0.0.rc1", "< 6.1"
5
+ gem "rails", ">= 6.0.0", "< 6.1"
6
6
  gem "mysql2", ">= 0.4.4"
7
7
  gem "pg", ">= 0.18", "< 2.0"
8
8
  gem "sqlite3", "~> 1.4"
@@ -0,0 +1,10 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", ">= 6.1.0", "< 6.2"
6
+ gem "mysql2", ">= 0.4.4"
7
+ gem "pg", ">= 1.1", "< 2.0"
8
+ gem "sqlite3", "~> 1.4"
9
+
10
+ gemspec name: "audited", path: "../"
@@ -16,7 +16,7 @@ module Audited
16
16
  class YAMLIfTextColumnType
17
17
  class << self
18
18
  def load(obj)
19
- if Audited.audit_class.columns_hash["audited_changes"].type.to_s == "text"
19
+ if text_column?
20
20
  ActiveRecord::Coders::YAMLColumn.new(Object).load(obj)
21
21
  else
22
22
  obj
@@ -24,12 +24,16 @@ module Audited
24
24
  end
25
25
 
26
26
  def dump(obj)
27
- if Audited.audit_class.columns_hash["audited_changes"].type.to_s == "text"
27
+ if text_column?
28
28
  ActiveRecord::Coders::YAMLColumn.new(Object).dump(obj)
29
29
  else
30
30
  obj
31
31
  end
32
32
  end
33
+
34
+ def text_column?
35
+ Audited.audit_class.columns_hash["audited_changes"].type.to_s == "text"
36
+ end
33
37
  end
34
38
  end
35
39
 
@@ -131,7 +135,7 @@ module Audited
131
135
  # by +user+. This method is hopefully threadsafe, making it ideal
132
136
  # for background operations that require audit information.
133
137
  def self.as_user(user)
134
- last_audited_user = ::Audited.store[:audited_user]
138
+ last_audited_user = ::Audited.store[:audited_user]
135
139
  ::Audited.store[:audited_user] = user
136
140
  yield
137
141
  ensure
@@ -168,8 +172,13 @@ module Audited
168
172
  private
169
173
 
170
174
  def set_version_number
171
- max = self.class.auditable_finder(auditable_id, auditable_type).maximum(:version) || 0
172
- self.version = max + 1
175
+ if action == 'create'
176
+ self.version = 1
177
+ else
178
+ collection = Rails::VERSION::MAJOR == 6 ? self.class.unscoped : self.class
179
+ max = collection.auditable_finder(auditable_id, auditable_type).maximum(:version) || 0
180
+ self.version = max + 1
181
+ end
173
182
  end
174
183
 
175
184
  def set_audit_user
@@ -34,6 +34,16 @@ module Audited
34
34
  # * +require_comment+ - Ensures that audit_comment is supplied before
35
35
  # any create, update or destroy operation.
36
36
  # * +max_audits+ - Limits the number of stored audits.
37
+
38
+ # * +redacted+ - Changes to these fields will be logged, but the values
39
+ # will not. This is useful, for example, if you wish to audit when a
40
+ # password is changed, without saving the actual password in the log.
41
+ # To store values as something other than '[REDACTED]', pass an argument
42
+ # to the redaction_value option.
43
+ #
44
+ # class User < ActiveRecord::Base
45
+ # audited redacted: :password, redaction_value: SecureRandom.uuid
46
+ # end
37
47
  #
38
48
  # * +if+ - Only audit the model when the given function returns true
39
49
  # * +unless+ - Only audit the model when the given function returns false
@@ -90,16 +100,8 @@ module Audited
90
100
  end
91
101
 
92
102
  module AuditedInstanceMethods
93
- # Deprecate version attribute in favor of audit_version attribute – preparing for eventual removal.
94
- def method_missing(method_name, *args, &block)
95
- if method_name == :version
96
- ActiveSupport::Deprecation.warn("`version` attribute has been changed to `audit_version`. This attribute will be removed.")
97
- audit_version
98
- else
99
- super
100
- end
101
- end
102
-
103
+ REDACTED = '[REDACTED]'
104
+
103
105
  # Temporarily turns off auditing while saving.
104
106
  def save_without_auditing
105
107
  without_auditing { save }
@@ -229,6 +231,7 @@ module Audited
229
231
  all_changes.except(*self.class.non_audited_columns)
230
232
  end
231
233
 
234
+ filtered_changes = redact_values(filtered_changes)
232
235
  filtered_changes = normalize_enum_changes(filtered_changes)
233
236
  filtered_changes.to_hash
234
237
  end
@@ -249,6 +252,22 @@ module Audited
249
252
  changes
250
253
  end
251
254
 
255
+ def redact_values(filtered_changes)
256
+ [audited_options[:redacted]].flatten.compact.each do |option|
257
+ changes = filtered_changes[option.to_s]
258
+ new_value = audited_options[:redaction_value] || REDACTED
259
+ if changes.is_a? Array
260
+ values = changes.map { new_value }
261
+ else
262
+ values = new_value
263
+ end
264
+ hash = Hash[option.to_s, values]
265
+ filtered_changes.merge!(hash)
266
+ end
267
+
268
+ filtered_changes
269
+ end
270
+
252
271
  def rails_below?(rails_version)
253
272
  Gem::Version.new(Rails::VERSION::STRING) < Gem::Version.new(rails_version)
254
273
  end
@@ -1,3 +1,3 @@
1
1
  module Audited
2
- VERSION = "4.9.0"
2
+ VERSION = "4.10.0"
3
3
  end
@@ -1,6 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
- SingleCov.covered!
3
+ SingleCov.covered! uncovered: 1 # Rails version check
4
4
 
5
5
  describe Audited::Audit do
6
6
  let(:user) { Models::ActiveRecord::User.new name: "Testing" }
@@ -62,7 +62,7 @@ describe Audited::Audit do
62
62
  end
63
63
 
64
64
  it "does not unserialize from binary columns" do
65
- allow(Audited.audit_class.columns_hash["audited_changes"]).to receive(:type).and_return("foo")
65
+ allow(Audited::YAMLIfTextColumnType).to receive(:text_column?).and_return(false)
66
66
  audit.audited_changes = {foo: "bar"}
67
67
  expect(audit.audited_changes).to eq "{:foo=>\"bar\"}"
68
68
  end
@@ -174,7 +174,7 @@ describe Audited::Audit do
174
174
  it "uses created at" do
175
175
  Audited::Audit.delete_all
176
176
  audit = Models::ActiveRecord::User.create(name: "John").audits.last
177
- audit.update_columns(created_at: Time.parse('2018-01-01'))
177
+ audit.update_columns(created_at: Time.zone.parse('2018-01-01'))
178
178
  expect(Audited::Audit.collection_cache_key).to match(/-20180101\d+$/)
179
179
  end
180
180
  else
@@ -212,6 +212,39 @@ describe Audited::Auditor do
212
212
  expect(user.audits.last.audited_changes.keys).to eq(%w{non_column_attr})
213
213
  end
214
214
 
215
+ it "should redact columns specified in 'redacted' option" do
216
+ redacted = Audited::Auditor::AuditedInstanceMethods::REDACTED
217
+ user = Models::ActiveRecord::UserRedactedPassword.create(password: "password")
218
+ user.save!
219
+ expect(user.audits.last.audited_changes['password']).to eq(redacted)
220
+ user.password = "new_password"
221
+ user.save!
222
+ expect(user.audits.last.audited_changes['password']).to eq([redacted, redacted])
223
+ end
224
+
225
+ it "should redact columns specified in 'redacted' option when there are multiple specified" do
226
+ redacted = Audited::Auditor::AuditedInstanceMethods::REDACTED
227
+ user =
228
+ Models::ActiveRecord::UserMultipleRedactedAttributes.create(
229
+ password: "password",
230
+ ssn: 123456789
231
+ )
232
+ user.save!
233
+ expect(user.audits.last.audited_changes['password']).to eq(redacted)
234
+ expect(user.audits.last.audited_changes['ssn']).to eq(redacted)
235
+ user.password = "new_password"
236
+ user.ssn = 987654321
237
+ user.save!
238
+ expect(user.audits.last.audited_changes['password']).to eq([redacted, redacted])
239
+ expect(user.audits.last.audited_changes['ssn']).to eq([redacted, redacted])
240
+ end
241
+
242
+ it "should redact columns in 'redacted' column with custom option" do
243
+ user = Models::ActiveRecord::UserRedactedPasswordCustomRedaction.create(password: "password")
244
+ user.save!
245
+ expect(user.audits.last.audited_changes['password']).to eq(["My", "Custom", "Value", 7])
246
+ end
247
+
215
248
  if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
216
249
  describe "'json' and 'jsonb' audited_changes column type" do
217
250
  let(:migrations_path) { SPEC_ROOT.join("support/active_record/postgres") }
@@ -101,7 +101,8 @@ describe AuditsController do
101
101
  controller.send(:current_user=, user)
102
102
 
103
103
  expect {
104
- put :update, Rails::VERSION::MAJOR == 4 ? {id: 123} : {params: {id: 123}}
104
+ params = Rails::VERSION::MAJOR == 4 ? {id: 123} : {params: {id: 123}}
105
+ put :update, **params
105
106
  }.to_not change( Audited::Audit, :count )
106
107
  end
107
108
  end
@@ -20,8 +20,10 @@ module AuditedSpecHelpers
20
20
  def run_migrations(direction, migrations_paths, target_version = nil)
21
21
  if rails_below?('5.2.0.rc1')
22
22
  ActiveRecord::Migrator.send(direction, migrations_paths, target_version)
23
- else
23
+ elsif rails_below?('6.0.0.rc1')
24
24
  ActiveRecord::MigrationContext.new(migrations_paths).send(direction, target_version)
25
+ else
26
+ ActiveRecord::MigrationContext.new(migrations_paths, ActiveRecord::SchemaMigration).send(direction, target_version)
25
27
  end
26
28
  end
27
29
 
@@ -25,6 +25,21 @@ module Models
25
25
  audited only: :password
26
26
  end
27
27
 
28
+ class UserRedactedPassword < ::ActiveRecord::Base
29
+ self.table_name = :users
30
+ audited redacted: :password
31
+ end
32
+
33
+ class UserMultipleRedactedAttributes < ::ActiveRecord::Base
34
+ self.table_name = :users
35
+ audited redacted: [:password, :ssn]
36
+ end
37
+
38
+ class UserRedactedPasswordCustomRedaction < ::ActiveRecord::Base
39
+ self.table_name = :users
40
+ audited redacted: :password, redaction_value: ["My", "Custom", "Value", 7]
41
+ end
42
+
28
43
  class CommentRequiredUser < ::ActiveRecord::Base
29
44
  self.table_name = :users
30
45
  audited comment_required: true
@@ -41,6 +41,7 @@ ActiveRecord::Schema.define do
41
41
  t.column :created_at, :datetime
42
42
  t.column :updated_at, :datetime
43
43
  t.column :favourite_device, :string
44
+ t.column :ssn, :integer
44
45
  end
45
46
 
46
47
  create_table :companies do |t|
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: 4.9.0
4
+ version: 4.10.0
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: 2019-07-18 00:00:00.000000000 Z
16
+ date: 2021-01-08 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: '4.2'
25
25
  - - "<"
26
26
  - !ruby/object:Gem::Version
27
- version: '6.1'
27
+ version: '6.2'
28
28
  type: :runtime
29
29
  prerelease: false
30
30
  version_requirements: !ruby/object:Gem::Requirement
@@ -34,7 +34,7 @@ dependencies:
34
34
  version: '4.2'
35
35
  - - "<"
36
36
  - !ruby/object:Gem::Version
37
- version: '6.1'
37
+ version: '6.2'
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: '4.2'
59
59
  - - "<"
60
60
  - !ruby/object:Gem::Version
61
- version: '6.1'
61
+ version: '6.2'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
@@ -68,7 +68,7 @@ dependencies:
68
68
  version: '4.2'
69
69
  - - "<"
70
70
  - !ruby/object:Gem::Version
71
- version: '6.1'
71
+ version: '6.2'
72
72
  - !ruby/object:Gem::Dependency
73
73
  name: rubocop
74
74
  requirement: !ruby/object:Gem::Requirement
@@ -180,6 +180,7 @@ files:
180
180
  - gemfiles/rails51.gemfile
181
181
  - gemfiles/rails52.gemfile
182
182
  - gemfiles/rails60.gemfile
183
+ - gemfiles/rails61.gemfile
183
184
  - lib/audited-rspec.rb
184
185
  - lib/audited.rb
185
186
  - lib/audited/audit.rb
@@ -206,6 +207,7 @@ files:
206
207
  - spec/audited/rspec_matchers_spec.rb
207
208
  - spec/audited/sweeper_spec.rb
208
209
  - spec/audited_spec_helpers.rb
210
+ - spec/rails_app/app/assets/config/manifest.js
209
211
  - spec/rails_app/app/controllers/application_controller.rb
210
212
  - spec/rails_app/config/application.rb
211
213
  - spec/rails_app/config/database.yml
@@ -235,7 +237,7 @@ homepage: https://github.com/collectiveidea/audited
235
237
  licenses:
236
238
  - MIT
237
239
  metadata: {}
238
- post_install_message:
240
+ post_install_message:
239
241
  rdoc_options: []
240
242
  require_paths:
241
243
  - lib
@@ -250,8 +252,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
250
252
  - !ruby/object:Gem::Version
251
253
  version: '0'
252
254
  requirements: []
253
- rubygems_version: 3.0.4
254
- signing_key:
255
+ rubygems_version: 3.1.4
256
+ signing_key:
255
257
  specification_version: 4
256
258
  summary: Log all changes to your models
257
259
  test_files: []