tidus 1.0.7 → 1.2.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
- SHA1:
3
- metadata.gz: c26f8a839787f3c0712f126588641b88aa80afc2
4
- data.tar.gz: dec777a33cc61c0dd8775e5edcfd77fdefb6c4a5
2
+ SHA256:
3
+ metadata.gz: c0788d5eac4c060fa79f55b57512f970ebc1919994532fba9d5fcd0857db0bcd
4
+ data.tar.gz: a30b93c68023dda2caaef0c71ca0ea52c521a2bc2c39ca15f98b9a1e66e5300c
5
5
  SHA512:
6
- metadata.gz: 55388c934e09337d12323f931bf225e252eaf0a2cff6b91dd0fed2f801d509620a23663c63923af00e025417df154fb87c876ecfd3c38ab70056645140340c05
7
- data.tar.gz: 5fb5942290b79d528d27b5f3d0839c96cf1ac454d86c2c33bf029bdc604b6d8e284dff6e48293f67f820997684ad14355a1a09cd7a28de387d48244fe78e07de
6
+ metadata.gz: 06a983ac2815a1178f8b53dcdb4a219fa0322f8e2de32d8af2071f57dffac1c292534de65f74f231e9705c3b3eaca12aeff69f2c642d9261c0beff74c640993f
7
+ data.tar.gz: 612b24c8414c4721af928321f9f057e5d933b2dc629a6fd16c73fa7c7544bf72ff16acc664cb0683eef2afd681e73e6d17a8960dc375bdad094918e845b9a647
data/lib/tasks/views.rake CHANGED
@@ -1,9 +1,16 @@
1
+ skip_tables = [
2
+ 'schema_migrations',
3
+ 'ar_internal_metadata',
4
+ ]
5
+
1
6
  namespace :db do
2
7
  desc "Clears all the views which are currently existing"
3
8
  task :clear_views do
4
9
  Rails.application.eager_load! if defined?(Rails)
10
+
5
11
  ActiveRecord::Base.descendants.each do |c|
6
- next if c.table_name == "schema_migrations"
12
+ next if skip_tables.include?(c.table_name)
13
+
7
14
  puts "Clearing view '#{c.view_name}' for table '#{c.table_name}'"
8
15
 
9
16
  c.clear_view
@@ -13,8 +20,9 @@ namespace :db do
13
20
  desc "Generates all the views for the models"
14
21
  task :generate_views do
15
22
  Rails.application.eager_load! if defined?(Rails)
23
+
16
24
  ActiveRecord::Base.descendants.each do |c|
17
- next if c.table_name == "schema_migrations" || c.skip_anonymization?
25
+ next if skip_tables.include?(c.table_name) || c.skip_anonymization?
18
26
 
19
27
  if ActiveRecord::Base.connection.table_exists? c.table_name
20
28
  puts "Generating view '#{c.view_name}' for table '#{c.table_name}'"
@@ -34,4 +42,4 @@ end
34
42
 
35
43
  Rake::Task["db:rollback"].enhance do
36
44
  Rake::Task["db:generate_views"].invoke
37
- end
45
+ end
data/lib/tidus.rb CHANGED
@@ -9,5 +9,5 @@ require "tidus/anonymization"
9
9
  require "tidus/strategies/base_selector"
10
10
  Dir["#{File.dirname(__FILE__)}/tidus/strategies/**/*.rb"].each { |f| require f }
11
11
 
12
- load "active_record/railties/databases.rake"
13
- load "tasks/views.rake"
12
+ load "active_record/railties/databases.rake" if defined?(Rails)
13
+ load "tasks/views.rake"
data/lib/tidus/query.rb CHANGED
@@ -2,8 +2,19 @@
2
2
 
3
3
  module Tidus
4
4
  module Query
5
+ def create_view_query_part
6
+ case connection.instance_values['config'][:adapter].to_s.downcase
7
+ when 'postgresql'
8
+ return 'CREATE OR REPLACE VIEW'
9
+ when 'sqlite3'
10
+ return 'CREATE VIEW IF NOT EXISTS'
11
+ else
12
+ return 'CREATE VIEW'
13
+ end
14
+ end
15
+
5
16
  def create_query
6
- "CREATE VIEW #{view_name} AS " +
17
+ "#{create_view_query_part} #{view_name} AS " +
7
18
  "SELECT #{view_columns.join(', ')} " +
8
19
  "FROM #{table_name}"
9
20
  end
@@ -0,0 +1,6 @@
1
+ # encoding: utf-8
2
+
3
+ module Tidus
4
+ class EanAnonymizer < Tidus::BaseSelector
5
+ end
6
+ end
@@ -0,0 +1,147 @@
1
+ module Tidus
2
+ module Postgresql
3
+ class EanAnonymizer
4
+ BASE_MAPPING = '0123456789'.freeze
5
+ DEFAULT_MAPPING_START = 1.freeze
6
+
7
+ def self.anonymize(table_name, column_name, options = {})
8
+ mapping_snippet = build_mapped_digit_snippet(column_name, options)
9
+
10
+ query = <<-SQL
11
+ (
12
+ SELECT
13
+ string_agg(new_digits.digit::TEXT, ''::TEXT)
14
+ FROM (
15
+ (
16
+ SELECT
17
+ pos,
18
+ digit
19
+ FROM (
20
+ #{mapping_snippet}
21
+ ) AS where_sub
22
+ ORDER BY pos ASC
23
+ )
24
+ UNION ALL
25
+ (
26
+ SELECT
27
+ LENGTH(#{column_name}::TEXT) AS pos,
28
+ (
29
+ 10
30
+ -
31
+ (
32
+ (
33
+ SELECT
34
+ SUM(digit)
35
+ FROM (
36
+ #{mapping_snippet}
37
+ ) AS where_sub
38
+ WHERE pos % 2 = LENGTH(#{column_name}::TEXT) % 2
39
+ )
40
+ +
41
+ (
42
+ SELECT
43
+ SUM(digit)
44
+ FROM (
45
+ #{mapping_snippet}
46
+ ) AS where_sub
47
+ WHERE pos % 2 = (LENGTH(#{column_name}::TEXT) - 1) % 2
48
+ ) * 3
49
+ ) % 10
50
+ ) % 10 AS digit
51
+ )
52
+ ) new_digits
53
+ )
54
+ SQL
55
+
56
+ return query.gsub!(/\n/, '').gsub!(/\ +/, ' ')
57
+ end
58
+
59
+ # Generates a new mapping if no cache_key is given
60
+ # Generates a new mapping if the cache_key is unknown
61
+ # Reuses the found mapping if the cache_key is known
62
+ def self.retrieve_mapping(cache_key)
63
+ @cached_mappings ||= {}
64
+ mapping = @cached_mappings[cache_key]
65
+
66
+ if mapping == nil
67
+ mapping = {
68
+ base: BASE_MAPPING,
69
+ replacement: BASE_MAPPING.split('').shuffle.join('')
70
+ }
71
+ end
72
+
73
+ if cache_key != nil
74
+ @cached_mappings[cache_key] = mapping
75
+ end
76
+
77
+ return mapping
78
+ end
79
+
80
+ def self.build_mapped_digit_snippet(column_name, options)
81
+ substrings = build_digit_mapping(column_name, options)
82
+
83
+ return <<-SQL
84
+ SELECT
85
+ *
86
+ FROM (
87
+ SELECT
88
+ ROW_NUMBER() over () AS pos,
89
+ digit::INT
90
+ FROM (
91
+ SELECT
92
+ REGEXP_SPLIT_TO_TABLE(
93
+ #{substrings.join(' || ')},
94
+ ''
95
+ ) AS digit
96
+ ) AS sub
97
+ ) AS sub
98
+ WHERE pos < LENGTH(#{column_name}::TEXT)
99
+ SQL
100
+ end
101
+
102
+ def self.build_digit_mapping(column_name, options)
103
+ mapping = retrieve_mapping(options[:cache_key])
104
+
105
+ options[:start] ||= DEFAULT_MAPPING_START
106
+
107
+ # reduce length by 1 to take away the check digit
108
+ total_length = "LENGTH(#{column_name}::TEXT) - 1"
109
+ length = options[:length] || total_length
110
+
111
+ substrings = []
112
+
113
+ if options[:start] != DEFAULT_MAPPING_START
114
+ substrings << build_substring_snippet(
115
+ column_name,
116
+ DEFAULT_MAPPING_START,
117
+ options[:start] - DEFAULT_MAPPING_START
118
+ )
119
+ end
120
+
121
+ translate_part = <<-SNIPPET
122
+ TRANSLATE(
123
+ #{build_substring_snippet(column_name, options[:start], length)},
124
+ '#{mapping[:base]}',
125
+ '#{mapping[:replacement]}'
126
+ )
127
+ SNIPPET
128
+
129
+ substrings << translate_part.gsub(/\n/, '').gsub(/\ +/, ' ')
130
+
131
+ if options[:length] != nil
132
+ substrings << build_substring_snippet(
133
+ column_name,
134
+ "#{options[:start]} + #{options[:length]}",
135
+ "#{total_length} - #{options[:start]}"
136
+ )
137
+ end
138
+
139
+ return substrings
140
+ end
141
+
142
+ def self.build_substring_snippet(column_name, start, length)
143
+ return "SUBSTRING(#{column_name}::TEXT, #{start}, #{length})"
144
+ end
145
+ end
146
+ end
147
+ end
data/lib/tidus/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Tidus
2
- VERSION = "1.0.7"
2
+ VERSION = "1.2.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tidus
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.7
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Schoknecht
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-09 00:00:00.000000000 Z
11
+ date: 2021-04-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -16,42 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 10.0.4
19
+ version: '13.0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 10.0.4
26
+ version: '13.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 2.14.1
33
+ version: '3.9'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 2.14.1
40
+ version: '3.9'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: sqlite3
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 1.3.10
47
+ version: '1.4'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 1.3.10
54
+ version: '1.4'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: activerecord
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -68,7 +68,7 @@ dependencies:
68
68
  version: '3.2'
69
69
  description: Creates views which allow anonymization of database tables.
70
70
  email:
71
- - tobias.schoknecht@gmail.com
71
+ - tobias.schoknecht@viafintech.com
72
72
  executables: []
73
73
  extensions: []
74
74
  extra_rdoc_files: []
@@ -79,10 +79,12 @@ files:
79
79
  - lib/tidus/query.rb
80
80
  - lib/tidus/strategies/base_selector.rb
81
81
  - lib/tidus/strategies/cond_anonymizer.rb
82
+ - lib/tidus/strategies/ean_anonymizer.rb
82
83
  - lib/tidus/strategies/email_anonymizer.rb
83
84
  - lib/tidus/strategies/null_anonymizer.rb
84
85
  - lib/tidus/strategies/overlay_anonymizer.rb
85
86
  - lib/tidus/strategies/postgresql/cond_anonymizer.rb
87
+ - lib/tidus/strategies/postgresql/ean_anonymizer.rb
86
88
  - lib/tidus/strategies/postgresql/email_anonymizer.rb
87
89
  - lib/tidus/strategies/postgresql/null_anonymizer.rb
88
90
  - lib/tidus/strategies/postgresql/overlay_anonymizer.rb
@@ -99,7 +101,7 @@ homepage: ''
99
101
  licenses:
100
102
  - MIT
101
103
  metadata: {}
102
- post_install_message:
104
+ post_install_message:
103
105
  rdoc_options: []
104
106
  require_paths:
105
107
  - lib
@@ -114,9 +116,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
116
  - !ruby/object:Gem::Version
115
117
  version: '0'
116
118
  requirements: []
117
- rubyforge_project:
118
- rubygems_version: 2.2.2
119
- signing_key:
119
+ rubygems_version: 3.0.6
120
+ signing_key:
120
121
  specification_version: 4
121
122
  summary: Gem for creating anonymization views.
122
123
  test_files: []