attr_masker 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 43cbbd6cf1150e2228d2b5fc1323bbdbae852510
4
- data.tar.gz: 614372bc5a85ac8b23112062b437a8d468064160
3
+ metadata.gz: 84f6dabd5fc0ea9d919da16d60ca4b06c46b2c97
4
+ data.tar.gz: 72d8b8eeb8eb59a24c7613c752fb8c2175be566f
5
5
  SHA512:
6
- metadata.gz: cb815eda36c7a99d2cfebf18df5a1b901a5e597df340b6f2041bd9bdb6ee722b4fac5b21dde71457ad63794de5cc3e1aec2659c02d32c2aea6e0bce7dfff2b8c
7
- data.tar.gz: 6e97866032f1d8c1323e11bb160f62d9798f001b2736b98be03907f9269f39ff462be45633ac3c59c04856621196fc8979556c1438cac3b6be5eff68f1f6c238
6
+ metadata.gz: 0274cb6920ce73043fff153a27c8140cfb3fa9ec095a020c1fe5f4180e1339d0ad75bb41cccf5a68573d351b3fb4b98ced45829ff836729e2c7966a8b9b3316e
7
+ data.tar.gz: 3e13de85e38714f92b9a10cbdcae9178ea6bf81ebca353b63e764ed33d797e759cb489803ee22f006883548b9d2ca1daad2ee2ceb17658da16d92f9097651015
data/.travis.yml CHANGED
@@ -3,6 +3,9 @@ dist: trusty
3
3
  language: ruby
4
4
  before_install: gem install bundler -v 1.15.1
5
5
 
6
+ services:
7
+ - mongodb
8
+
6
9
  script:
7
10
  - bundle exec rspec
8
11
 
@@ -26,6 +29,14 @@ matrix:
26
29
  gemfile: "gemfiles/Rails-4.1.gemfile"
27
30
  - rvm: "2.2"
28
31
  gemfile: "gemfiles/Rails-4.0.gemfile"
32
+ - rvm: "2.4"
33
+ gemfile: "gemfiles/Rails-5.1.gemfile"
34
+ env:
35
+ - WITHOUT_ACTIVE_RECORD: "1"
36
+ - rvm: "2.4"
37
+ gemfile: "gemfiles/Rails-5.1.gemfile"
38
+ env:
39
+ - WITHOUT_MONGOID: "1"
29
40
 
30
41
  allow_failures:
31
42
  - rvm: "ruby-head"
data/CHANGELOG.adoc CHANGED
@@ -1,3 +1,10 @@
1
+ == Not released yet
2
+
3
+ == 0.2.0
4
+
5
+ * `AttrMasker::Maskers::Simple` is now a class
6
+ * Added support for Mongoid
7
+
1
8
  == 0.1.1
2
9
 
3
10
  * Mask records disregarding default scope
data/README.adoc CHANGED
@@ -6,13 +6,13 @@
6
6
  image:https://img.shields.io/gem/v/attr_masker.svg["Gem Version", link="https://rubygems.org/gems/attr_masker"]
7
7
  image:https://img.shields.io/travis/riboseinc/attr_masker/master.svg["Build Status", link="https://travis-ci.org/riboseinc/attr_masker"]
8
8
 
9
- Mask ActiveRecord data with ease!
9
+ Mask ActiveRecord/Mongoid data with ease!
10
10
 
11
11
  == Introduction
12
12
 
13
13
  This gem is intended to mask sensitive data so that production database dumps
14
- can be used in staging or test environments. It works with Active Record 4+
15
- and modern Rubies.
14
+ can be used in staging or test environments. It works with Rails 4+ and modern
15
+ Rubies. It supports Active Record and Mongoid models.
16
16
 
17
17
  == Getting started
18
18
 
@@ -76,7 +76,7 @@ gem to soft-delete your data, records marked as deleted will be masked as well.
76
76
 
77
77
  === Using custom maskers
78
78
 
79
- By default, data is maksed with `AttrMasker::Maskers::SIMPLE` masker which
79
+ By default, data is maksed with `AttrMasker::Maskers::Simple` masker which
80
80
  always returns `"(redacted)"` string. But anything what responds to `#call`
81
81
  can be used instead: a lambda, `Method` instance, and more. You can specify it
82
82
  by setting the `:masker` option.
@@ -100,7 +100,7 @@ customize masker's behaviour.
100
100
 
101
101
  Attr Masker comes with several built-in maskers.
102
102
 
103
- `AttrMasker::Maskers::SIMPLE`::
103
+ `AttrMasker::Maskers::Simple`::
104
104
  +
105
105
  Simply replaces any value with the `"(redacted)"`. Only useful for columns
106
106
  containing textual data.
@@ -112,7 +112,7 @@ Example:
112
112
  [source,ruby]
113
113
  ----
114
114
  attr_masker :first_name
115
- attr_masker :last_name, :masker => AttrMasker::Maskers::SIMPLE
115
+ attr_masker :last_name, :masker => AttrMasker::Maskers::Simple.new
116
116
  ----
117
117
  +
118
118
  Would set both `first_name` and `last_name` attributes to `"(redacted)"`.
data/attr_masker.gemspec CHANGED
@@ -27,6 +27,8 @@ Gem::Specification.new do |gem|
27
27
  gem.add_development_dependency("bundler", "~> 1.15")
28
28
  gem.add_development_dependency("combustion", "~> 0.7.0")
29
29
  gem.add_development_dependency("database_cleaner", "~> 1.6")
30
+ # Older versions aren't needed as we don't support Rails < 4
31
+ gem.add_development_dependency("mongoid", ">= 5")
30
32
  gem.add_development_dependency("pry")
31
33
  gem.add_development_dependency("rspec", ">= 3.0")
32
34
  gem.add_development_dependency("rubocop", "~> 0.49.1")
@@ -1,5 +1,3 @@
1
- source "https://rubygems.org"
1
+ eval File.read "gemfiles/common.gemfile"
2
2
 
3
3
  gem "activerecord", "~> 4.0.0"
4
-
5
- gemspec path: ".."
@@ -1,5 +1,3 @@
1
- source "https://rubygems.org"
1
+ eval File.read "gemfiles/common.gemfile"
2
2
 
3
3
  gem "activerecord", "~> 4.1.0"
4
-
5
- gemspec path: ".."
@@ -1,5 +1,3 @@
1
- source "https://rubygems.org"
1
+ eval File.read "gemfiles/common.gemfile"
2
2
 
3
3
  gem "activerecord", "~> 4.2.0"
4
-
5
- gemspec path: ".."
@@ -1,5 +1,3 @@
1
- source "https://rubygems.org"
1
+ eval File.read "gemfiles/common.gemfile"
2
2
 
3
3
  gem "activerecord", "~> 5.0.0"
4
-
5
- gemspec path: ".."
@@ -1,5 +1,3 @@
1
- source "https://rubygems.org"
1
+ eval File.read "gemfiles/common.gemfile"
2
2
 
3
3
  gem "activerecord", "~> 5.1.0"
4
-
5
- gemspec path: ".."
@@ -1,6 +1,4 @@
1
- source "https://rubygems.org"
1
+ eval File.read "gemfiles/common.gemfile"
2
2
 
3
3
  gem "activerecord", github: "rails/rails"
4
4
  gem "arel", github: "rails/arel"
5
-
6
- gemspec path: ".."
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec path: ".."
4
+
5
+ gem "mongoid", require: false
data/lib/attr_masker.rb CHANGED
@@ -12,7 +12,7 @@ module AttrMasker
12
12
 
13
13
  module Maskers
14
14
  autoload :Replacing, "attr_masker/maskers/replacing"
15
- autoload :SIMPLE, "attr_masker/maskers/simple"
15
+ autoload :Simple, "attr_masker/maskers/simple"
16
16
  end
17
17
 
18
18
  require "attr_masker/railtie" if defined?(Rails)
@@ -5,8 +5,10 @@ module AttrMasker
5
5
  # +opts+ is a Hash with the key :value that gives you the current attribute
6
6
  # value.
7
7
  #
8
- SIMPLE = lambda do |_opts|
9
- "(redacted)"
8
+ class Simple
9
+ def call(_opts)
10
+ "(redacted)"
11
+ end
10
12
  end
11
13
  end
12
14
  end
@@ -82,7 +82,7 @@ module AttrMasker
82
82
  marshaler: Marshal,
83
83
  dump_method: "dump",
84
84
  load_method: "load",
85
- masker: AttrMasker::Maskers::SIMPLE,
85
+ masker: AttrMasker::Maskers::Simple.new,
86
86
  }
87
87
 
88
88
  options = args.extract_options!.
@@ -2,12 +2,8 @@
2
2
  #
3
3
  module AttrMasker
4
4
  module Performer
5
- class ActiveRecord
5
+ class Base
6
6
  def mask
7
- unless defined? ::ActiveRecord
8
- raise AttrMasker::Error, "ActiveRecord undefined. Nothing to do!"
9
- end
10
-
11
7
  # Do not want production environment to be masked!
12
8
  #
13
9
  if Rails.env.production?
@@ -44,7 +40,7 @@ module AttrMasker
44
40
  acc.merge!(column_name => masker_value)
45
41
  end
46
42
 
47
- klass.all.unscoped.update(instance.id, updates)
43
+ make_update instance, updates unless updates.empty?
48
44
  end
49
45
 
50
46
  def progressbar_for_model(klass)
@@ -59,10 +55,34 @@ module AttrMasker
59
55
  ensure
60
56
  bar.finish
61
57
  end
58
+ end
59
+
60
+ class ActiveRecord < Base
61
+ def dependencies_available?
62
+ defined? ::ActiveRecord
63
+ end
62
64
 
63
65
  def all_models
64
66
  ::ActiveRecord::Base.descendants.select(&:table_exists?)
65
67
  end
68
+
69
+ def make_update(instance, updates)
70
+ instance.class.all.unscoped.update(instance.id, updates)
71
+ end
72
+ end
73
+
74
+ class Mongoid < Base
75
+ def dependencies_available?
76
+ defined? ::Mongoid
77
+ end
78
+
79
+ def all_models
80
+ ::Mongoid.models
81
+ end
82
+
83
+ def make_update(instance, updates)
84
+ instance.class.all.unscoped.where(id: instance.id).update(updates)
85
+ end
66
86
  end
67
87
  end
68
88
  end
@@ -5,8 +5,8 @@ module AttrMasker
5
5
  # Contains information about this gem's version
6
6
  module Version
7
7
  MAJOR = 0
8
- MINOR = 1
9
- PATCH = 1
8
+ MINOR = 2
9
+ PATCH = 0
10
10
 
11
11
  # Returns a version string by joining <tt>MAJOR</tt>, <tt>MINOR</tt>, and
12
12
  # <tt>PATCH</tt> with <tt>'.'</tt>
data/lib/tasks/db.rake CHANGED
@@ -16,6 +16,13 @@ namespace :db do
16
16
  # http://stackoverflow.com/questions/14163938/activerecordconnectionnotestablished-within-a-rake-task
17
17
  #
18
18
  task :mask => :environment do
19
- AttrMasker::Performer::ActiveRecord.new.mask
19
+ performers = AttrMasker::Performer::Base.descendants.map(&:new)
20
+ performers.select!(&:dependencies_available?)
21
+
22
+ if performers.empty?
23
+ raise AttrMasker::Error, "No supported database!"
24
+ end
25
+
26
+ performers.each(&:mask)
20
27
  end
21
28
  end
@@ -0,0 +1,33 @@
1
+ # Heavily based on Mongoid's test suite
2
+ # https://github.com/mongodb/mongoid/blob/v6.2.0/spec/config/mongoid.yml
3
+ test:
4
+ clients:
5
+ default:
6
+ database: attr_masker_test
7
+ hosts:
8
+ - <%=ENV["MONGOID_SPEC_HOST"]%>:<%=ENV["MONGOID_SPEC_PORT"]%>
9
+ options:
10
+ auth_source: "admin"
11
+ read:
12
+ mode: :primary_preferred
13
+ tag_sets:
14
+ - use: web
15
+ max_pool_size: 1
16
+ reports:
17
+ database: reports
18
+ hosts:
19
+ - <%=ENV["MONGOID_SPEC_HOST"]%>:<%=ENV["MONGOID_SPEC_PORT"]%>
20
+ options:
21
+ user: "mongoid-user"
22
+ password: "password"
23
+ auth_source: "admin"
24
+ options:
25
+ include_root_in_json: false
26
+ include_type_for_serialization: false
27
+ preload_models: false
28
+ scope_overwrite_exception: false
29
+ raise_not_found_error: true
30
+ use_activesupport_time_zone: true
31
+ use_utc: false
32
+ log_level: :warn
33
+ app_name: 'testing'
@@ -0,0 +1,28 @@
1
+ # (c) 2017 Ribose Inc.
2
+ #
3
+
4
+ # No point in using ApplicationRecord here.
5
+ # rubocop:disable Rails/ApplicationRecord
6
+
7
+ require_relative "shared_examples"
8
+
9
+ RSpec.describe "Attr Masker gem", :suppress_progressbar do
10
+ context "when used with ActiveRecord" do
11
+ before do
12
+ if ENV["WITHOUT_ACTIVE_RECORD"]
13
+ expect(defined?(::ActiveRecord)).to be(nil)
14
+ skip "Active Record specs disabled with WITHOUT_ACTIVE_RECORD shell " \
15
+ "variable"
16
+ end
17
+ end
18
+
19
+ before do
20
+ allow(ActiveRecord::Base).to receive(:descendants).
21
+ and_return([ActiveRecord::SchemaMigration, user_class_definition])
22
+ end
23
+
24
+ let(:user_class_definition) { Class.new(ActiveRecord::Base) }
25
+
26
+ include_examples "Attr Masker gem feature specs"
27
+ end
28
+ end
@@ -0,0 +1,36 @@
1
+ # (c) 2017 Ribose Inc.
2
+ #
3
+
4
+ require_relative "shared_examples"
5
+
6
+ RSpec.describe "Attr Masker gem", :suppress_progressbar do
7
+ context "when used with Mongoid" do
8
+ before do
9
+ if ENV["WITHOUT_MONGOID"]
10
+ expect(defined?(::Mongoid)).to be(nil)
11
+ skip "Mongoid specs disabled with WITHOUT_MONGOID shell variable"
12
+ end
13
+ end
14
+
15
+ after do
16
+ # Remove the example-specific model from Mongoid.models
17
+ ::Mongoid.models.delete(user_class_definition)
18
+ end
19
+
20
+ let(:user_class_definition) do
21
+ Class.new do
22
+ include Mongoid::Document
23
+ include Mongoid::Timestamps
24
+
25
+ store_in collection: "users"
26
+
27
+ field :first_name
28
+ field :last_name
29
+ field :email
30
+ field :avatar
31
+ end
32
+ end
33
+
34
+ include_examples "Attr Masker gem feature specs"
35
+ end
36
+ end
@@ -1,26 +1,20 @@
1
1
  # (c) 2017 Ribose Inc.
2
2
  #
3
3
 
4
- # No point in using ApplicationRecord here.
5
- # rubocop:disable Rails/ApplicationRecord
6
-
7
4
  # No point in ensuring a trailing comma in multiline argument lists here.
8
5
  # rubocop:disable Style/TrailingCommaInArguments
9
6
 
10
7
  require "spec_helper"
11
8
 
12
- RSpec.describe "Attr Masker gem", :suppress_progressbar do
9
+ RSpec.shared_examples "Attr Masker gem feature specs" do
13
10
  before do
14
- stub_const "User", Class.new(ActiveRecord::Base)
11
+ stub_const "User", user_class_definition
15
12
 
16
13
  User.class_eval do
17
14
  def jedi?
18
15
  email.ends_with? "@jedi.example.test"
19
16
  end
20
17
  end
21
-
22
- allow(ActiveRecord::Base).to receive(:descendants).
23
- and_return([ActiveRecord::SchemaMigration, User])
24
18
  end
25
19
 
26
20
  let!(:han) do
data/spec/spec_helper.rb CHANGED
@@ -4,7 +4,7 @@
4
4
  require "bundler"
5
5
  Bundler.require :default, :development
6
6
 
7
- Dir[File.expand_path "../support/**/*.rb", __FILE__].each { |f| require f }
7
+ Dir[File.expand_path "../support/**/*.rb", __FILE__].sort.each { |f| require f }
8
8
 
9
9
  RSpec.configure do |config|
10
10
  # Enable flags like --only-failures and --next-failure
@@ -17,5 +17,3 @@ RSpec.configure do |config|
17
17
  c.syntax = :expect
18
18
  end
19
19
  end
20
-
21
- require "rails/all"
@@ -0,0 +1,9 @@
1
+ # Copied from Mongoid's test suite
2
+ # https://github.com/mongodb/mongoid/blob/v6.2.0/spec/spec_helper.rb
3
+
4
+ # These environment variables can be set if wanting to test against a database
5
+ # that is not on the local machine.
6
+ ENV["MONGOID_SPEC_HOST"] ||= "127.0.0.1"
7
+ ENV["MONGOID_SPEC_PORT"] ||= "27017"
8
+
9
+ require "mongoid" unless ENV["WITHOUT_MONGOID"]
@@ -0,0 +1,10 @@
1
+ # (c) 2017 Ribose Inc.
2
+ #
3
+
4
+ Combustion.path = "spec/dummy"
5
+
6
+ if ENV["WITHOUT_ACTIVE_RECORD"].nil?
7
+ Combustion.initialize! :active_record
8
+ else
9
+ Combustion.initialize!
10
+ end
@@ -2,9 +2,18 @@ require "database_cleaner"
2
2
 
3
3
  RSpec.configure do |config|
4
4
  config.before(:suite) do
5
- DatabaseCleaner.clean_with(:truncation)
5
+ unless ENV["WITHOUT_ACTIVE_RECORD"]
6
+ DatabaseCleaner[:active_record].strategy = :truncation
7
+ end
6
8
 
7
- DatabaseCleaner.strategy = :truncation
9
+ # Since models are defined dynamically in specs, Database Cleaner is unable
10
+ # to list them and to determine collection names to be cleaned.
11
+ # Therefore, they are specified explicitly here.
12
+ unless ENV["WITHOUT_MONGOID"]
13
+ DatabaseCleaner[:mongoid].strategy = :truncation, { only: "users" }
14
+ end
15
+
16
+ DatabaseCleaner.clean_with(:truncation)
8
17
  end
9
18
 
10
19
  config.around(:each) do |example|
@@ -5,8 +5,8 @@
5
5
 
6
6
  require "spec_helper"
7
7
 
8
- RSpec.describe AttrMasker::Maskers::SIMPLE do
9
- subject { described_class }
8
+ RSpec.describe AttrMasker::Maskers::Simple do
9
+ subject { described_class.new }
10
10
 
11
11
  example { expect(subject.(value: "Solo")).to eq("(redacted)") }
12
12
  example { expect(subject.(value: Math::PI)).to eq("(redacted)") }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attr_masker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-07 00:00:00.000000000 Z
11
+ date: 2017-09-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -86,6 +86,20 @@ dependencies:
86
86
  - - "~>"
87
87
  - !ruby/object:Gem::Version
88
88
  version: '1.6'
89
+ - !ruby/object:Gem::Dependency
90
+ name: mongoid
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '5'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '5'
89
103
  - !ruby/object:Gem::Dependency
90
104
  name: pry
91
105
  requirement: !ruby/object:Gem::Requirement
@@ -169,6 +183,7 @@ files:
169
183
  - gemfiles/Rails-5.0.gemfile
170
184
  - gemfiles/Rails-5.1.gemfile
171
185
  - gemfiles/Rails-head.gemfile
186
+ - gemfiles/common.gemfile
172
187
  - lib/attr_masker.rb
173
188
  - lib/attr_masker/attribute.rb
174
189
  - lib/attr_masker/error.rb
@@ -180,12 +195,16 @@ files:
180
195
  - lib/attr_masker/version.rb
181
196
  - lib/tasks/db.rake
182
197
  - spec/dummy/config/database.yml
198
+ - spec/dummy/config/mongoid.yml
183
199
  - spec/dummy/config/routes.rb
184
200
  - spec/dummy/db/schema.rb
185
201
  - spec/dummy/public/favicon.ico
186
- - spec/features_spec.rb
202
+ - spec/features/active_record_spec.rb
203
+ - spec/features/mongoid_spec.rb
204
+ - spec/features/shared_examples.rb
187
205
  - spec/spec_helper.rb
188
- - spec/support/0_combustion.rb
206
+ - spec/support/00_mongoid_env.rb
207
+ - spec/support/20_combustion.rb
189
208
  - spec/support/db_cleaner.rb
190
209
  - spec/support/matchers.rb
191
210
  - spec/support/rake.rb
@@ -220,12 +239,16 @@ specification_version: 4
220
239
  summary: Masking attributes
221
240
  test_files:
222
241
  - spec/dummy/config/database.yml
242
+ - spec/dummy/config/mongoid.yml
223
243
  - spec/dummy/config/routes.rb
224
244
  - spec/dummy/db/schema.rb
225
245
  - spec/dummy/public/favicon.ico
226
- - spec/features_spec.rb
246
+ - spec/features/active_record_spec.rb
247
+ - spec/features/mongoid_spec.rb
248
+ - spec/features/shared_examples.rb
227
249
  - spec/spec_helper.rb
228
- - spec/support/0_combustion.rb
250
+ - spec/support/00_mongoid_env.rb
251
+ - spec/support/20_combustion.rb
229
252
  - spec/support/db_cleaner.rb
230
253
  - spec/support/matchers.rb
231
254
  - spec/support/rake.rb
@@ -1,5 +0,0 @@
1
- # (c) 2017 Ribose Inc.
2
- #
3
-
4
- Combustion.path = "spec/dummy"
5
- Combustion.initialize! :all