gdpr_admin 1.3.0 → 1.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9b5cc14d1e0f88e99bec3ccd100795cc1985ef86fa559fbdd2639bdd5bef1ee4
4
- data.tar.gz: 5c07836dec53a6265e3fcd6516f910a22b6834234bea5f39890030ba394d0e5c
3
+ metadata.gz: 9b1d58ff60fa19dc3b0a1fb067ae2ed0dfc96e8798257989534a39e8600ef878
4
+ data.tar.gz: b199dc1a90a1fab64a6b98bcde51dc656a8943f12381dcdbc275e51147997c92
5
5
  SHA512:
6
- metadata.gz: f4552232540bf1153c32e15ccc1ec0ed5f5a399649bd5618ded36476881124d2496a1f345deec8f5baf98ecba1ff4e0161743ca905abae45761024d9c68432e0
7
- data.tar.gz: 8169ff0b5040484ceac0084601246d19d875e222509ec2f1a2dab055822d79db13b999c6a96468167cf39adfe5cc26b0aff60b9c046bbcc31422177e2ca66684
6
+ metadata.gz: b7813fc861f53e6d280369e403e9ece16484dfc433e2005b6c6eac739f91694d06169fcf0b60a3b1d1e32f65dcc45a44a8dee5446e89a35b90391070a42c0c96
7
+ data.tar.gz: 02a363b0a84f217aceeb3e19e2d0f53b09d7f5030e3dbf16abae8c92a8dc52cca9138c3fca55b6ce1014f639a915914e910c45e7538d5f24ecf79c005a3abb14
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
- GdprAdmin.config.tenant_adapter.with_tenant(tenant) { process_policies }
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
- policy = policy_class.new(self)
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
- raise SkipDataPolicyError
32
+ skip_data_policy!
14
33
  end
15
34
 
16
35
  def export(_record)
@@ -21,8 +40,49 @@ 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
+ scope.find_each do |record|
47
+ process_record(record)
48
+ end
49
+ rescue SkipDataPolicyError
50
+ nil
51
+ end
52
+ end
53
+
24
54
  protected
25
55
 
26
56
  attr_reader :request
57
+
58
+ def process_record(record)
59
+ run_record_preprocessors(record)
60
+ export(record) if request.export?
61
+ erase(record) if request.erase?
62
+ rescue SkipRecordError
63
+ nil
64
+ end
65
+
66
+ def run_preprocessors
67
+ before_process_hooks = self.class.before_process_hooks || []
68
+ before_process_hooks.each do |hook|
69
+ call_hook(hook)
70
+ end
71
+ end
72
+
73
+ def run_record_preprocessors(record)
74
+ before_process_record_hooks = self.class.before_process_record_hooks || []
75
+ before_process_record_hooks.each do |hook|
76
+ call_hook(hook, record)
77
+ end
78
+ end
79
+
80
+ def call_hook(hook, value = nil)
81
+ hook = method(hook) unless hook.respond_to?(:call)
82
+
83
+ arity = hook.arity
84
+ args = [value].take(arity).reverse
85
+ instance_exec(*args, &hook)
86
+ end
27
87
  end
28
88
  end
@@ -0,0 +1,15 @@
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
+ end
14
+ end
15
+ 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
- return if item_fields.nil?
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,6 +18,15 @@ 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
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GdprAdmin
4
+ class SkipRecordError < StandardError; end
5
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  # :nocov:
4
4
  module GdprAdmin
5
- VERSION = '1.3.0'
5
+ VERSION = '1.4.0'
6
6
  end
7
7
  # :nocov:
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.3.0
4
+ version: 1.4.0
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-01 00:00:00.000000000 Z
11
+ date: 2023-03-30 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