forget_that 0.1.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c4c089033e63cc13c348be8e0fc634dc9270d835b1427faffcfce82f744fce33
4
+ data.tar.gz: ccf7e04335ecc2af7e89742d0e3046c1d2fa04f063f1a45d74de3dade8526d71
5
+ SHA512:
6
+ metadata.gz: 84525558e0101333d1c38b59a79b48230043dafac018c729f4340e34f1f4b7063b2936b72f82d738abcc1db3e054cfbfadae35312a2e0d733b9505768272ef14
7
+ data.tar.gz: 0c5e4546c6f65dcbc70d02a9179258e4d1cb0f200e8f4b54cb0787d6b2cddfb3d1b4e0d8c7d499de903d2b6c968f056001fded5c8599882d5b590b5894b07cba
@@ -0,0 +1,37 @@
1
+ exit
2
+ self.default_scoped.object_id
3
+ self.object_id
4
+ self
5
+ exit
6
+ klass.for_anonymization.to_sql
7
+ klass.where(created_at: (Time.now - 2000.years)..(Time.now), anonymized: 0)
8
+ klass.for_anonymization.to_sql
9
+ klass.where(created_at: (Time.now - 2000.years)..(Time.now), anonymized: 0)
10
+ klass.where(created_at: (Time.now - 2000.years)..(Time.now), anonymized: 1)
11
+ klass.where(created_at: (Time.now - 2000.years)..(Time.now), anonymized: true)
12
+ klass.where(created_at: (Time.now - 2000.years)..(Time.now))
13
+ klass.where(created_at: (Time.now - 2.years)..(Time.now - 90.days))
14
+ klass.where(created_at: (Time.now - 2.years)..(Time.now))
15
+ klass.where(anonymized: false, created_at: (Time.now - 2.years)..(Time.now))
16
+ klass.where(anonymized: false, created_at: (Time.now - 2000.years)..(Time.now))
17
+ klass.where(anonymized: false, created_at: (Time.now - 2000.years)..(retention_threshold.call))
18
+ end)
19
+ where(anonymized: false, created_at: (Time.now - 2000.years)..(retention_threshold.call))
20
+ scope :for_anonymization, (lambda do
21
+ klass.for_anonymization.to_sql
22
+ klass.all
23
+ klass.where(anonymizeed: true).to_sql
24
+ klass.where(anonymized: 'true').to_sql
25
+ klass.where(anonymized: true).to_sql
26
+ klass.where(anonymized: 'true')
27
+ klass.where(anonymized: true)
28
+ klass.where(anonymized: true).to_sql
29
+ klass.where(anonymized: false).to_sql
30
+ klass.where(anonymized: false)
31
+ klass.where(id: 1)
32
+ klass.where()id: 1
33
+ klass.where(anonymized: false)
34
+ klass.for_anonymization
35
+ klass.for:anonymization
36
+ klass.all
37
+ klass
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
@@ -0,0 +1,117 @@
1
+ Style/Documentation:
2
+ Enabled: false
3
+ Style/MixinUsage:
4
+ Exclude:
5
+ - 'bin/setup'
6
+ - 'bin/update'
7
+ Metrics/LineLength:
8
+ Max: 120
9
+ IgnoredPatterns: ['(\A|\s)#']
10
+
11
+ Metrics/MethodLength:
12
+ Max: 68
13
+
14
+ Metrics/ClassLength:
15
+ Max: 258
16
+ Exclude:
17
+ - 'app/components/consumer/factories/persist_leasing_request.rb'
18
+
19
+ Metrics/ModuleLength:
20
+ Max: 212
21
+
22
+ Metrics/ParameterLists:
23
+ Enabled: false
24
+
25
+ Style/MethodMissingSuper:
26
+ Enabled: false
27
+
28
+ Style/MissingRespondToMissing:
29
+ Enabled: false
30
+
31
+ Style/NumericLiteralPrefix:
32
+ Enabled: false
33
+
34
+ Naming/VariableNumber:
35
+ Enabled: false
36
+
37
+ Naming/PredicateName:
38
+ Enabled: false
39
+
40
+ Style/DoubleNegation:
41
+ Enabled: false
42
+
43
+ Style/EmptyMethod:
44
+ Enabled: false
45
+
46
+ Style/StringLiteralsInInterpolation:
47
+ Enabled: false
48
+
49
+ # Nodody really wants this. We are using Ruby! ` return ` as direct call should be used as less as possible
50
+ Style/GuardClause:
51
+ Enabled: false
52
+
53
+ Style/FormatStringToken:
54
+ Exclude:
55
+ - spec/**/*
56
+
57
+ Style/SafeNavigation:
58
+ Enabled: false
59
+
60
+ Metrics/AbcSize:
61
+ Max: 99
62
+ Exclude:
63
+ - spec/**/*
64
+
65
+ Metrics/CyclomaticComplexity:
66
+ Max: 13
67
+
68
+ Metrics/PerceivedComplexity:
69
+ Max: 14
70
+
71
+ Documentation:
72
+ Enabled: false
73
+
74
+ Layout/MultilineHashBraceLayout:
75
+ EnforcedStyle: symmetrical
76
+
77
+ Layout/AlignHash:
78
+ Enabled: false
79
+
80
+ Layout/AlignParameters:
81
+ Enabled: false
82
+
83
+ Metrics/BlockLength:
84
+ Enabled: false
85
+
86
+ # TODO: This is just a quickfix, we need to find out what this *really* does.
87
+ Lint/SafeNavigationChain:
88
+ Enabled: false
89
+
90
+ # Allows to create getter and setter methods with get_ and set_
91
+ Naming/AccessorMethodName:
92
+ Enabled: false
93
+
94
+ Naming/MemoizedInstanceVariableName:
95
+ Enabled: false
96
+
97
+ Lint/AmbiguousBlockAssociation:
98
+ Exclude:
99
+ - "spec/**/*"
100
+
101
+ Lint/AmbiguousOperator:
102
+ Enabled: true
103
+
104
+ AllCops:
105
+ DisplayCopNames: true
106
+ TargetRubyVersion: 2.5.0
107
+ CacheRootDirectory: tmp/test-results
108
+ Exclude:
109
+ - db/**/*
110
+ - bin/**
111
+ - utils/**/*
112
+ - Guardfile
113
+ - config/**/*
114
+ - node_modules/**/*
115
+ - vendor/**/*
116
+ - Gemfile
117
+ - Gemfile.lock
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.6.3
7
+ before_install: gem install bundler -v 2.0.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in forget_that.gemspec
4
+ gemspec
@@ -0,0 +1,97 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ forget_that (0.1.0)
5
+ activerecord (>= 5)
6
+ activesupport
7
+ pg
8
+ railties (>= 5)
9
+
10
+ GEM
11
+ remote: https://rubygems.org/
12
+ specs:
13
+ actionpack (6.0.2.1)
14
+ actionview (= 6.0.2.1)
15
+ activesupport (= 6.0.2.1)
16
+ rack (~> 2.0, >= 2.0.8)
17
+ rack-test (>= 0.6.3)
18
+ rails-dom-testing (~> 2.0)
19
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
20
+ actionview (6.0.2.1)
21
+ activesupport (= 6.0.2.1)
22
+ builder (~> 3.1)
23
+ erubi (~> 1.4)
24
+ rails-dom-testing (~> 2.0)
25
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
26
+ activemodel (6.0.2.1)
27
+ activesupport (= 6.0.2.1)
28
+ activerecord (6.0.2.1)
29
+ activemodel (= 6.0.2.1)
30
+ activesupport (= 6.0.2.1)
31
+ activesupport (6.0.2.1)
32
+ concurrent-ruby (~> 1.0, >= 1.0.2)
33
+ i18n (>= 0.7, < 2)
34
+ minitest (~> 5.1)
35
+ tzinfo (~> 1.1)
36
+ zeitwerk (~> 2.2)
37
+ builder (3.2.4)
38
+ concurrent-ruby (1.1.5)
39
+ crass (1.0.5)
40
+ diff-lcs (1.3)
41
+ erubi (1.9.0)
42
+ i18n (1.7.0)
43
+ concurrent-ruby (~> 1.0)
44
+ loofah (2.4.0)
45
+ crass (~> 1.0.2)
46
+ nokogiri (>= 1.5.9)
47
+ method_source (0.9.2)
48
+ mini_portile2 (2.4.0)
49
+ minitest (5.13.0)
50
+ nokogiri (1.10.7)
51
+ mini_portile2 (~> 2.4.0)
52
+ pg (1.2.1)
53
+ rack (2.0.8)
54
+ rack-test (1.1.0)
55
+ rack (>= 1.0, < 3)
56
+ rails-dom-testing (2.0.3)
57
+ activesupport (>= 4.2.0)
58
+ nokogiri (>= 1.6)
59
+ rails-html-sanitizer (1.3.0)
60
+ loofah (~> 2.3)
61
+ railties (6.0.2.1)
62
+ actionpack (= 6.0.2.1)
63
+ activesupport (= 6.0.2.1)
64
+ method_source
65
+ rake (>= 0.8.7)
66
+ thor (>= 0.20.3, < 2.0)
67
+ rake (10.5.0)
68
+ rspec (3.9.0)
69
+ rspec-core (~> 3.9.0)
70
+ rspec-expectations (~> 3.9.0)
71
+ rspec-mocks (~> 3.9.0)
72
+ rspec-core (3.9.1)
73
+ rspec-support (~> 3.9.1)
74
+ rspec-expectations (3.9.0)
75
+ diff-lcs (>= 1.2.0, < 2.0)
76
+ rspec-support (~> 3.9.0)
77
+ rspec-mocks (3.9.1)
78
+ diff-lcs (>= 1.2.0, < 2.0)
79
+ rspec-support (~> 3.9.0)
80
+ rspec-support (3.9.2)
81
+ thor (1.0.1)
82
+ thread_safe (0.3.6)
83
+ tzinfo (1.2.6)
84
+ thread_safe (~> 0.1)
85
+ zeitwerk (2.2.2)
86
+
87
+ PLATFORMS
88
+ ruby
89
+
90
+ DEPENDENCIES
91
+ bundler (~> 2.0)
92
+ forget_that!
93
+ rake (~> 10.0)
94
+ rspec (~> 3.0)
95
+
96
+ BUNDLED WITH
97
+ 2.0.2
@@ -0,0 +1,137 @@
1
+ # ForgetThat
2
+
3
+ ForgetThat is a tool to take care of critical data in your database. It replaces the critical pieces of data with anonymized data, according to pre-set per-application policy.
4
+
5
+ ## Important notice
6
+
7
+ When misconfigured and/or misused this gem can effectively wipe important data from the database. Be responsible and test before running on production data.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'forget_that'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ ## Configuration
22
+
23
+ Before gem could be used, a config in `config/anonymization_config.yml` in must be created:
24
+
25
+ ```YAML
26
+ config:
27
+ retention_time:
28
+ value: 90
29
+ unit: 'days'
30
+
31
+ schema:
32
+ table1:
33
+ name: 'Peter'
34
+ table2:
35
+ phone: '%{random_phone}'
36
+ ```
37
+
38
+ Pay attention that default placeholders are `random_date`, `hex_string`, `random_phone`, `fake_personal_id_number`, `random_amount`. You can add your own placeholders by supplying them to initializer ([see below](#custom_placeholders))
39
+
40
+ ## Database migration
41
+
42
+ After you created a config you can generate migration that adds anonymization metadata to corresponding tables:
43
+
44
+ $ rails g forget_that:install
45
+
46
+ Do not forget to run the migration:
47
+
48
+ $ rails db:migrate
49
+
50
+ ## Usage
51
+
52
+ In order to run the service, you can create an instance and use the `call` method:
53
+
54
+ ```ruby
55
+ ForgetThat::Service.new.call
56
+ ```
57
+
58
+ Calling that will find records older then `retention_time` in your configured tables and replace the configured fields with configured values.
59
+ If some of the placeholders are not supplied, or some tables do not contain `anonymization` flag the error will be raised.
60
+
61
+ ### Sidekiq
62
+
63
+ The case gem is used originally is data anonymization with accordance to data protection regulations in EU. Reducing the amount of sensitive information, after transactions are complete is the safest bet when it comes to data security.
64
+
65
+ This can be achieved through setting up a `sidekiq` worker:
66
+
67
+ ```ruby
68
+ class AnonymizeCustomerData
69
+ include Sidekiq::Worker
70
+
71
+ sidekiq_options retry: 10
72
+
73
+ def perform
74
+ Rails.logger.info('[AnonymizeCustomerData.perform] start')
75
+
76
+ ForgetThat::Service.new.call
77
+
78
+ Rails.logger.info('[AnonymizeCustomerData.perform] done')
79
+ end
80
+ end
81
+ ```
82
+
83
+ Then you can use tool like `sidekiq-cron` in order to schedule it.
84
+
85
+ ### Rake-task for using production data locally
86
+
87
+ Another use might be when a developer dumps a production database in order to play with it locally.
88
+
89
+ To be on the safe side and to not compromise sensitive data, the gem might be configured in the following way:
90
+
91
+ ```YAML
92
+ config:
93
+ retention_time:
94
+ value: 0
95
+ unit: 'seconds'
96
+
97
+ schema:
98
+ # your anonymization schema
99
+ ```
100
+
101
+ Then gem can be invoked from the rake-task. It is your responsibility to ensure that it never runs on production.
102
+
103
+ ### Custom placeholders
104
+
105
+ The default placeholders are `random_date`, `hex_string`, `random_phone`, `fake_personal_id_number`, `random_amount`. In some cases this might not be enough or behaviour might not be desireable. In that case you can supply `anonymizers` hash.
106
+
107
+ ```ruby
108
+ ForgetThat::Service.new(
109
+ anonymizers: {
110
+ foobar: -> { 'Foo' + 'Bar' }
111
+ }
112
+ ).call
113
+ ```
114
+
115
+ Each member of this hash must be a zero-arity lambda that returns a string value.
116
+
117
+ If the key in the hash matches one of the pre-defined placeholders, the pre-defined placeholder will be overridden by the new one.
118
+
119
+ After anonymizer was supplied with the lambda, it can be used in the config.
120
+
121
+ ```YAML
122
+ # ...
123
+
124
+ schema:
125
+ users:
126
+ name: 'Peter %{foobar}' #results in the "name" column of table "users" filled with "Peter FooBar"
127
+ ```
128
+
129
+ ## Development
130
+
131
+ 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.
132
+
133
+ 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).
134
+
135
+ ## Contributing
136
+
137
+ Bug reports and pull requests are welcome on GitHub at https://github.com/vehiculum-berlin/forget_that.
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "forget_that"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,17 @@
1
+ config:
2
+ retention_time:
3
+ value: 90
4
+ unit: 'days'
5
+
6
+ schema:
7
+ addresses:
8
+ city: 'Kyteż'
9
+ zip_code: '99999'
10
+ street: 'Sesame Street'
11
+ street_number: '123'
12
+ lived_since: '%{random_date}'
13
+
14
+ bank_accounts:
15
+ bic: '123456789'
16
+ iban: '123456789'
17
+ bank_name: 'ACME INC.'
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'forget_that/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'forget_that'
9
+ spec.version = ForgetThat::VERSION
10
+ spec.authors = ['Stan Pankov']
11
+ spec.email = ['s.pankov@vehiculum.de']
12
+
13
+ spec.summary = "Strip your customers' data from db"
14
+ spec.description = 'Easily setup and run anonymization policies'
15
+ spec.homepage = 'https://github.com/vehiculum-berlin'
16
+
17
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
18
+
19
+ spec.metadata['homepage_uri'] = spec.homepage
20
+ spec.metadata['source_code_uri'] = 'https://github.com/vehiculum-berlin/forget_that'
21
+ spec.metadata["changelog_uri"] = 'https://github.com/vehiculum-berlin/forget_that'
22
+
23
+ # Specify which files should be added to the gem when it is released.
24
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
25
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
26
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
27
+ end
28
+ spec.bindir = 'exe'
29
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
+ spec.require_paths = ['lib']
31
+
32
+ spec.add_development_dependency 'bundler', '~> 2.0'
33
+ spec.add_development_dependency 'rake', '~> 10.0'
34
+ spec.add_development_dependency 'rspec', '~> 3.0'
35
+
36
+ spec.add_runtime_dependency 'activerecord', '>= 5'
37
+ spec.add_runtime_dependency 'activesupport'
38
+ spec.add_runtime_dependency 'pg'
39
+ spec.add_runtime_dependency 'railties', '>= 5'
40
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forget_that/version'
4
+ require 'forget_that/service'
5
+ require 'forget_that/record'
6
+
7
+ module ForgetThat
8
+ class InvalidConfigError < StandardError; end
9
+
10
+ class << self
11
+ attr_writer :logger
12
+
13
+ def logger
14
+ @logger ||= Logger.new($stdout).tap do |log|
15
+ log.progname = self.name
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_record'
4
+ module ForgetThat
5
+ class Record < ActiveRecord::Base
6
+ retention_threshold = (
7
+ -> { YAML.load_file('config/anonymization_config.yml') } >>
8
+ ->(config) { config.dig('config', 'retention_time') } >>
9
+ ->(retention_params) { retention_params['value'].send(retention_params['unit']) } >>
10
+ ->(retention_time) { Time.current - retention_time }
11
+ )
12
+
13
+ scope :for_anonymization, (lambda do
14
+ where(anonymized: false)
15
+ .where('created_at < ?', retention_threshold.call)
16
+ end)
17
+ end
18
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ForgetThat
4
+ class Service
5
+ def initialize(options = {})
6
+ @custom_anonymizers = options[:anonymizers] || {}
7
+ end
8
+
9
+ def call
10
+ raise InvalidConfigError unless valid_config?
11
+
12
+ config.each do |table, columns|
13
+ klass = Class.new(ForgetThat::Record) { self.table_name = table }
14
+ records_hash = klass
15
+ .for_anonymization
16
+ .pluck(:id)
17
+ .map { |id| [id, populate_records_hash(columns)] }
18
+ .to_h
19
+ klass.update(records_hash.keys, records_hash.values)
20
+ end
21
+ end
22
+
23
+ def anonymizers
24
+ {
25
+ random_date: -> { Time.now - [*1..10**4].sample.days },
26
+ hex_string: -> { SecureRandom.hex(5) },
27
+ random_phone: -> { "+49#{[*0..10].map { SecureRandom.random_number(10) } .join}" },
28
+ fake_personal_id_number: -> { "DE#{[*0..10].map { SecureRandom.random_number(10) }.join}" },
29
+ random_amount: -> { [*1..80].sample * [*900..1100].sample }
30
+ }.merge(@custom_anonymizers)
31
+ end
32
+
33
+ def valid_config?
34
+ return false unless valid_anonymizer_set?
35
+ return false unless valid_database_schema?
36
+
37
+ true
38
+ end
39
+
40
+ def valid_anonymizer_set?
41
+ available = anonymizers.stringify_keys.keys
42
+ required = config
43
+ .map { |_key, value| value.map { |_key, val| val } }
44
+ .flatten
45
+ .map { |value| value.to_s.scan(/%{(\w*)\.?.*}/) }
46
+ .flatten
47
+ .uniq
48
+ return true if (required - available).empty?
49
+
50
+ ForgetThat.logger.error("Anonymizers #{(required - available).join(', ')} are not defined")
51
+ false
52
+ end
53
+
54
+ def valid_database_schema?
55
+ if config
56
+ .keys
57
+ .map { |table| ActiveRecord::Base.connection.columns(table).map(&:name).include? 'anonymized' }
58
+ .reduce { |a, b| a && b }
59
+ true
60
+ else
61
+ ForgetThat.logger.error('Some of the tables in your database do not contain `anonymized` flag')
62
+ false
63
+ end
64
+ end
65
+
66
+ private
67
+
68
+ def populate_records_hash(columns)
69
+ columns
70
+ .map { |key, value| [key, value.to_s % generate_anonymized_values] }
71
+ .to_h
72
+ .merge('anonymized' => true)
73
+ end
74
+
75
+ def generate_anonymized_values
76
+ anonymizers.map { |key, value| [key, value.call] }.to_h
77
+ end
78
+
79
+ def config
80
+ YAML.load_file('config/anonymization_config.yml').dig('schema')
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,3 @@
1
+ module ForgetThat
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators/active_record'
4
+
5
+ module ForgetThat
6
+ module Generators
7
+ class InstallGenerator < Rails::Generators::Base
8
+ include ActiveRecord::Generators::Migration
9
+ source_root File.join(__dir__, 'templates')
10
+
11
+ def copy_migration
12
+ migration_template 'migration.rb', 'db/migrate/install_forget_that.rb', migration_version: migration_version
13
+ end
14
+
15
+ def migration_version
16
+ "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
17
+ end
18
+
19
+ def used_tables
20
+ YAML
21
+ .load_file('config/anonymization_config.yml')
22
+ .dig('schema')
23
+ .keys
24
+ .map { |table| [table, ActiveRecord::Base.connection.columns(table).map(&:name).include?('anonymized')] }
25
+ .to_h
26
+ .reject { |_key, value| value }
27
+ .keys
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,7 @@
1
+ class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version %>
2
+ def change
3
+ <% used_tables.each do |table| -%>
4
+ add_column :<%= table %>, :anonymized, :boolean, default: false
5
+ <% end -%>
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,163 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: forget_that
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Stan Pankov
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-01-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: activerecord
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '5'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '5'
69
+ - !ruby/object:Gem::Dependency
70
+ name: activesupport
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
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: pg
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
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: railties
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '5'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '5'
111
+ description: Easily setup and run anonymization policies
112
+ email:
113
+ - s.pankov@vehiculum.de
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - ".byebug_history"
119
+ - ".gitignore"
120
+ - ".rspec"
121
+ - ".rubocop.yml"
122
+ - ".travis.yml"
123
+ - Gemfile
124
+ - Gemfile.lock
125
+ - README.md
126
+ - Rakefile
127
+ - bin/console
128
+ - bin/setup
129
+ - config/anonymization_config.yml
130
+ - forget_that.gemspec
131
+ - lib/forget_that.rb
132
+ - lib/forget_that/record.rb
133
+ - lib/forget_that/service.rb
134
+ - lib/forget_that/version.rb
135
+ - lib/generators/forget_that/install_generator.rb
136
+ - lib/generators/forget_that/templates/migration.rb.tt
137
+ homepage: https://github.com/vehiculum-berlin
138
+ licenses: []
139
+ metadata:
140
+ allowed_push_host: https://rubygems.org
141
+ homepage_uri: https://github.com/vehiculum-berlin
142
+ source_code_uri: https://github.com/vehiculum-berlin/forget_that
143
+ changelog_uri: https://github.com/vehiculum-berlin/forget_that
144
+ post_install_message:
145
+ rdoc_options: []
146
+ require_paths:
147
+ - lib
148
+ required_ruby_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ required_rubygems_version: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - ">="
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ requirements: []
159
+ rubygems_version: 3.0.6
160
+ signing_key:
161
+ specification_version: 4
162
+ summary: Strip your customers' data from db
163
+ test_files: []