gdpr_admin 1.1.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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +60 -0
- data/Rakefile +10 -0
- data/app/jobs/gdpr_admin/application_job.rb +6 -0
- data/app/jobs/gdpr_admin/request_processor_job.rb +9 -0
- data/app/models/gdpr_admin/application_record.rb +7 -0
- data/app/models/gdpr_admin/request.rb +67 -0
- data/config/routes.rb +5 -0
- data/db/migrate/20230212185817_create_gdpr_admin_requests.rb +15 -0
- data/lib/gdpr_admin/anonymizers/contact_anonymizer.rb +11 -0
- data/lib/gdpr_admin/anonymizers/internet_anonymizer.rb +15 -0
- data/lib/gdpr_admin/anonymizers/name_anonymizer.rb +19 -0
- data/lib/gdpr_admin/application_data_policy.rb +27 -0
- data/lib/gdpr_admin/configuration.rb +21 -0
- data/lib/gdpr_admin/engine.rb +7 -0
- data/lib/gdpr_admin/helpers/erase_helper.rb +83 -0
- data/lib/gdpr_admin/skip_data_policy_error.rb +5 -0
- data/lib/gdpr_admin/tenant_adapters/acts_as_tenant_adapter.rb +11 -0
- data/lib/gdpr_admin/version.rb +5 -0
- data/lib/gdpr_admin.rb +31 -0
- data/lib/tasks/gdpr_admin_tasks.rake +5 -0
- metadata +180 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 805cbc1723602328c1f50a94bc0ce0ec9bf3e06aa68bfc8ea4ed4b209cd16bca
|
4
|
+
data.tar.gz: b14d9f47e9f06d9ef5480dd42ab9fa3c287e9c2c1a1241c997ba75f6a5e18e17
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d3ae19c166459e40ea1d7428883935de10eaae4450d36de7a55e5ad8fd357d0cd8af736423d0823bc08e89645a67c370b660908fd93bb5d29c93bf6a0140ed8e
|
7
|
+
data.tar.gz: 95e6688226094762e6a25915075d2e26addf4d8f82ec5d799c89d097bdc752c1df1944ea4971eca2dc21f856d527e31f3d308e3b5cafd361e13a5b4d95af7373
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2023 Colex
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# GDPR Admin
|
2
|
+
Rails engine for processing GDPR processes. GDPR Admin offers a simple interface for defining strategies for automating the process of data access and data removal as required by data privacy regulations like GDPR.
|
3
|
+
|
4
|
+
## Installation
|
5
|
+
Add this line to your application's Gemfile:
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
gem "gdpr_admin"
|
9
|
+
```
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
```bash
|
13
|
+
$ bundle
|
14
|
+
```
|
15
|
+
|
16
|
+
Or install it yourself as:
|
17
|
+
```bash
|
18
|
+
$ gem install gdpr_admin
|
19
|
+
```
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
Create your data policies file within `app/gdpr` _(configurable)_ and inherit from `GdprAdmin::ApplicationDataPolicy`.
|
24
|
+
Implement the methods `#scope`, `#export` and `#erase` for the new data policy. Within the data policy, you will be
|
25
|
+
able to access the `GdprAdmin::Request` object in any method by calling the method `request` - you can, therefore, have
|
26
|
+
different scopes and different removal behaviors depending on the request.
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
class UserDataPolicy < GdprAdmin::ApplicationDataPolicy
|
30
|
+
def scope
|
31
|
+
User.with_deleted.where(updated_at: ...request.data_older_than)
|
32
|
+
end
|
33
|
+
|
34
|
+
def erase(user)
|
35
|
+
user.update_columns(
|
36
|
+
first_name: 'Anonymous',
|
37
|
+
last_name: "User #{user.id}",
|
38
|
+
email: "anonymous.user#{user.id}@company.co",
|
39
|
+
anonymized_at: Time.zone.now,
|
40
|
+
)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
```
|
44
|
+
|
45
|
+
Once you have all your data policies defined, create a `GdprAdmin::Request` to process a new request:
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
GdprAdmin::Request.create!(
|
49
|
+
tenant: current_tenant,
|
50
|
+
requester: current_admin_user,
|
51
|
+
request_type: 'erase_all',
|
52
|
+
data_older_than: 1.month.ago, # Optional: by default, it will be todays date
|
53
|
+
)
|
54
|
+
```
|
55
|
+
|
56
|
+
Creating a request will automatically enqueue the request to be processed in 4 hours - this gives time to cancel an accidental request. You can configure this grace period as desired.
|
57
|
+
|
58
|
+
|
59
|
+
## License
|
60
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GdprAdmin
|
4
|
+
class Request < ApplicationRecord
|
5
|
+
belongs_to :tenant, class_name: GdprAdmin.config.tenant_class
|
6
|
+
belongs_to :requester, class_name: GdprAdmin.config.requester_class
|
7
|
+
|
8
|
+
enum status: {
|
9
|
+
pending: 'pending',
|
10
|
+
processing: 'processing',
|
11
|
+
completed: 'completed',
|
12
|
+
failed: 'failed',
|
13
|
+
}
|
14
|
+
|
15
|
+
enum request_type: {
|
16
|
+
subject_export: 'subject_export',
|
17
|
+
erase_all: 'erase_all',
|
18
|
+
erase_subject: 'erase_subject',
|
19
|
+
erase_timeframe: 'erase_timeframe',
|
20
|
+
}
|
21
|
+
|
22
|
+
before_validation :set_default_data_older_than!
|
23
|
+
after_create_commit :schedule_processing
|
24
|
+
|
25
|
+
def process!
|
26
|
+
GdprAdmin.load_data_policies
|
27
|
+
with_lock { processing! }
|
28
|
+
with_lock do
|
29
|
+
GdprAdmin.config.tenant_adapter.with_tenant(tenant) { process_policies }
|
30
|
+
completed!
|
31
|
+
end
|
32
|
+
rescue StandardError
|
33
|
+
failed!
|
34
|
+
raise
|
35
|
+
end
|
36
|
+
|
37
|
+
def erase?
|
38
|
+
erase_all? || erase_subject? || erase_timeframe?
|
39
|
+
end
|
40
|
+
|
41
|
+
def export?
|
42
|
+
subject_export?
|
43
|
+
end
|
44
|
+
|
45
|
+
def schedule_processing
|
46
|
+
RequestProcessorJob.set(wait: 4.hours).perform_later(self)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def process_policies
|
52
|
+
ApplicationDataPolicy.descendants.each do |policy_class|
|
53
|
+
policy = policy_class.new(self)
|
54
|
+
policy.scope.find_each do |record|
|
55
|
+
policy.export(record) if export?
|
56
|
+
policy.erase(record) if erase?
|
57
|
+
end
|
58
|
+
rescue SkipDataPolicyError
|
59
|
+
next
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def set_default_data_older_than!
|
64
|
+
self.data_older_than ||= Time.zone.now
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CreateGdprAdminRequests < ActiveRecord::Migration[7.0]
|
4
|
+
def change
|
5
|
+
create_table :gdpr_admin_requests do |t|
|
6
|
+
t.references :tenant, null: false, foreign_key: { to_table: :organizations }
|
7
|
+
t.references :requester, null: false, foreign_key: { to_table: :admin_users }
|
8
|
+
t.string :request_type, null: false
|
9
|
+
t.string :status, default: 'pending', null: false
|
10
|
+
t.datetime :data_older_than, null: false
|
11
|
+
|
12
|
+
t.timestamps
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GdprAdmin
|
4
|
+
module Anonymizers
|
5
|
+
module InternetAnonymizer
|
6
|
+
def anonymize_email
|
7
|
+
Faker::Internet.email
|
8
|
+
end
|
9
|
+
|
10
|
+
def anonymize_password(record)
|
11
|
+
record.send(:password_digest, SecureRandom.hex(32))
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GdprAdmin
|
4
|
+
module Anonymizers
|
5
|
+
module NameAnonymizer
|
6
|
+
def anonymize_name
|
7
|
+
Faker::Name.name
|
8
|
+
end
|
9
|
+
|
10
|
+
def anonymize_first_name
|
11
|
+
Faker::Name.first_name
|
12
|
+
end
|
13
|
+
|
14
|
+
def anonymize_last_name
|
15
|
+
Faker::Name.last_name
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GdprAdmin
|
4
|
+
class ApplicationDataPolicy
|
5
|
+
include Helpers::EraseHelper
|
6
|
+
|
7
|
+
def initialize(request)
|
8
|
+
@request = request
|
9
|
+
end
|
10
|
+
|
11
|
+
def scope
|
12
|
+
raise SkipDataPolicyError
|
13
|
+
end
|
14
|
+
|
15
|
+
def export(_record)
|
16
|
+
raise NotImplementedError
|
17
|
+
end
|
18
|
+
|
19
|
+
def erase(_record)
|
20
|
+
raise NotImplementedError
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
|
25
|
+
attr_reader :request
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GdprAdmin
|
4
|
+
class Configuration
|
5
|
+
attr_accessor :tenant_class, :requester_class, :data_policies_path
|
6
|
+
attr_writer :tenant_adapter
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@tenant_class = 'Organization'
|
10
|
+
@requester_class = 'AdminUser'
|
11
|
+
@tenant_adapter = TenantAdapters::ActsAsTenantAdapter.new
|
12
|
+
@data_policies_path = Rails.root.join('app', 'gdpr')
|
13
|
+
end
|
14
|
+
|
15
|
+
def tenant_adapter
|
16
|
+
return @tenant_adapter unless @tenant_adapter.is_a?(Symbol)
|
17
|
+
|
18
|
+
GdprAdmin::TenantAdapters.const_get("#{@tenant_adapter}_adapter".classify).new
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../anonymizers/name_anonymizer'
|
4
|
+
require_relative '../anonymizers/contact_anonymizer'
|
5
|
+
require_relative '../anonymizers/internet_anonymizer'
|
6
|
+
|
7
|
+
module GdprAdmin
|
8
|
+
module Helpers
|
9
|
+
module EraseHelper
|
10
|
+
include Anonymizers::NameAnonymizer
|
11
|
+
include Anonymizers::ContactAnonymizer
|
12
|
+
include Anonymizers::InternetAnonymizer
|
13
|
+
|
14
|
+
##
|
15
|
+
# Erases the given fields on the given record using the method given.
|
16
|
+
# Fields should be an array of hashes formatted as follows:
|
17
|
+
#
|
18
|
+
# ```ruby
|
19
|
+
# [
|
20
|
+
# { field: :first_name, method: :anonymize, seed: :id },
|
21
|
+
# { field: :last_name, method: :anonymize },
|
22
|
+
# { field: :job_title, method: -> { 'Anonymized Title' } },
|
23
|
+
# { field: :email, method: :anonymize_email },
|
24
|
+
# { field: :password_digest, method: :anonymize_password },
|
25
|
+
# { field: :phone_number, method: ->(record) { record.phone_number.split('').shuffle.join } },
|
26
|
+
# { field: :address, method: :nillify },
|
27
|
+
# ]
|
28
|
+
# ```
|
29
|
+
#
|
30
|
+
# By default, the seed for the anonymize method is the value of the field being anonymized.
|
31
|
+
# If you want to use a different field as the seed, you can specify it using the `seed` key.
|
32
|
+
#
|
33
|
+
# If you want to use a method that is not defined in the anonymizer, you can pass a lambda.
|
34
|
+
# The lambda will be called with the record as the first argument and the seed as the second.
|
35
|
+
#
|
36
|
+
# The third argument of the `erase_fields` method is an optional base fields hash that will be used to
|
37
|
+
# update the record. This is useful if you want to `erase_fields` to update other fields that
|
38
|
+
# are not part of the erasure process. For example:
|
39
|
+
#
|
40
|
+
# ```ruby
|
41
|
+
# erase_fields(record, fields, { anonymized_at: Time.zone.now })
|
42
|
+
# ```
|
43
|
+
#
|
44
|
+
# This method uses the `update_columns` method to update the record, so it will skip validations.
|
45
|
+
#
|
46
|
+
# @param record [ActiveRecord::Base] The record to erase
|
47
|
+
# @param fields [Array<Hash>] The fields to erase
|
48
|
+
# @param base_fields [Hash] The fields to update on the record together with the erased fields
|
49
|
+
def erase_fields(record, fields, base_fields = {})
|
50
|
+
new_data = fields.inject(base_fields) do |res, curr|
|
51
|
+
next res if record[curr[:field]].nil?
|
52
|
+
|
53
|
+
res.merge(
|
54
|
+
curr[:field] => call_method(curr[:method], record, record[curr[:seed] || curr[:field]]),
|
55
|
+
)
|
56
|
+
end
|
57
|
+
record.update_columns(new_data)
|
58
|
+
end
|
59
|
+
|
60
|
+
def nillify
|
61
|
+
nil
|
62
|
+
end
|
63
|
+
|
64
|
+
def with_seed(seed)
|
65
|
+
Faker::Config.random = Random.new(seed.to_s.chars.sum(&:ord)) if defined?(Faker)
|
66
|
+
yield
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def call_method(erase_method, record, seed)
|
72
|
+
return if erase_method.nil?
|
73
|
+
|
74
|
+
erase_method = method(erase_method) if erase_method.is_a?(Symbol)
|
75
|
+
|
76
|
+
arity = erase_method.arity
|
77
|
+
with_seed(seed) do
|
78
|
+
erase_method.call(*[record, seed].take(arity))
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/lib/gdpr_admin.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'gdpr_admin/version'
|
4
|
+
require 'gdpr_admin/engine'
|
5
|
+
require 'gdpr_admin/configuration'
|
6
|
+
require 'gdpr_admin/skip_data_policy_error'
|
7
|
+
require 'gdpr_admin/helpers/erase_helper'
|
8
|
+
require 'gdpr_admin/application_data_policy'
|
9
|
+
require 'gdpr_admin/tenant_adapters/acts_as_tenant_adapter'
|
10
|
+
|
11
|
+
begin
|
12
|
+
require 'faker'
|
13
|
+
rescue LoadError; end # rubocop:disable Lint/SuppressedException
|
14
|
+
|
15
|
+
module GdprAdmin
|
16
|
+
def self.configure
|
17
|
+
yield config
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.config
|
21
|
+
@config ||= Configuration.new
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.load_data_policies(force: false)
|
25
|
+
return if Rails.application.config.eager_load && !force
|
26
|
+
|
27
|
+
Dir.glob(Pathname.new(config.data_policies_path).join('**', '*.rb')).each do |file|
|
28
|
+
require_dependency file
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,180 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gdpr_admin
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Colex
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-02-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 6.1.7
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 6.1.7
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec-rails
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 6.0.1
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 6.0.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rubocop
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.45.1
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.45.1
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop-performance
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.11.5
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 1.11.5
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop-rails
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 2.12.4
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 2.12.4
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop-rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 2.4.0
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 2.4.0
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: simplecov
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.22.0
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.22.0
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: timecop
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.9.6
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.9.6
|
125
|
+
description: Engine for managing GDPR processes.
|
126
|
+
email:
|
127
|
+
- alex.santos@reachdesk.com
|
128
|
+
executables: []
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files: []
|
131
|
+
files:
|
132
|
+
- MIT-LICENSE
|
133
|
+
- README.md
|
134
|
+
- Rakefile
|
135
|
+
- app/jobs/gdpr_admin/application_job.rb
|
136
|
+
- app/jobs/gdpr_admin/request_processor_job.rb
|
137
|
+
- app/models/gdpr_admin/application_record.rb
|
138
|
+
- app/models/gdpr_admin/request.rb
|
139
|
+
- config/routes.rb
|
140
|
+
- db/migrate/20230212185817_create_gdpr_admin_requests.rb
|
141
|
+
- lib/gdpr_admin.rb
|
142
|
+
- lib/gdpr_admin/anonymizers/contact_anonymizer.rb
|
143
|
+
- lib/gdpr_admin/anonymizers/internet_anonymizer.rb
|
144
|
+
- lib/gdpr_admin/anonymizers/name_anonymizer.rb
|
145
|
+
- lib/gdpr_admin/application_data_policy.rb
|
146
|
+
- lib/gdpr_admin/configuration.rb
|
147
|
+
- lib/gdpr_admin/engine.rb
|
148
|
+
- lib/gdpr_admin/helpers/erase_helper.rb
|
149
|
+
- lib/gdpr_admin/skip_data_policy_error.rb
|
150
|
+
- lib/gdpr_admin/tenant_adapters/acts_as_tenant_adapter.rb
|
151
|
+
- lib/gdpr_admin/version.rb
|
152
|
+
- lib/tasks/gdpr_admin_tasks.rake
|
153
|
+
homepage: https://github.com/Colex/gdpr_admin
|
154
|
+
licenses:
|
155
|
+
- MIT
|
156
|
+
metadata:
|
157
|
+
homepage_uri: https://github.com/Colex/gdpr_admin
|
158
|
+
source_code_uri: https://github.com/Colex/gdpr_admin
|
159
|
+
changelog_uri: https://github.com/Colex/gdpr_admin
|
160
|
+
rubygems_mfa_required: 'true'
|
161
|
+
post_install_message:
|
162
|
+
rdoc_options: []
|
163
|
+
require_paths:
|
164
|
+
- lib
|
165
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
166
|
+
requirements:
|
167
|
+
- - ">="
|
168
|
+
- !ruby/object:Gem::Version
|
169
|
+
version: 2.7.4
|
170
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
171
|
+
requirements:
|
172
|
+
- - ">="
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: '0'
|
175
|
+
requirements: []
|
176
|
+
rubygems_version: 3.3.26
|
177
|
+
signing_key:
|
178
|
+
specification_version: 4
|
179
|
+
summary: Engine for managing GDPR processes.
|
180
|
+
test_files: []
|