tidus 1.0.7 → 1.2.1

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
- 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: []