column_anonymizer 0.1.0 → 0.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -1
- data/LICENSE +21 -0
- data/README.md +56 -57
- data/data.tar.gz +0 -0
- data/lib/column_anonymizer/anonymizer.rb +3 -3
- data/lib/column_anonymizer/schema_loader.rb +2 -2
- data/lib/column_anonymizer/version.rb +1 -1
- data/lib/generators/column_anonymizer/initializer/templates/column_anonymizer.rb +12 -2
- data/lib/generators/column_anonymizer/install/README +1 -1
- data/lib/generators/column_anonymizer/install/install_generator.rb +2 -2
- data/lib/generators/column_anonymizer/scan/scan_generator.rb +3 -3
- data/lib/tasks/column_anonymizer.rake +18 -22
- metadata +6 -17
- data/CUSTOM_GENERATORS_COMPLETE.md +0 -507
- data/CUSTOM_GENERATORS_GUIDE.md +0 -515
- data/CUSTOM_GENERATORS_IMPLEMENTATION.md +0 -471
- data/CUSTOM_GENERATORS_QUICK_REF.md +0 -95
- data/FEATURE_COMPLETE.md +0 -287
- data/GEMSPEC_FIX.md +0 -90
- data/IMPLEMENTATION_SUMMARY.md +0 -205
- data/QUICK_REFERENCE.md +0 -92
- data/RAKE_TASKS_GUIDE.md +0 -469
- data/RAKE_TASKS_IMPLEMENTATION.md +0 -363
- data/RAKE_TASKS_QUICK_REF.md +0 -164
- data/SCAN_GENERATOR_TEST.md +0 -141
- data/WORKFLOW_GUIDE.md +0 -368
- data/YAML_MIGRATION_GUIDE.md +0 -284
- /data/lib/generators/column_anonymizer/install/templates/{encrypted_columns.yml → anonymized_columns.yml} +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 351f52ee756bfef495e20244a9a09eb943bedd0607481a5036c367020a667c45
|
|
4
|
+
data.tar.gz: 2913789599dbc0d942ff5bcffb7240af16e514afcb843a77407b46744d00bbc1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 58b8fd172ce7fe3638ad1840161f9c557932a1d4fe8ba760b5c5574ed719168b485b69d93bfd5dd2754a313687a04f9ca55b67455c1902c2912df9f88631a337
|
|
7
|
+
data.tar.gz: 91e50ab83c8ba977aeeb2defbbbd49eff2afeb71c09768ae5d1cd2b95afd965730dab83a7c7667c8d4a3014da94c7d74c8cca2736210c7fa77d7b6e9e21af6ab
|
data/CHANGELOG.md
CHANGED
|
@@ -28,6 +28,11 @@
|
|
|
28
28
|
- Comprehensive type guessing for common column name patterns
|
|
29
29
|
|
|
30
30
|
### Changed
|
|
31
|
+
- **Configuration File Renamed**: `config/encrypted_columns.yml` → `config/anonymized_columns.yml`
|
|
32
|
+
- More descriptive and intuitive filename
|
|
33
|
+
- Better reflects the file's purpose (anonymization configuration)
|
|
34
|
+
- All generators, rake tasks, and documentation updated
|
|
35
|
+
- Migration: Simply rename your existing file
|
|
31
36
|
- Anonymizer now uses `BUILT_IN_GENERATORS` constant instead of `GENERATORS`
|
|
32
37
|
- `all_generators` method merges built-in and custom generators dynamically
|
|
33
38
|
- Scan generator now uses append-only strategy instead of regenerating entire file
|
|
@@ -36,11 +41,12 @@
|
|
|
36
41
|
- Safe for team environments with organized config files
|
|
37
42
|
- Updated install generator to suggest scan option
|
|
38
43
|
- Enhanced README with scan generator and custom generators documentation
|
|
44
|
+
- Railtie now includes `rake_tasks` block to automatically load rake tasks
|
|
39
45
|
|
|
40
46
|
## [0.1.0] - 2026-02-04
|
|
41
47
|
|
|
42
48
|
- Initial release with YAML-based configuration
|
|
43
|
-
- Add `SchemaLoader` to load encrypted column types from `config/
|
|
49
|
+
- Add `SchemaLoader` to load encrypted column types from `config/anonymized_columns.yml`
|
|
44
50
|
- Add `Encryptable` module that reads column types from YAML schema
|
|
45
51
|
- Add `Anonymizer` class with built-in generators for common data types (email, phone, SSN, name, address, etc.)
|
|
46
52
|
- Add `anonymize_model` and `anonymize_model!` methods for intelligent data anonymization
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 RoleModel Software
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Column Anonymizer
|
|
2
2
|
|
|
3
|
-
A Rails gem for intelligently anonymizing encrypted data with YAML-based configuration.
|
|
3
|
+
A vibe coded Rails gem for intelligently anonymizing encrypted data with YAML-based configuration.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
@@ -25,14 +25,6 @@ And then execute:
|
|
|
25
25
|
bundle install
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
Or install from source:
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
cd column_anonymizer
|
|
32
|
-
gem build column_anonymizer.gemspec
|
|
33
|
-
gem install column_anonymizer-0.1.0.gem
|
|
34
|
-
```
|
|
35
|
-
|
|
36
28
|
## Quick Start
|
|
37
29
|
|
|
38
30
|
### 1. Install Configuration File
|
|
@@ -41,7 +33,7 @@ gem install column_anonymizer-0.1.0.gem
|
|
|
41
33
|
rails generate column_anonymizer:install
|
|
42
34
|
```
|
|
43
35
|
|
|
44
|
-
This creates `config/
|
|
36
|
+
This creates `config/anonymized_columns.yml`.
|
|
45
37
|
|
|
46
38
|
### 2. Scan Your Models (Recommended)
|
|
47
39
|
|
|
@@ -61,9 +53,7 @@ rails generate column_anonymizer:install --scan
|
|
|
61
53
|
|
|
62
54
|
```ruby
|
|
63
55
|
class User < ApplicationRecord
|
|
64
|
-
encrypts :email
|
|
65
|
-
encrypts :phone_number
|
|
66
|
-
encrypts :ssn
|
|
56
|
+
encrypts :email, :phone_number, :ssn
|
|
67
57
|
end
|
|
68
58
|
```
|
|
69
59
|
|
|
@@ -71,7 +61,7 @@ end
|
|
|
71
61
|
|
|
72
62
|
```ruby
|
|
73
63
|
user = User.first
|
|
74
|
-
ColumnAnonymizer::Anonymizer.
|
|
64
|
+
ColumnAnonymizer::Anonymizer.anonymize_instance!(user)
|
|
75
65
|
|
|
76
66
|
# email becomes: user_a1b2c3d4@example.com
|
|
77
67
|
# phone_number becomes: +15551234567
|
|
@@ -87,19 +77,21 @@ rails generate column_anonymizer:scan
|
|
|
87
77
|
```
|
|
88
78
|
|
|
89
79
|
**Output:**
|
|
80
|
+
|
|
90
81
|
```
|
|
91
82
|
🔍 Scanning models for encrypted attributes...
|
|
92
83
|
➕ Adding User.email as 'email'
|
|
93
84
|
➕ Adding User.phone as 'phone'
|
|
94
85
|
➕ Adding User.ssn as 'ssn'
|
|
95
86
|
✅ Scanned 1 model(s) with encrypted attributes
|
|
96
|
-
📝 Appended 3 new column(s) to config/
|
|
87
|
+
📝 Appended 3 new column(s) to config/anonymized_columns.yml
|
|
97
88
|
User: email, phone, ssn
|
|
98
89
|
```
|
|
99
90
|
|
|
100
91
|
### Append-Only Updates 🎯
|
|
101
92
|
|
|
102
93
|
The scanner **preserves your existing file structure**:
|
|
94
|
+
|
|
103
95
|
- ✅ Comments and custom formatting maintained
|
|
104
96
|
- ✅ Only new entries added (minimal git diffs)
|
|
105
97
|
- ✅ Existing configuration never modified
|
|
@@ -112,16 +104,17 @@ Perfect for team environments where the YAML file has custom organization!
|
|
|
112
104
|
|
|
113
105
|
The scanner automatically detects appropriate anonymization types:
|
|
114
106
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
|
118
|
-
| `
|
|
119
|
-
| `
|
|
120
|
-
| `
|
|
121
|
-
| `
|
|
122
|
-
| `
|
|
123
|
-
| `
|
|
124
|
-
| `
|
|
107
|
+
|
|
108
|
+
| Column Name Pattern | Detected Type | Example Output |
|
|
109
|
+
| ------------------------- | ------------- | --------------------------- |
|
|
110
|
+
| `email` | `:email` | `user_a1b2c3d4@example.com` |
|
|
111
|
+
| `phone`, `mobile`, `cell` | `:phone` | `+15551234567` |
|
|
112
|
+
| `ssn`, `social_security` | `:ssn` | `123-45-6789` |
|
|
113
|
+
| `first_name`, `fname` | `:first_name` | `John`, `Jane` |
|
|
114
|
+
| `last_name`, `surname` | `:last_name` | `Smith`, `Johnson` |
|
|
115
|
+
| `name`, `full_name` | `:name` | `Anonymous User abc123` |
|
|
116
|
+
| `address`, `street` | `:address` | `1234 Anonymous St` |
|
|
117
|
+
| `password`, `token` | `:text` | `Anonymized text abc123` |
|
|
125
118
|
|
|
126
119
|
### Safe Configuration Updates
|
|
127
120
|
|
|
@@ -132,6 +125,7 @@ rails generate column_anonymizer:scan
|
|
|
132
125
|
```
|
|
133
126
|
|
|
134
127
|
**Output:**
|
|
128
|
+
|
|
135
129
|
```
|
|
136
130
|
🔍 Scanning models for encrypted attributes...
|
|
137
131
|
ℹ️ Skipping User.email (already configured as 'email')
|
|
@@ -140,19 +134,21 @@ rails generate column_anonymizer:scan
|
|
|
140
134
|
```
|
|
141
135
|
|
|
142
136
|
**What gets preserved:**
|
|
137
|
+
|
|
143
138
|
- ✅ Your comments in the YAML file
|
|
144
139
|
- ✅ Custom formatting and indentation
|
|
145
140
|
- ✅ Order of existing entries
|
|
146
141
|
- ✅ Manual type overrides
|
|
147
142
|
|
|
148
143
|
The scanner intelligently:
|
|
144
|
+
|
|
149
145
|
- Inserts new columns under their existing model
|
|
150
146
|
- Appends new models at the end of the file
|
|
151
147
|
- Never regenerates or reformats existing content
|
|
152
148
|
|
|
153
149
|
## Manual Configuration
|
|
154
150
|
|
|
155
|
-
You can also manually edit `config/
|
|
151
|
+
You can also manually edit `config/anonymized_columns.yml`:
|
|
156
152
|
|
|
157
153
|
```yaml
|
|
158
154
|
User:
|
|
@@ -175,16 +171,17 @@ CreditCard:
|
|
|
175
171
|
|
|
176
172
|
## Built-in Anonymization Types
|
|
177
173
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
|
181
|
-
| `:
|
|
182
|
-
| `:
|
|
183
|
-
| `:
|
|
184
|
-
| `:
|
|
185
|
-
| `:
|
|
186
|
-
| `:
|
|
187
|
-
| `:
|
|
174
|
+
|
|
175
|
+
| Type | Example Output | Use Case |
|
|
176
|
+
| ------------- | ----------------------------------- | ----------------------- |
|
|
177
|
+
| `:email` | `user_a1b2c3d4@example.com` | Email addresses |
|
|
178
|
+
| `:phone` | `+15551234567` | Phone numbers |
|
|
179
|
+
| `:ssn` | `123-45-6789` | Social Security Numbers |
|
|
180
|
+
| `:name` | `Anonymous User abc123` | Full names |
|
|
181
|
+
| `:first_name` | `John`, `Jane`, `Alex` | First names |
|
|
182
|
+
| `:last_name` | `Smith`, `Johnson`, `Williams` | Last names |
|
|
183
|
+
| `:address` | `1234 Anonymous St, City, ST 12345` | Full addresses |
|
|
184
|
+
| `:text` | `Anonymized text a1b2c3d4` | Generic text |
|
|
188
185
|
|
|
189
186
|
## Custom Anonymization Types 🎨
|
|
190
187
|
|
|
@@ -212,7 +209,7 @@ end
|
|
|
212
209
|
Use them in your config:
|
|
213
210
|
|
|
214
211
|
```yaml
|
|
215
|
-
# config/
|
|
212
|
+
# config/anonymized_columns.yml
|
|
216
213
|
User:
|
|
217
214
|
credit_card_number: credit_card # Custom type!
|
|
218
215
|
employee_number: employee_id # Custom type!
|
|
@@ -226,19 +223,19 @@ User:
|
|
|
226
223
|
|
|
227
224
|
```ruby
|
|
228
225
|
user = User.find(123)
|
|
229
|
-
ColumnAnonymizer::Anonymizer.
|
|
226
|
+
ColumnAnonymizer::Anonymizer.anonymize_instance!(user)
|
|
230
227
|
user.reload
|
|
231
228
|
|
|
232
|
-
puts user.email
|
|
233
|
-
puts user.phone
|
|
234
|
-
puts user.ssn
|
|
229
|
+
puts user.email # => "user_abc12345@example.com"
|
|
230
|
+
puts user.phone # => "+15551234567"
|
|
231
|
+
puts user.ssn # => "123-45-6789"
|
|
235
232
|
```
|
|
236
233
|
|
|
237
234
|
### Anonymize All Records
|
|
238
235
|
|
|
239
236
|
```ruby
|
|
240
237
|
User.find_each do |user|
|
|
241
|
-
ColumnAnonymizer::Anonymizer.
|
|
238
|
+
ColumnAnonymizer::Anonymizer.anonymize_instance!(user)
|
|
242
239
|
end
|
|
243
240
|
```
|
|
244
241
|
|
|
@@ -247,7 +244,7 @@ end
|
|
|
247
244
|
```ruby
|
|
248
245
|
# Anonymize users from a specific date range
|
|
249
246
|
User.where("created_at < ?", 1.year.ago).find_each do |user|
|
|
250
|
-
ColumnAnonymizer::Anonymizer.
|
|
247
|
+
ColumnAnonymizer::Anonymizer.anonymize_instance!(user)
|
|
251
248
|
end
|
|
252
249
|
```
|
|
253
250
|
|
|
@@ -273,6 +270,7 @@ rake column_anonymizer:stats
|
|
|
273
270
|
```
|
|
274
271
|
|
|
275
272
|
**Example Output:**
|
|
273
|
+
|
|
276
274
|
```
|
|
277
275
|
📋 Processing User...
|
|
278
276
|
Columns: email, phone, ssn
|
|
@@ -296,7 +294,7 @@ namespace :data do
|
|
|
296
294
|
task anonymize_old_users: :environment do
|
|
297
295
|
count = 0
|
|
298
296
|
User.where("created_at < ?", 2.years.ago).find_each do |user|
|
|
299
|
-
ColumnAnonymizer::Anonymizer.
|
|
297
|
+
ColumnAnonymizer::Anonymizer.anonymize_instance!(user)
|
|
300
298
|
count += 1
|
|
301
299
|
end
|
|
302
300
|
puts "Anonymized #{count} users"
|
|
@@ -334,16 +332,17 @@ ColumnAnonymizer::SchemaLoader.load_schema
|
|
|
334
332
|
|
|
335
333
|
## Generator Commands
|
|
336
334
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
|
340
|
-
| `rails generate column_anonymizer:install
|
|
341
|
-
| `rails generate column_anonymizer:scan` |
|
|
342
|
-
| `rails generate column_anonymizer:
|
|
335
|
+
|
|
336
|
+
| Command | Description |
|
|
337
|
+
| ------------------------------------------------- | ---------------------------------------- |
|
|
338
|
+
| `rails generate column_anonymizer:install` | Create config file |
|
|
339
|
+
| `rails generate column_anonymizer:install --scan` | Install and scan models |
|
|
340
|
+
| `rails generate column_anonymizer:scan` | Scan models and update config |
|
|
341
|
+
| `rails generate column_anonymizer:initializer` | Create initializer for custom generators |
|
|
343
342
|
|
|
344
343
|
## Configuration File
|
|
345
344
|
|
|
346
|
-
The gem expects a YAML file at `config/
|
|
345
|
+
The gem expects a YAML file at `config/anonymized_columns.yml`:
|
|
347
346
|
|
|
348
347
|
```yaml
|
|
349
348
|
# Format: ModelName -> column_name -> anonymization_type
|
|
@@ -359,12 +358,12 @@ Patient:
|
|
|
359
358
|
|
|
360
359
|
## Why YAML Configuration?
|
|
361
360
|
|
|
362
|
-
✅ **Centralized**: All column types in one file
|
|
363
|
-
✅ **Version Controlled**: Track changes in git
|
|
364
|
-
✅ **No Code Changes**: Use standard Rails `encrypts`
|
|
365
|
-
✅ **Easy Updates**: Modify types without touching models
|
|
366
|
-
✅ **Automatic Discovery**: Scan feature populates config
|
|
367
|
-
✅ **Team Friendly**: Clear overview of all encrypted data
|
|
361
|
+
✅ **Centralized**: All column types in one file
|
|
362
|
+
✅ **Version Controlled**: Track changes in git
|
|
363
|
+
✅ **No Code Changes**: Use standard Rails `encrypts`
|
|
364
|
+
✅ **Easy Updates**: Modify types without touching models
|
|
365
|
+
✅ **Automatic Discovery**: Scan feature populates config
|
|
366
|
+
✅ **Team Friendly**: Clear overview of all encrypted data
|
|
368
367
|
|
|
369
368
|
## Requirements
|
|
370
369
|
|
data/data.tar.gz
ADDED
|
Binary file
|
|
@@ -80,7 +80,7 @@ module ColumnAnonymizer
|
|
|
80
80
|
@custom_generators = {}
|
|
81
81
|
end
|
|
82
82
|
|
|
83
|
-
def
|
|
83
|
+
def anonymize_instance(model_instance)
|
|
84
84
|
klass = model_instance.class
|
|
85
85
|
return model_instance unless klass.respond_to?(:encrypted_columns_metadata)
|
|
86
86
|
|
|
@@ -94,8 +94,8 @@ module ColumnAnonymizer
|
|
|
94
94
|
model_instance
|
|
95
95
|
end
|
|
96
96
|
|
|
97
|
-
def
|
|
98
|
-
|
|
97
|
+
def anonymize_instance!(model_instance)
|
|
98
|
+
anonymize_instance(model_instance)
|
|
99
99
|
model_instance.save!
|
|
100
100
|
end
|
|
101
101
|
end
|
|
@@ -30,9 +30,9 @@ module ColumnAnonymizer
|
|
|
30
30
|
|
|
31
31
|
def schema_file_path
|
|
32
32
|
if defined?(Rails)
|
|
33
|
-
Rails.root.join('config', '
|
|
33
|
+
Rails.root.join('config', 'anonymized_columns.yml').to_s
|
|
34
34
|
else
|
|
35
|
-
File.join(Dir.pwd, 'config', '
|
|
35
|
+
File.join(Dir.pwd, 'config', 'anonymized_columns.yml')
|
|
36
36
|
end
|
|
37
37
|
end
|
|
38
38
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# Column Anonymizer - Custom Generator Configuration
|
|
4
4
|
#
|
|
5
|
-
# Register custom anonymization generators for use in your
|
|
5
|
+
# Register custom anonymization generators for use in your anonymized_columns.yml
|
|
6
6
|
#
|
|
7
7
|
# Example:
|
|
8
8
|
# User:
|
|
@@ -32,6 +32,16 @@ end
|
|
|
32
32
|
# "#{letters}-#{numbers}"
|
|
33
33
|
# end
|
|
34
34
|
|
|
35
|
+
# Generator for JSONB column
|
|
36
|
+
# ColumnAnonymizer::Anonymizer.register(:user_preferences_jsonb) do
|
|
37
|
+
# {
|
|
38
|
+
# "theme" => ["light", "dark", "auto"].sample,
|
|
39
|
+
# "notifications" => [true, false].sample,
|
|
40
|
+
# "email_frequency" => ["daily", "weekly", "monthly", "never"].sample,
|
|
41
|
+
# "language" => ["en", "es", "fr", "de", "ja"].sample
|
|
42
|
+
# }
|
|
43
|
+
# end
|
|
44
|
+
|
|
35
45
|
# Generator that uses Rails helpers or models
|
|
36
46
|
# ColumnAnonymizer::Anonymizer.register(:department_name) do
|
|
37
47
|
# Department.active.pluck(:name).sample || "General"
|
|
@@ -69,7 +79,7 @@ end
|
|
|
69
79
|
# :text - Generates lorem ipsum text
|
|
70
80
|
# ============================================================================
|
|
71
81
|
|
|
72
|
-
# To use your custom types, add them to config/
|
|
82
|
+
# To use your custom types, add them to config/anonymized_columns.yml:
|
|
73
83
|
#
|
|
74
84
|
# User:
|
|
75
85
|
# credit_card_number: credit_card
|
|
@@ -7,13 +7,13 @@ module ColumnAnonymizer
|
|
|
7
7
|
class InstallGenerator < Rails::Generators::Base
|
|
8
8
|
source_root File.expand_path('templates', __dir__)
|
|
9
9
|
|
|
10
|
-
desc "Creates a ColumnAnonymizer configuration file at config/
|
|
10
|
+
desc "Creates a ColumnAnonymizer configuration file at config/anonymized_columns.yml"
|
|
11
11
|
|
|
12
12
|
class_option :scan, type: :boolean, default: false,
|
|
13
13
|
desc: "Automatically scan models for encrypted attributes and populate the config"
|
|
14
14
|
|
|
15
15
|
def create_config_file
|
|
16
|
-
template '
|
|
16
|
+
template 'anonymized_columns.yml', 'config/anonymized_columns.yml'
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def scan_models_if_requested
|
|
@@ -6,10 +6,10 @@ require 'yaml'
|
|
|
6
6
|
module ColumnAnonymizer
|
|
7
7
|
module Generators
|
|
8
8
|
class ScanGenerator < Rails::Generators::Base
|
|
9
|
-
desc "Scans Rails models for encrypted attributes and updates config/
|
|
9
|
+
desc "Scans Rails models for encrypted attributes and updates config/anonymized_columns.yml"
|
|
10
10
|
|
|
11
11
|
def scan_and_update_config
|
|
12
|
-
config_path = Rails.root.join('config', '
|
|
12
|
+
config_path = Rails.root.join('config', 'anonymized_columns.yml')
|
|
13
13
|
|
|
14
14
|
# Load existing config or create empty hash
|
|
15
15
|
existing_config = if File.exist?(config_path)
|
|
@@ -40,7 +40,7 @@ module ColumnAnonymizer
|
|
|
40
40
|
append_to_config(config_path, additions)
|
|
41
41
|
|
|
42
42
|
say "✅ Scanned #{discovered_encryptions.keys.size} model(s) with encrypted attributes", :green
|
|
43
|
-
say "📝 Appended #{count_additions(additions)} new column(s) to config/
|
|
43
|
+
say "📝 Appended #{count_additions(additions)} new column(s) to config/anonymized_columns.yml", :green
|
|
44
44
|
|
|
45
45
|
# Show what was found
|
|
46
46
|
discovered_encryptions.each do |model_name, columns|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
namespace :column_anonymizer do
|
|
4
|
-
desc "Anonymize all encrypted columns defined in config/
|
|
4
|
+
desc "Anonymize all encrypted columns defined in config/anonymized_columns.yml"
|
|
5
5
|
task anonymize_all: :environment do
|
|
6
6
|
require 'column_anonymizer'
|
|
7
7
|
|
|
@@ -9,7 +9,7 @@ namespace :column_anonymizer do
|
|
|
9
9
|
schema = ColumnAnonymizer::SchemaLoader.load_schema
|
|
10
10
|
|
|
11
11
|
if schema.empty?
|
|
12
|
-
puts "❌ No models found in config/
|
|
12
|
+
puts "❌ No models found in config/anonymized_columns.yml"
|
|
13
13
|
exit 1
|
|
14
14
|
end
|
|
15
15
|
|
|
@@ -39,21 +39,17 @@ namespace :column_anonymizer do
|
|
|
39
39
|
# Anonymize each record with progress
|
|
40
40
|
anonymized_count = 0
|
|
41
41
|
error_count = 0
|
|
42
|
+
index = 0
|
|
42
43
|
|
|
43
|
-
model_class.
|
|
44
|
-
|
|
45
|
-
ColumnAnonymizer::Anonymizer.
|
|
46
|
-
anonymized_count += 1
|
|
47
|
-
|
|
48
|
-
# Show progress every 100 records
|
|
49
|
-
if (index + 1) % 100 == 0
|
|
50
|
-
print "\r Progress: #{index + 1}/#{record_count}"
|
|
51
|
-
$stdout.flush
|
|
52
|
-
end
|
|
53
|
-
rescue => e
|
|
54
|
-
error_count += 1
|
|
55
|
-
puts "\n ❌ Error anonymizing #{model_name} ID #{record.id}: #{e.message}"
|
|
44
|
+
model_class.find_in_batches(batch_size: 500) do |records|
|
|
45
|
+
anonymized_attributes = records.map do |record|
|
|
46
|
+
ColumnAnonymizer::Anonymizer.anonymize_instance(record).attributes
|
|
56
47
|
end
|
|
48
|
+
anonymized_count += records.size
|
|
49
|
+
print "\r Progress: #{anonymized_count}/#{record_count}"
|
|
50
|
+
# $stdout.flush
|
|
51
|
+
|
|
52
|
+
model_class.upsert_all(anonymized_attributes, record_timestamps: false, unique_by: :id)
|
|
57
53
|
end
|
|
58
54
|
|
|
59
55
|
# Clear progress line and show final result
|
|
@@ -81,7 +77,7 @@ namespace :column_anonymizer do
|
|
|
81
77
|
end
|
|
82
78
|
|
|
83
79
|
desc "Anonymize a specific model"
|
|
84
|
-
task :
|
|
80
|
+
task :anonymize_instance, [:model_name] => :environment do |t, args|
|
|
85
81
|
require 'column_anonymizer'
|
|
86
82
|
|
|
87
83
|
unless args[:model_name]
|
|
@@ -93,7 +89,7 @@ namespace :column_anonymizer do
|
|
|
93
89
|
schema = ColumnAnonymizer::SchemaLoader.load_schema
|
|
94
90
|
|
|
95
91
|
unless schema.key?(model_name)
|
|
96
|
-
puts "❌ Model '#{model_name}' not found in config/
|
|
92
|
+
puts "❌ Model '#{model_name}' not found in config/anonymized_columns.yml"
|
|
97
93
|
puts "Available models: #{schema.keys.join(', ')}"
|
|
98
94
|
exit 1
|
|
99
95
|
end
|
|
@@ -118,7 +114,7 @@ namespace :column_anonymizer do
|
|
|
118
114
|
|
|
119
115
|
model_class.find_each.with_index do |record, index|
|
|
120
116
|
begin
|
|
121
|
-
ColumnAnonymizer::Anonymizer.
|
|
117
|
+
ColumnAnonymizer::Anonymizer.anonymize_instance!(record)
|
|
122
118
|
anonymized_count += 1
|
|
123
119
|
|
|
124
120
|
if (index + 1) % 100 == 0
|
|
@@ -151,7 +147,7 @@ namespace :column_anonymizer do
|
|
|
151
147
|
schema = ColumnAnonymizer::SchemaLoader.load_schema
|
|
152
148
|
|
|
153
149
|
if schema.empty?
|
|
154
|
-
puts "❌ No models found in config/
|
|
150
|
+
puts "❌ No models found in config/anonymized_columns.yml"
|
|
155
151
|
exit 1
|
|
156
152
|
end
|
|
157
153
|
|
|
@@ -206,7 +202,7 @@ namespace :column_anonymizer do
|
|
|
206
202
|
schema = ColumnAnonymizer::SchemaLoader.load_schema
|
|
207
203
|
|
|
208
204
|
unless schema.key?(model_name)
|
|
209
|
-
puts "❌ Model '#{model_name}' not found in config/
|
|
205
|
+
puts "❌ Model '#{model_name}' not found in config/anonymized_columns.yml"
|
|
210
206
|
exit 1
|
|
211
207
|
end
|
|
212
208
|
|
|
@@ -239,7 +235,7 @@ namespace :column_anonymizer do
|
|
|
239
235
|
|
|
240
236
|
records.find_each.with_index do |record, index|
|
|
241
237
|
begin
|
|
242
|
-
ColumnAnonymizer::Anonymizer.
|
|
238
|
+
ColumnAnonymizer::Anonymizer.anonymize_instance!(record)
|
|
243
239
|
anonymized_count += 1
|
|
244
240
|
|
|
245
241
|
if (index + 1) % 100 == 0
|
|
@@ -273,7 +269,7 @@ namespace :column_anonymizer do
|
|
|
273
269
|
schema = ColumnAnonymizer::SchemaLoader.load_schema
|
|
274
270
|
|
|
275
271
|
if schema.empty?
|
|
276
|
-
puts "❌ No models found in config/
|
|
272
|
+
puts "❌ No models found in config/anonymized_columns.yml"
|
|
277
273
|
exit 1
|
|
278
274
|
end
|
|
279
275
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: column_anonymizer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Hunter-Kendall
|
|
@@ -50,22 +50,10 @@ files:
|
|
|
50
50
|
- ".rspec"
|
|
51
51
|
- ".rspec_status"
|
|
52
52
|
- CHANGELOG.md
|
|
53
|
-
-
|
|
54
|
-
- CUSTOM_GENERATORS_GUIDE.md
|
|
55
|
-
- CUSTOM_GENERATORS_IMPLEMENTATION.md
|
|
56
|
-
- CUSTOM_GENERATORS_QUICK_REF.md
|
|
57
|
-
- FEATURE_COMPLETE.md
|
|
58
|
-
- GEMSPEC_FIX.md
|
|
59
|
-
- IMPLEMENTATION_SUMMARY.md
|
|
60
|
-
- QUICK_REFERENCE.md
|
|
61
|
-
- RAKE_TASKS_GUIDE.md
|
|
62
|
-
- RAKE_TASKS_IMPLEMENTATION.md
|
|
63
|
-
- RAKE_TASKS_QUICK_REF.md
|
|
53
|
+
- LICENSE
|
|
64
54
|
- README.md
|
|
65
55
|
- Rakefile
|
|
66
|
-
-
|
|
67
|
-
- WORKFLOW_GUIDE.md
|
|
68
|
-
- YAML_MIGRATION_GUIDE.md
|
|
56
|
+
- data.tar.gz
|
|
69
57
|
- lib/column_anonymizer.rb
|
|
70
58
|
- lib/column_anonymizer/anonymizer.rb
|
|
71
59
|
- lib/column_anonymizer/encryptable.rb
|
|
@@ -76,11 +64,12 @@ files:
|
|
|
76
64
|
- lib/generators/column_anonymizer/initializer/templates/column_anonymizer.rb
|
|
77
65
|
- lib/generators/column_anonymizer/install/README
|
|
78
66
|
- lib/generators/column_anonymizer/install/install_generator.rb
|
|
79
|
-
- lib/generators/column_anonymizer/install/templates/
|
|
67
|
+
- lib/generators/column_anonymizer/install/templates/anonymized_columns.yml
|
|
80
68
|
- lib/generators/column_anonymizer/scan/scan_generator.rb
|
|
81
69
|
- lib/tasks/column_anonymizer.rake
|
|
82
70
|
homepage: https://github.com/hunter-kendall/column_anonymizer
|
|
83
|
-
licenses:
|
|
71
|
+
licenses:
|
|
72
|
+
- MIT
|
|
84
73
|
metadata:
|
|
85
74
|
homepage_uri: https://github.com/hunter-kendall/column_anonymizer
|
|
86
75
|
source_code_uri: https://github.com/hunter-kendall/column_anonymizer
|