anonymous 0.0.1 → 0.1.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a6a9033ae3bc4fd39ceda354e07a2795b83f0c41
4
- data.tar.gz: 455d838090ad8422a5405a79da005333f4fa9f5a
3
+ metadata.gz: d683875143716c1f88d1f357b794ccde3f1b8b9e
4
+ data.tar.gz: cd9333dae0d8859396e106efc54c579ab50e214e
5
5
  SHA512:
6
- metadata.gz: edac28ed6aa5552480967d872a69f774c7225f56b27781d7d6131ff64dc3ca077c6549fa5974fd3fb7af22ee48e21809c899095f2d8fe30ebf131d4097f4d405
7
- data.tar.gz: 56294a50da1f9d0b88531f6212cceb191edca2930d9410db99ee5de1badd22b2935102ad14e4da03790c460787e733a69ef2d99457a540762904fc5af33015c1
6
+ metadata.gz: f59daf6693ef9f8dc85a3ba34ccce68cca7eadb445acacfec6f25bcee48443168c548ef6fb50ab76f3c8771df69b58a7f82c0516b71f93ab6bc5a8335006f36c
7
+ data.tar.gz: 937bd58e5c9539f1ec7261af2cb8668d37501adf6df507a110e50e0c67ddb5f7bee4783dbbc37a5b82e981e1a8ad3034ace6e03ca8e534138dd0762aac968be7
data/.travis.yml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
2
  sudo: false
3
3
  language: ruby
4
- cache: bundler
5
4
  rvm:
6
- - 2.4.2
5
+ - 2.2
6
+ - 2.3
7
+ - 2.4
8
+ - 2.5
9
+ cache: bundler
10
+ gemfile:
11
+ - gemfiles/4.2.gemfile
12
+ - gemfiles/5.0.gemfile
13
+ - gemfiles/5.1.gemfile
14
+ - gemfiles/5.2.gemfile
7
15
  before_install: gem install bundler -v 1.17.2
data/Appraisals ADDED
@@ -0,0 +1,15 @@
1
+ appraise "4.2" do
2
+ gem "activerecord", "~> 4.2.5.1"
3
+ end
4
+
5
+ appraise "5.0" do
6
+ gem "activerecord", "~> 5.0.0"
7
+ end
8
+
9
+ appraise "5.1" do
10
+ gem "activerecord", "~> 5.1.0"
11
+ end
12
+
13
+ appraise "5.2" do
14
+ gem "activerecord", "~> 5.2.0"
15
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,69 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ anonymous (0.1.1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ activemodel (5.2.2)
10
+ activesupport (= 5.2.2)
11
+ activerecord (5.2.2)
12
+ activemodel (= 5.2.2)
13
+ activesupport (= 5.2.2)
14
+ arel (>= 9.0)
15
+ activesupport (5.2.2)
16
+ concurrent-ruby (~> 1.0, >= 1.0.2)
17
+ i18n (>= 0.7, < 2)
18
+ minitest (~> 5.1)
19
+ tzinfo (~> 1.1)
20
+ appraisal (2.2.0)
21
+ bundler
22
+ rake
23
+ thor (>= 0.14.0)
24
+ arel (9.0.0)
25
+ coderay (1.1.2)
26
+ concurrent-ruby (1.1.4)
27
+ diff-lcs (1.3)
28
+ i18n (1.3.0)
29
+ concurrent-ruby (~> 1.0)
30
+ method_source (0.9.2)
31
+ minitest (5.11.3)
32
+ pry (0.12.2)
33
+ coderay (~> 1.1.0)
34
+ method_source (~> 0.9.0)
35
+ rake (10.5.0)
36
+ rspec (3.8.0)
37
+ rspec-core (~> 3.8.0)
38
+ rspec-expectations (~> 3.8.0)
39
+ rspec-mocks (~> 3.8.0)
40
+ rspec-core (3.8.0)
41
+ rspec-support (~> 3.8.0)
42
+ rspec-expectations (3.8.2)
43
+ diff-lcs (>= 1.2.0, < 2.0)
44
+ rspec-support (~> 3.8.0)
45
+ rspec-mocks (3.8.0)
46
+ diff-lcs (>= 1.2.0, < 2.0)
47
+ rspec-support (~> 3.8.0)
48
+ rspec-support (3.8.0)
49
+ sqlite3 (1.3.13)
50
+ thor (0.20.3)
51
+ thread_safe (0.3.6)
52
+ tzinfo (1.2.5)
53
+ thread_safe (~> 0.1)
54
+
55
+ PLATFORMS
56
+ ruby
57
+
58
+ DEPENDENCIES
59
+ activerecord
60
+ anonymous!
61
+ appraisal
62
+ bundler (~> 1.17)
63
+ pry
64
+ rake (~> 10.0)
65
+ rspec (~> 3.0)
66
+ sqlite3
67
+
68
+ BUNDLED WITH
69
+ 1.17.2
data/README.md CHANGED
@@ -1,8 +1,10 @@
1
1
  # Anonymous
2
+ [![Gem Version](https://badge.fury.io/rb/anonymous.svg)](https://badge.fury.io/rb/anonymous)
3
+ [![Build Status](https://travis-ci.com/jamesstonehill/anonymous.svg?branch=master)](https://travis-ci.com/jamesstonehill/anonymous)
2
4
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/anonymous`. To experiment with that code, run `bin/console` for an interactive prompt.
4
-
5
- TODO: Delete this and the text above, and describe your gem
5
+ Anonymous is a light-weight gem that makes anonymizing ActiveRecord models easy!
6
+ Remember, friends don't let friends use production data in
7
+ staging/development.
6
8
 
7
9
  ## Installation
8
10
 
@@ -16,24 +18,116 @@ And then execute:
16
18
 
17
19
  $ bundle
18
20
 
19
- Or install it yourself as:
21
+ ## Usage
20
22
 
21
- $ gem install anonymous
23
+ ### Usage With ActiveRecord
24
+ To use this gem in your ActiveRecord models you need to do two things.
25
+ 1. Include the `Anonymous::ActiveRecord` module in your model
26
+ 2. Define a private method `anonymization_definitions` with the anonymization
27
+ definitions inside it.
22
28
 
23
- ## Usage
29
+ ```ruby
30
+ class User < ApplicationRecord
31
+ include Anonymous::ActiveRecord
32
+
33
+ private
34
+
35
+ def anonymization_definitions
36
+ {
37
+ name: ["Bob Dylan", "Tony Blair"].sample,
38
+ email: -> (user_email) { "fake_#{user_email}" },
39
+ phone_number: -> (phone) { phone[0..-4] + 3.times.map{rand(10)}.join },
40
+ }
41
+ end
42
+ end
43
+ ```
44
+
45
+ The return value of `anonymization_definitions` should be a Hash where the keys
46
+ are the names of the attribute to be anonymized and the values are either a
47
+ `Proc` object or the value to be filled in for the anonymized attribute.
48
+
49
+ If you use a proc or lambda as the argument then the attribute value will be
50
+ provided to you in the proc's first argument. This is useful when you want your
51
+ anonymized value to be a transformation of the original.
52
+
53
+ It is recommended that you use this gem in conjunction with a fake data
54
+ generation library like [faker](https://github.com/stympy/faker).
55
+
56
+ ```ruby
57
+ def anonymization_definitions
58
+ {
59
+ first_name: Faker::Name.first_name,
60
+ email: Faker::Internet.unique.email,
61
+ }
62
+ end
63
+ ```
64
+
65
+ Then when you have set up the gem correctly you can call `anonymize` and
66
+ `anonymize!` on the model.
24
67
 
25
- TODO: Write usage instructions here
68
+ ```ruby
69
+ user = User.create(
70
+ name: "John Smith",
71
+ email: "john.smith@example.com",
72
+ phone_number: "+447875477389"
73
+ )
74
+ user.anonymize! # or user.anonymize
75
+ user.reload
76
+ user.email
77
+ => "fake_john.smith@example.com"
78
+ user.name
79
+ => "Bob Dylan"
80
+ user.phone_number
81
+ => "+447875477412"
82
+ ```
83
+
84
+ The only difference between `anonymize!` and `anonymize` is that the former
85
+ calls `update!` and the latter calls `update`.
86
+
87
+ ## Configuration
88
+
89
+ You can configure the gem to alter the anonymisation behaviour.
90
+
91
+ ```ruby
92
+ # config/initializers/anonymous.rb
93
+
94
+ Anonymous.configure do |config|
95
+ config.max_anonymize_retries = 0
96
+ end
97
+ ```
98
+
99
+ ### Configuration Options
100
+
101
+ 1. max_anonymize_retries
102
+ Under some situations (like if an RecordNotUnique error is raised when updating)
103
+ the gem will retry the anonymization process. By default it will only do this
104
+ once.
26
105
 
27
106
  ## Development
28
107
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
108
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run
109
+ `bundle exec rake appraisal spec` to run the tests. You can also run
110
+ `bin/console` for an interactive prompt that will allow you to experiment.
30
111
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
112
+ To install this gem onto your local machine, run `bundle exec rake install`. To
113
+ release a new version, update the version number in `version.rb`, and then run
114
+ `bundle exec rake release`, which will create a git tag for the version, push
115
+ git commits and tags, and push the `.gem` file to
116
+ [rubygems.org](https://rubygems.org).
32
117
 
33
118
  ## Contributing
34
119
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/anonymous.
120
+ Bug reports and pull requests are welcome on GitHub at
121
+ https://github.com/jamesstonehill/anonymous.
122
+
123
+ Some ideas for feature contributions:
124
+ - Support for ORMs other than ActiveRecord.
125
+ - More comprehensive retry functionality in Anonymous::ActiveRecord. A the
126
+ moment we only retry if we get an ActiveRecord::RecordNotUnique unique
127
+ error. I didn't want to blindly rescue all errors, but it seems like that
128
+ there are other times we would want to retry.
36
129
 
37
130
  ## License
38
131
 
39
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
132
+ The gem is available as open source under the terms of the [MIT
133
+ License](https://opensource.org/licenses/MIT).
data/Rakefile CHANGED
@@ -1,5 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rspec/core/rake_task"
3
+ require "appraisal"
3
4
 
4
5
  RSpec::Core::RakeTask.new(:spec)
5
6
 
data/anonymous.gemspec CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  lib = File.expand_path("../lib", __FILE__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
3
  require "anonymous/version"
@@ -26,4 +25,8 @@ Gem::Specification.new do |spec|
26
25
  spec.add_development_dependency "bundler", "~> 1.17"
27
26
  spec.add_development_dependency "rake", "~> 10.0"
28
27
  spec.add_development_dependency "rspec", "~> 3.0"
28
+ spec.add_development_dependency "appraisal"
29
+ spec.add_development_dependency "pry"
30
+ spec.add_development_dependency "sqlite3"
31
+ spec.add_development_dependency "activerecord"
29
32
  end
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activerecord", "~> 4.2.5.1"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,73 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ anonymous (0.0.1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ activemodel (4.2.5.2)
10
+ activesupport (= 4.2.5.2)
11
+ builder (~> 3.1)
12
+ activerecord (4.2.5.2)
13
+ activemodel (= 4.2.5.2)
14
+ activesupport (= 4.2.5.2)
15
+ arel (~> 6.0)
16
+ activesupport (4.2.5.2)
17
+ i18n (~> 0.7)
18
+ json (~> 1.7, >= 1.7.7)
19
+ minitest (~> 5.1)
20
+ thread_safe (~> 0.3, >= 0.3.4)
21
+ tzinfo (~> 1.1)
22
+ appraisal (2.2.0)
23
+ bundler
24
+ rake
25
+ thor (>= 0.14.0)
26
+ arel (6.0.4)
27
+ builder (3.2.3)
28
+ coderay (1.1.2)
29
+ concurrent-ruby (1.1.4)
30
+ diff-lcs (1.3)
31
+ i18n (0.9.5)
32
+ concurrent-ruby (~> 1.0)
33
+ json (1.8.6)
34
+ method_source (0.9.2)
35
+ minitest (5.11.3)
36
+ pry (0.12.2)
37
+ coderay (~> 1.1.0)
38
+ method_source (~> 0.9.0)
39
+ rake (10.5.0)
40
+ rspec (3.8.0)
41
+ rspec-core (~> 3.8.0)
42
+ rspec-expectations (~> 3.8.0)
43
+ rspec-mocks (~> 3.8.0)
44
+ rspec-core (3.8.0)
45
+ rspec-support (~> 3.8.0)
46
+ rspec-expectations (3.8.2)
47
+ diff-lcs (>= 1.2.0, < 2.0)
48
+ rspec-support (~> 3.8.0)
49
+ rspec-mocks (3.8.0)
50
+ diff-lcs (>= 1.2.0, < 2.0)
51
+ rspec-support (~> 3.8.0)
52
+ rspec-support (3.8.0)
53
+ sqlite3 (1.3.13)
54
+ thor (0.20.3)
55
+ thread_safe (0.3.6)
56
+ tzinfo (1.2.5)
57
+ thread_safe (~> 0.1)
58
+
59
+ PLATFORMS
60
+ ruby
61
+
62
+ DEPENDENCIES
63
+ activerecord (~> 4.2.5.1)
64
+ anonymous!
65
+ appraisal
66
+ bundler (~> 1.17)
67
+ pry
68
+ rake (~> 10.0)
69
+ rspec (~> 3.0)
70
+ sqlite3
71
+
72
+ BUNDLED WITH
73
+ 1.17.2
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activerecord", "~> 5.0.0"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,69 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ anonymous (0.0.1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ activemodel (5.0.7.1)
10
+ activesupport (= 5.0.7.1)
11
+ activerecord (5.0.7.1)
12
+ activemodel (= 5.0.7.1)
13
+ activesupport (= 5.0.7.1)
14
+ arel (~> 7.0)
15
+ activesupport (5.0.7.1)
16
+ concurrent-ruby (~> 1.0, >= 1.0.2)
17
+ i18n (>= 0.7, < 2)
18
+ minitest (~> 5.1)
19
+ tzinfo (~> 1.1)
20
+ appraisal (2.2.0)
21
+ bundler
22
+ rake
23
+ thor (>= 0.14.0)
24
+ arel (7.1.4)
25
+ coderay (1.1.2)
26
+ concurrent-ruby (1.1.4)
27
+ diff-lcs (1.3)
28
+ i18n (1.2.0)
29
+ concurrent-ruby (~> 1.0)
30
+ method_source (0.9.2)
31
+ minitest (5.11.3)
32
+ pry (0.12.2)
33
+ coderay (~> 1.1.0)
34
+ method_source (~> 0.9.0)
35
+ rake (10.5.0)
36
+ rspec (3.8.0)
37
+ rspec-core (~> 3.8.0)
38
+ rspec-expectations (~> 3.8.0)
39
+ rspec-mocks (~> 3.8.0)
40
+ rspec-core (3.8.0)
41
+ rspec-support (~> 3.8.0)
42
+ rspec-expectations (3.8.2)
43
+ diff-lcs (>= 1.2.0, < 2.0)
44
+ rspec-support (~> 3.8.0)
45
+ rspec-mocks (3.8.0)
46
+ diff-lcs (>= 1.2.0, < 2.0)
47
+ rspec-support (~> 3.8.0)
48
+ rspec-support (3.8.0)
49
+ sqlite3 (1.3.13)
50
+ thor (0.20.3)
51
+ thread_safe (0.3.6)
52
+ tzinfo (1.2.5)
53
+ thread_safe (~> 0.1)
54
+
55
+ PLATFORMS
56
+ ruby
57
+
58
+ DEPENDENCIES
59
+ activerecord (~> 5.0.0)
60
+ anonymous!
61
+ appraisal
62
+ bundler (~> 1.17)
63
+ pry
64
+ rake (~> 10.0)
65
+ rspec (~> 3.0)
66
+ sqlite3
67
+
68
+ BUNDLED WITH
69
+ 1.17.2
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activerecord", "~> 5.1.0"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,69 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ anonymous (0.0.1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ activemodel (5.1.4)
10
+ activesupport (= 5.1.4)
11
+ activerecord (5.1.4)
12
+ activemodel (= 5.1.4)
13
+ activesupport (= 5.1.4)
14
+ arel (~> 8.0)
15
+ activesupport (5.1.4)
16
+ concurrent-ruby (~> 1.0, >= 1.0.2)
17
+ i18n (~> 0.7)
18
+ minitest (~> 5.1)
19
+ tzinfo (~> 1.1)
20
+ appraisal (2.2.0)
21
+ bundler
22
+ rake
23
+ thor (>= 0.14.0)
24
+ arel (8.0.0)
25
+ coderay (1.1.2)
26
+ concurrent-ruby (1.1.4)
27
+ diff-lcs (1.3)
28
+ i18n (0.9.5)
29
+ concurrent-ruby (~> 1.0)
30
+ method_source (0.9.2)
31
+ minitest (5.11.3)
32
+ pry (0.12.2)
33
+ coderay (~> 1.1.0)
34
+ method_source (~> 0.9.0)
35
+ rake (10.5.0)
36
+ rspec (3.8.0)
37
+ rspec-core (~> 3.8.0)
38
+ rspec-expectations (~> 3.8.0)
39
+ rspec-mocks (~> 3.8.0)
40
+ rspec-core (3.8.0)
41
+ rspec-support (~> 3.8.0)
42
+ rspec-expectations (3.8.2)
43
+ diff-lcs (>= 1.2.0, < 2.0)
44
+ rspec-support (~> 3.8.0)
45
+ rspec-mocks (3.8.0)
46
+ diff-lcs (>= 1.2.0, < 2.0)
47
+ rspec-support (~> 3.8.0)
48
+ rspec-support (3.8.0)
49
+ sqlite3 (1.3.13)
50
+ thor (0.20.3)
51
+ thread_safe (0.3.6)
52
+ tzinfo (1.2.5)
53
+ thread_safe (~> 0.1)
54
+
55
+ PLATFORMS
56
+ ruby
57
+
58
+ DEPENDENCIES
59
+ activerecord (~> 5.1.0)
60
+ anonymous!
61
+ appraisal
62
+ bundler (~> 1.17)
63
+ pry
64
+ rake (~> 10.0)
65
+ rspec (~> 3.0)
66
+ sqlite3
67
+
68
+ BUNDLED WITH
69
+ 1.17.2
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activerecord", "~> 5.2.0"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,69 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ anonymous (0.0.1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ activemodel (5.2.1)
10
+ activesupport (= 5.2.1)
11
+ activerecord (5.2.1)
12
+ activemodel (= 5.2.1)
13
+ activesupport (= 5.2.1)
14
+ arel (>= 9.0)
15
+ activesupport (5.2.1)
16
+ concurrent-ruby (~> 1.0, >= 1.0.2)
17
+ i18n (>= 0.7, < 2)
18
+ minitest (~> 5.1)
19
+ tzinfo (~> 1.1)
20
+ appraisal (2.2.0)
21
+ bundler
22
+ rake
23
+ thor (>= 0.14.0)
24
+ arel (9.0.0)
25
+ coderay (1.1.2)
26
+ concurrent-ruby (1.1.4)
27
+ diff-lcs (1.3)
28
+ i18n (1.2.0)
29
+ concurrent-ruby (~> 1.0)
30
+ method_source (0.9.2)
31
+ minitest (5.11.3)
32
+ pry (0.12.2)
33
+ coderay (~> 1.1.0)
34
+ method_source (~> 0.9.0)
35
+ rake (10.5.0)
36
+ rspec (3.8.0)
37
+ rspec-core (~> 3.8.0)
38
+ rspec-expectations (~> 3.8.0)
39
+ rspec-mocks (~> 3.8.0)
40
+ rspec-core (3.8.0)
41
+ rspec-support (~> 3.8.0)
42
+ rspec-expectations (3.8.2)
43
+ diff-lcs (>= 1.2.0, < 2.0)
44
+ rspec-support (~> 3.8.0)
45
+ rspec-mocks (3.8.0)
46
+ diff-lcs (>= 1.2.0, < 2.0)
47
+ rspec-support (~> 3.8.0)
48
+ rspec-support (3.8.0)
49
+ sqlite3 (1.3.13)
50
+ thor (0.20.3)
51
+ thread_safe (0.3.6)
52
+ tzinfo (1.2.5)
53
+ thread_safe (~> 0.1)
54
+
55
+ PLATFORMS
56
+ ruby
57
+
58
+ DEPENDENCIES
59
+ activerecord (~> 5.2.0)
60
+ anonymous!
61
+ appraisal
62
+ bundler (~> 1.17)
63
+ pry
64
+ rake (~> 10.0)
65
+ rspec (~> 3.0)
66
+ sqlite3
67
+
68
+ BUNDLED WITH
69
+ 1.17.2
@@ -0,0 +1,38 @@
1
+ require_relative './anonymizer'
2
+
3
+ module Anonymous
4
+ # This module handles anonymization for ActiveRecord models. In order to
5
+ # impliment this module you must define a private #anonymization_definitions
6
+ # method in your model.
7
+ #
8
+ # Retry Functionality:
9
+ # When the model update fails because of an ActiveRecord::RecordNotUnique
10
+ # exception the module will retry the update. This is in the event that the
11
+ # anonymization_definitions randomly produce values that violate a unique
12
+ # constraint in the database.
13
+ module ActiveRecord
14
+ def anonymize!
15
+ anonymizer = Anonymizer.new(attributes, anonymization_definitions)
16
+ update!(anonymizer.anonymized_attributes)
17
+ rescue ::ActiveRecord::RecordNotUnique => e
18
+ @anonymization_attempts ||= 0
19
+ max_retries = Anonymous.configuration.max_anonymize_retries
20
+ raise e if @anonymization_attempts >= max_retries
21
+
22
+ @anonymization_attempts += 1
23
+ retry
24
+ end
25
+
26
+ def anonymize
27
+ anonymizer = Anonymizer.new(attributes, anonymization_definitions)
28
+ update(anonymizer.anonymized_attributes)
29
+ rescue ::ActiveRecord::RecordNotUnique => e
30
+ @anonymization_attempts ||= 0
31
+ max_retries = Anonymous.configuration.max_anonymize_retries
32
+ raise e if @anonymization_attempts >= max_retries
33
+
34
+ @anonymization_attempts += 1
35
+ retry
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,42 @@
1
+ module Anonymous
2
+ class Anonymizer
3
+ attr_reader :anonymization_definitions
4
+
5
+ def initialize(attributes, anonymization_definitions)
6
+ @attributes = symbolize_keys(attributes)
7
+ @anonymization_definitions = symbolize_keys(anonymization_definitions)
8
+ @anonymization_attempts = 0
9
+ end
10
+
11
+ def anonymized_attributes
12
+ attributes_to_anonymise = non_nil_attributes
13
+
14
+ attributes_to_anonymise.each_with_object({}) do |(attr_name, value), result|
15
+ anonymization_definition = anonymization_definitions.fetch(attr_name)
16
+
17
+ if anonymization_definition.respond_to?(:call)
18
+ result[attr_name] = anonymization_definition.call(value)
19
+ else
20
+ result[attr_name] = anonymization_definition
21
+ end
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :attributes
28
+
29
+ def non_nil_attributes
30
+ @non_nil_attributes ||= attributes.select do |attr_name, value|
31
+ !value.nil? && anonymization_definitions[attr_name]
32
+ end
33
+ end
34
+
35
+ def symbolize_keys(hash)
36
+ hash.each_with_object({}) do |(key, value), obj|
37
+ key = key.to_sym rescue key
38
+ obj[key] = value
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,13 @@
1
+ module Anonymous
2
+ class Configuration
3
+ DEFAULTS = {
4
+ max_anonymize_retries: 1
5
+ }.freeze
6
+
7
+ attr_accessor :max_anonymize_retries
8
+
9
+ def initialize
10
+ @max_anonymize_retries = DEFAULTS[:max_anonymize_retries]
11
+ end
12
+ end
13
+ end
@@ -1,3 +1,3 @@
1
1
  module Anonymous
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.1"
3
3
  end
data/lib/anonymous.rb CHANGED
@@ -1,6 +1,16 @@
1
1
  require "anonymous/version"
2
+ require "anonymous/configuration"
3
+ require "anonymous/anonymizer"
4
+ require "anonymous/active_record"
2
5
 
3
6
  module Anonymous
4
- class Error < StandardError; end
5
- # Your code goes here...
7
+ def configure
8
+ yield configuration
9
+ end
10
+
11
+ def configuration
12
+ @configuration ||= Configuration.new
13
+ end
14
+
15
+ module_function :configure, :configuration
6
16
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: anonymous
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Stonehill
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-12-15 00:00:00.000000000 Z
11
+ date: 2018-12-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,62 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: appraisal
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: sqlite3
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: activerecord
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
55
111
  description: A gem that makes anonymising data easier.
56
112
  email:
57
113
  - jamesstonehill@gmail.com
@@ -62,14 +118,27 @@ files:
62
118
  - ".gitignore"
63
119
  - ".rspec"
64
120
  - ".travis.yml"
121
+ - Appraisals
65
122
  - Gemfile
123
+ - Gemfile.lock
66
124
  - LICENSE.txt
67
125
  - README.md
68
126
  - Rakefile
69
127
  - anonymous.gemspec
70
128
  - bin/console
71
129
  - bin/setup
130
+ - gemfiles/4.2.gemfile
131
+ - gemfiles/4.2.gemfile.lock
132
+ - gemfiles/5.0.gemfile
133
+ - gemfiles/5.0.gemfile.lock
134
+ - gemfiles/5.1.gemfile
135
+ - gemfiles/5.1.gemfile.lock
136
+ - gemfiles/5.2.gemfile
137
+ - gemfiles/5.2.gemfile.lock
72
138
  - lib/anonymous.rb
139
+ - lib/anonymous/active_record.rb
140
+ - lib/anonymous/anonymizer.rb
141
+ - lib/anonymous/configuration.rb
73
142
  - lib/anonymous/version.rb
74
143
  homepage: https://github.com/jamesstonehill/anonymous
75
144
  licenses: