gdpr_admin 1.3.0 → 1.4.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 +4 -4
- data/README.md +40 -0
- data/app/models/gdpr_admin/request.rb +2 -8
- data/lib/gdpr_admin/application_data_policy.rb +69 -1
- data/lib/gdpr_admin/helpers/data_policy_helper.rb +25 -0
- data/lib/gdpr_admin/paper_trail/version_data_policy.rb +11 -14
- data/lib/gdpr_admin/skip_record_error.rb +5 -0
- data/lib/gdpr_admin/version.rb +1 -1
- data/lib/gdpr_admin.rb +2 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 99489f549c8f701322c68c19a73dad4796af585f7b981ac8680590b14e2b299e
|
4
|
+
data.tar.gz: c2918882ca853ded91dc6ecd8aa52ae95dd6c2a9cac99d6c829917693d7e96e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 29c763ef8b44f45c56c63c4da8fc8b275dd2a2ce3f6bdb1c8808015543343bcafc1599450d74c2d54be74a8c2020c24649fd31f94d2f0188e38fcc19bc8b6637
|
7
|
+
data.tar.gz: b68927faf70d507c7992f7a64fc2a7eab37034533ebc492d93490179e6e0f276ece51ef2855b06ba938ef03fe974230a2770145a7a263a0fcf2baf181c588b19
|
data/README.md
CHANGED
@@ -35,6 +35,11 @@ Or install it yourself as:
|
|
35
35
|
$ gem install gdpr_admin
|
36
36
|
```
|
37
37
|
|
38
|
+
Then install the migrations:
|
39
|
+
```bash
|
40
|
+
$ rails gdpr_admin:install:migrations
|
41
|
+
```
|
42
|
+
|
38
43
|
## Usage
|
39
44
|
|
40
45
|
Create your data policies file within `app/gdpr` _(configurable)_ and inherit from `GdprAdmin::ApplicationDataPolicy`.
|
@@ -138,6 +143,41 @@ same anonymized value. _(note: different values may also yield the same value)_
|
|
138
143
|
|
139
144
|
To use the built-in anonymizer functions, you need to install the gem `faker`.
|
140
145
|
|
146
|
+
## Data Policy Hooks
|
147
|
+
For advanced use cases, you may install hooks that are run at different stages of the data policy process.
|
148
|
+
|
149
|
+
### `before_process`
|
150
|
+
Will be run before the policy is executed. Calling `skip_data_policy!` will raise `GdprAdmin::SkipDataPolicyError` and
|
151
|
+
stop the execution of the data policy.
|
152
|
+
|
153
|
+
```ruby
|
154
|
+
class ContactDataPolicy < GdprAdmin::ApplicationDataPolicy
|
155
|
+
before_process :skip_internal_contacts!
|
156
|
+
|
157
|
+
private
|
158
|
+
|
159
|
+
def skip_internal_contacts!
|
160
|
+
skip_data_policy! if contact.email =~ /.*@company\.com/
|
161
|
+
end
|
162
|
+
end
|
163
|
+
```
|
164
|
+
|
165
|
+
### `before_process_record`
|
166
|
+
Called before processing a record (either erasing or exporting). Calling `skip_record!` will raise `GdprAdmin::SkipRecordError` and
|
167
|
+
skip processing that particular record.
|
168
|
+
|
169
|
+
```ruby
|
170
|
+
class UserDataPolicy < GdprAdmin::ApplicationDataPolicy
|
171
|
+
before_process :skip_super_admins!
|
172
|
+
|
173
|
+
private
|
174
|
+
|
175
|
+
def skip_super_admins!(user)
|
176
|
+
skip_record! if user.role == 'super_admin'
|
177
|
+
end
|
178
|
+
end
|
179
|
+
```
|
180
|
+
|
141
181
|
## GDPR Request
|
142
182
|
A GDPR Request (`GdprAdmin::Request`) represents a request to remove a subject's data, tenant's data, or export subject data.
|
143
183
|
|
@@ -35,7 +35,7 @@ module GdprAdmin
|
|
35
35
|
GdprAdmin.load_data_policies
|
36
36
|
with_lock { processing! }
|
37
37
|
with_lock do
|
38
|
-
|
38
|
+
process_policies
|
39
39
|
completed!
|
40
40
|
end
|
41
41
|
rescue StandardError
|
@@ -63,13 +63,7 @@ module GdprAdmin
|
|
63
63
|
|
64
64
|
def process_policies
|
65
65
|
ApplicationDataPolicy.descendants.each do |policy_class|
|
66
|
-
|
67
|
-
policy.scope.find_each do |record|
|
68
|
-
policy.export(record) if export?
|
69
|
-
policy.erase(record) if erase?
|
70
|
-
end
|
71
|
-
rescue SkipDataPolicyError
|
72
|
-
next
|
66
|
+
policy_class.process(self)
|
73
67
|
end
|
74
68
|
end
|
75
69
|
|
@@ -2,15 +2,34 @@
|
|
2
2
|
|
3
3
|
module GdprAdmin
|
4
4
|
class ApplicationDataPolicy
|
5
|
+
include Helpers::DataPolicyHelper
|
5
6
|
include Helpers::EraseHelper
|
6
7
|
include Helpers::ScopeHelper
|
7
8
|
|
9
|
+
class << self
|
10
|
+
attr_reader :before_process_hooks, :before_process_record_hooks
|
11
|
+
|
12
|
+
def before_process(method)
|
13
|
+
@before_process_hooks ||= []
|
14
|
+
@before_process_hooks << method
|
15
|
+
end
|
16
|
+
|
17
|
+
def before_process_record(method)
|
18
|
+
@before_process_record_hooks ||= []
|
19
|
+
@before_process_record_hooks << method
|
20
|
+
end
|
21
|
+
|
22
|
+
def process(request)
|
23
|
+
new(request).process
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
8
27
|
def initialize(request)
|
9
28
|
@request = request
|
10
29
|
end
|
11
30
|
|
12
31
|
def scope
|
13
|
-
|
32
|
+
skip_data_policy!
|
14
33
|
end
|
15
34
|
|
16
35
|
def export(_record)
|
@@ -21,8 +40,57 @@ module GdprAdmin
|
|
21
40
|
raise NotImplementedError
|
22
41
|
end
|
23
42
|
|
43
|
+
def process
|
44
|
+
GdprAdmin.config.tenant_adapter.with_tenant(request.tenant) do
|
45
|
+
run_preprocessors
|
46
|
+
process_scope(scope)
|
47
|
+
rescue SkipDataPolicyError
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def process_scope(scope)
|
53
|
+
scope.find_each do |record|
|
54
|
+
process_record(record)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
24
58
|
protected
|
25
59
|
|
26
60
|
attr_reader :request
|
61
|
+
|
62
|
+
def process_record(record)
|
63
|
+
run_record_preprocessors(record)
|
64
|
+
export(record) if request.export?
|
65
|
+
erase(record) if request.erase?
|
66
|
+
rescue SkipRecordError
|
67
|
+
nil
|
68
|
+
end
|
69
|
+
|
70
|
+
def run_preprocessors
|
71
|
+
before_process_hooks = self.class.before_process_hooks || []
|
72
|
+
before_process_hooks.each do |hook|
|
73
|
+
call_hook(hook)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def run_record_preprocessors(record)
|
78
|
+
before_process_record_hooks = self.class.before_process_record_hooks || []
|
79
|
+
before_process_record_hooks.each do |hook|
|
80
|
+
call_hook(hook, record)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def call_hook(hook, value = nil)
|
85
|
+
hook = method(hook) unless hook.respond_to?(:call)
|
86
|
+
|
87
|
+
arity = arity_of(hook)
|
88
|
+
args = [value].take(arity).reverse
|
89
|
+
instance_exec(*args, &hook)
|
90
|
+
end
|
91
|
+
|
92
|
+
def arity_of(method_or_proc)
|
93
|
+
defined?(T::Utils.arity) ? T::Utils.arity(method_or_proc) : method_or_proc.arity
|
94
|
+
end
|
27
95
|
end
|
28
96
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GdprAdmin
|
4
|
+
module Helpers
|
5
|
+
module DataPolicyHelper
|
6
|
+
def skip_data_policy!
|
7
|
+
raise SkipDataPolicyError
|
8
|
+
end
|
9
|
+
|
10
|
+
def skip_record!
|
11
|
+
raise SkipRecordError
|
12
|
+
end
|
13
|
+
|
14
|
+
def model_data_policy_class(model)
|
15
|
+
model = model.constantize if model.is_a?(String)
|
16
|
+
return model.data_policy_class if model.respond_to?(:data_policy_class)
|
17
|
+
|
18
|
+
prefix = model.data_policy_prefix if model.respond_to?(:data_policy_prefix)
|
19
|
+
"#{prefix}#{model}DataPolicy".constantize
|
20
|
+
rescue NameError
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -9,13 +9,7 @@ module GdprAdmin
|
|
9
9
|
|
10
10
|
def erase(version, item_fields = nil)
|
11
11
|
item_fields ||= infer_item_fields(version)
|
12
|
-
|
13
|
-
|
14
|
-
base_changes = {
|
15
|
-
object: anonymize_version_object(version, item_fields),
|
16
|
-
object_changes: anonymize_version_object_changes(version, item_fields),
|
17
|
-
}.compact
|
18
|
-
erase_fields(version, fields, base_changes)
|
12
|
+
erase_fields(version, fields, base_changes(version, item_fields))
|
19
13
|
end
|
20
14
|
|
21
15
|
def fields
|
@@ -24,18 +18,21 @@ module GdprAdmin
|
|
24
18
|
|
25
19
|
private
|
26
20
|
|
21
|
+
def base_changes(version, item_fields)
|
22
|
+
return {} if item_fields.blank?
|
23
|
+
|
24
|
+
{
|
25
|
+
object: anonymize_version_object(version, item_fields),
|
26
|
+
object_changes: anonymize_version_object_changes(version, item_fields),
|
27
|
+
}.compact
|
28
|
+
end
|
29
|
+
|
27
30
|
def infer_item_fields(version)
|
28
31
|
infer_data_policy_class(version)&.new(request)&.try(:fields)
|
29
32
|
end
|
30
33
|
|
31
34
|
def infer_data_policy_class(version)
|
32
|
-
|
33
|
-
return model.data_policy_class if model.respond_to?(:data_policy_class)
|
34
|
-
|
35
|
-
prefix = model.data_policy_prefix if model.respond_to?(:data_policy_prefix)
|
36
|
-
"#{prefix}#{version.item_type}DataPolicy".constantize
|
37
|
-
rescue NameError
|
38
|
-
nil
|
35
|
+
model_data_policy_class(version.item_type)
|
39
36
|
end
|
40
37
|
end
|
41
38
|
end
|
data/lib/gdpr_admin/version.rb
CHANGED
data/lib/gdpr_admin.rb
CHANGED
@@ -6,6 +6,8 @@ require 'gdpr_admin/configuration'
|
|
6
6
|
require 'gdpr_admin/error'
|
7
7
|
require 'gdpr_admin/invalid_status_error'
|
8
8
|
require 'gdpr_admin/skip_data_policy_error'
|
9
|
+
require 'gdpr_admin/skip_record_error'
|
10
|
+
require 'gdpr_admin/helpers/data_policy_helper'
|
9
11
|
require 'gdpr_admin/helpers/erase_helper'
|
10
12
|
require 'gdpr_admin/helpers/scope_helper'
|
11
13
|
require 'gdpr_admin/application_data_policy'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gdpr_admin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Colex
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-03
|
11
|
+
date: 2023-04-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -165,6 +165,7 @@ files:
|
|
165
165
|
- lib/gdpr_admin/configuration.rb
|
166
166
|
- lib/gdpr_admin/engine.rb
|
167
167
|
- lib/gdpr_admin/error.rb
|
168
|
+
- lib/gdpr_admin/helpers/data_policy_helper.rb
|
168
169
|
- lib/gdpr_admin/helpers/erase_helper.rb
|
169
170
|
- lib/gdpr_admin/helpers/field_anonymizer_helper.rb
|
170
171
|
- lib/gdpr_admin/helpers/paper_trail_helper.rb
|
@@ -172,6 +173,7 @@ files:
|
|
172
173
|
- lib/gdpr_admin/invalid_status_error.rb
|
173
174
|
- lib/gdpr_admin/paper_trail/version_data_policy.rb
|
174
175
|
- lib/gdpr_admin/skip_data_policy_error.rb
|
176
|
+
- lib/gdpr_admin/skip_record_error.rb
|
175
177
|
- lib/gdpr_admin/tenant_adapters/acts_as_tenant_adapter.rb
|
176
178
|
- lib/gdpr_admin/version.rb
|
177
179
|
- lib/tasks/gdpr_admin_tasks.rake
|