gdpr_rails 0.2.4 → 0.3.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
  SHA1:
3
- metadata.gz: 6f3bd8d4a83a8def6219e0f1133cdc0f5a072ce6
4
- data.tar.gz: c2678088ad8a2945e0836a20719778de1693dc7e
3
+ metadata.gz: b43a8ecf784c5fe1b24530af6c767b88c0af6d54
4
+ data.tar.gz: 492df811d80c74b0c28b69dde3e3bba0feeebf64
5
5
  SHA512:
6
- metadata.gz: 40d2cb1dbe0646fdd9193f034f06b71cac780e7e4b336fd054cf1441a8b317c6e3eb5d9dbb709a5006717acf1b19df4828c756a489b90a60cc2a81417ca51f5d
7
- data.tar.gz: d95f5add634525882da0543931adbcb15e6b77fb172ed194481b650a73dd37a173da16ae0e23027d2e6e720b6f1a7cc7c58f3663e2727d13fe27fd473db8f5d9
6
+ metadata.gz: 53f0054aaeafad9a6e64022609bbccfbf0417b0488291b33b578c93ea07e8cd57000c03f6c549824ada0e7115b33843d97bd9bba9c428bfefaae7779dcf66183
7
+ data.tar.gz: 3e366811b4af4b5dc8f5dac5bf2448e1b9c05379de27ab4fd9a701c4ae0b1def7f5a117bfe3c1f4f972d8dc06ac571d6744525b68b81efce9103ff1b372c2e10
data/README.md CHANGED
@@ -24,7 +24,7 @@ PolicyManager (Aka GDPR RAILS) was created with flexibility in mind to comply wi
24
24
  + JSON endpoints to handle pending policies and portability logic in order to be implemented in *client only* interfaces, ie: frontend apps like React, Vue, Backbone, you name it.
25
25
 
26
26
  #### Portability
27
- Portability module lets you define export options, that will generate a navigable static site with all the data you've defined in the **portability rules**
27
+ Portability module lets you define export options, that will generate a navigable static HTML site with all the data you've defined in the **portability rules** with json support too.
28
28
  + Seamless data export with configurable templates
29
29
  + Configurable Mailer templates for progress & download completion
30
30
  + Downloads images to the local filesystem in order to comply with GDPR requirements on data accessibility.
@@ -210,8 +210,8 @@ Export option & Portability rules will allow you to set up how and which data yo
210
210
  #### Exporter:
211
211
  + **path**: where the folder will be generated, usually can be set on /tmp, this will need a pathname, like `Rails.root.join("tmp/export")`
212
212
  + **resource**: which model , ie: `User`
213
- + **index_template**: The first page. defaults to a simple ul li list of links tied to your rules, this expects a Pathname or a String with yout template
214
- + **layout**: A layout template to wrap the static site, this expects a Pathname or a String with your template
213
+ + **index_template**: The first page. defaults to a simple ul li list of links tied to your rules, this expects a Pathname or a String with your template
214
+ + **layout**: A layout template this expects a layout name which has to be available on your app.
215
215
  + **after_zip**: a callback to handle the zip file on the resource, something like:
216
216
  ```ruby
217
217
  after_zip: ->(zip_path, resource){
@@ -245,6 +245,8 @@ PolicyManager::Config.setup do |c|
245
245
  name: "exportable_data",
246
246
  collection: :articles,
247
247
  template: "hello, a collection will be rendered here use @collection.to_json",
248
+ json_template: "collection.json.jbuilder", # or Rails.root.join("app/views/collection.json.jbuilder")
249
+
248
250
  per: 10
249
251
  })
250
252
 
@@ -0,0 +1,7 @@
1
+ module PolicyManager
2
+ class ExporterController < ActionController::Base
3
+
4
+ include ExporterHelper
5
+
6
+ end
7
+ end
@@ -0,0 +1,29 @@
1
+ module PolicyManager
2
+ module ExporterHelper
3
+
4
+ def image_tag(remote_image, opts={})
5
+ begin
6
+ basename = File.basename(remote_image)
7
+ id = opts[:id] || SecureRandom.hex(10)
8
+ composed_name = [id, basename].compact.join("-")
9
+ path = "#{File.dirname(@base_path)}/#{composed_name}"
10
+ save_image(remote_image, path)
11
+ tag(:img, {src: "./#{id}-#{File.basename(URI(remote_image).path)}" }.merge(opts))
12
+ rescue => e
13
+ Config.error_notifier_method(e)
14
+ content_tag(:p, "broken image")
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def save_image(remote_image, path)
21
+ open(URI(path).path, 'wb') do |file|
22
+ file << open(remote_image).read
23
+ end
24
+ end
25
+
26
+ end
27
+ end
28
+
29
+
@@ -65,10 +65,7 @@ module PolicyManager::Concerns::UserBehavior
65
65
  self.send(rule.member)
66
66
  end
67
67
 
68
- def portability_collection_for(rule, page)
69
- # if kaminari
70
- # self.send(rule.collection).page(1)
71
- # if will paginate
68
+ def portability_collection_for(rule, page = nil)
72
69
  self.send(rule.collection).paginate(page: page, per_page: rule.per)
73
70
  end
74
71
 
@@ -8,8 +8,10 @@ require "policy_manager/portability_rule"
8
8
  require "policy_manager/exporter"
9
9
  require "policy_manager/exporter/handler.rb"
10
10
  require "policy_manager/exporter/view.rb"
11
+ require "policy_manager/exporter/json_view.rb"
11
12
  require "policy_manager/exporter/zip_generator.rb"
12
13
  require "policy_manager/exporter/paginator_renderer.rb"
14
+ require "policy_manager/exporter/json_link.rb"
13
15
 
14
16
  require "policy_manager/config"
15
17
 
@@ -28,7 +28,8 @@ module PolicyManager
28
28
  end
29
29
 
30
30
  def self.error_notifier_method(error)
31
- @@error_notifier.call(error)
31
+ puts error
32
+ @@error_notifier.call(error) unless @@error_notifier.blank?
32
33
  end
33
34
 
34
35
  def self.admin_email(user)
@@ -66,37 +66,72 @@ module PolicyManager
66
66
  return unless resource.respond_to?(:portability_member_for)
67
67
  o = resource.portability_member_for(rule)
68
68
  base_dir = self.base_path.join(rule.name)
69
- resource_path = base_dir.join("index.html")
70
69
  FileUtils.mkdir_p(base_dir)
71
- view = ExporterView.new({member: o}, {build_path: self.base_path, base_path: resource_path, template: rule.template, rule: rule})
70
+ resource_path = base_dir.join("index.html")
71
+
72
+ view = ExporterView.new({
73
+ assigns: {member: o},
74
+ build_path: self.base_path,
75
+ base_path: resource_path,
76
+ template: rule.template,
77
+ rule: rule
78
+ }).save(resource_path)
79
+
72
80
  puts "saving at #{self.path.join rule.name}"
73
- view.save(resource_path )
81
+
82
+ json = JsonExporterView.new({
83
+ assigns: {member: o},
84
+ template: rule.json_template,
85
+ folder: base_dir
86
+ }).save if rule.json_template.present?
74
87
  end
75
88
 
76
89
  def render_collection(rule)
77
90
  return unless resource.respond_to?(:portability_collection_for)
78
- o = resource.portability_collection_for(rule ,1)
79
-
91
+ o = resource.portability_collection_for(rule, 1)
92
+
93
+ base_dir = self.base_path.join(rule.name)
94
+ FileUtils.mkdir_p(base_dir)
95
+
80
96
  (1..o.total_pages).to_a.each do |i|
81
- o = resource.portability_collection_for(rule,i)
82
- page_name = i #== 1 ? "index" : i
83
- base_dir = self.base_path.join(rule.name)
84
- base_dir = base_dir.join(page_name.to_s) unless page_name == 1
85
- FileUtils.mkdir_p(base_dir)
86
- resource_path = base_dir.join("index.html")
87
- view = ExporterView.new({collection: o}, {build_path: self.base_path, base_path: resource_path, template: rule.template, rule: rule})
97
+ o = resource.portability_collection_for(rule, i)
98
+
99
+ page_name = i
100
+ folder_dir = page_name == 1 ? base_dir : base_dir.join(page_name.to_s)
101
+ FileUtils.mkdir_p(folder_dir)
102
+ resource_path = folder_dir.join("index.html")
103
+
104
+ view = ExporterView.new({
105
+ assigns: {collection: o} ,
106
+ build_path: self.base_path,
107
+ base_path: resource_path,
108
+ template: rule.template,
109
+ rule: rule
110
+ }).save(resource_path)
111
+
112
+
113
+ json = JsonExporterView.new({
114
+ assigns: {collection: o},
115
+ template: rule.json_template,
116
+ folder: folder_dir
117
+ }).save if rule.json_template.present?
118
+
88
119
  puts "saving at #{self.path.join rule.name}"
89
- view.save( resource_path )
90
120
  end
91
121
  end
92
122
 
93
123
  def render_index
94
124
  resource_path = self.base_path.join("index.html")
95
125
  template = PolicyManager::Config.exporter.index_template
96
- view = ExporterView.new({collection: PolicyManager::Config.portability_rules},
97
- {build_path: self.base_path, base_path: resource_path, template: template})
126
+ view = ExporterView.new({
127
+ assigns: {
128
+ collection: PolicyManager::Config.portability_rules
129
+ },
130
+ build_path: self.base_path,
131
+ base_path: resource_path,
132
+ template: template
133
+ }).save( resource_path )
98
134
  puts "saving at #{resource_path}"
99
- view.save( resource_path )
100
135
  end
101
136
 
102
137
  def generate_zip
@@ -0,0 +1,19 @@
1
+ module PolicyManager
2
+ class JsonLink
3
+
4
+ def self.render(collection = nil)
5
+ ActionController::Base.helpers.content_tag(:a, "Open as JSON", href: link(collection), target: '_blank')
6
+ end
7
+
8
+ private
9
+
10
+ def self.link(collection)
11
+ if collection.nil? || collection.current_page == 1
12
+ return "./data.json"
13
+ else
14
+ return "./../data.json"
15
+ end
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,47 @@
1
+ require "fileutils"
2
+
3
+ module PolicyManager
4
+ class JsonExporterView
5
+ attr_accessor :template, :folder, :assigns
6
+
7
+ def initialize(vars={}, options)
8
+ self.folder = options[:folder]
9
+ self.assigns = options[:assigns]
10
+ @template = options.fetch(:template) #, self.class.template)
11
+ return self
12
+ end
13
+
14
+ def save
15
+ render_json
16
+ end
17
+
18
+ def save_json(file, data)
19
+ File.open(file, "w") do |f|
20
+ f.write(data)
21
+ end
22
+ end
23
+
24
+ def render_json
25
+ ac = PolicyManager::ExporterController.new()
26
+ options = handled_template.merge!({assigns: self.assigns })
27
+ content = ac.render_to_string(options)
28
+ save_json("#{folder}/data.json", content)
29
+ end
30
+
31
+ def handled_template
32
+ begin
33
+ if URI.parse(@template)
34
+ return {template: @template}
35
+ end
36
+ rescue URI::InvalidURIError
37
+ end
38
+
39
+ if @template.is_a?(String)
40
+ return {inline: @template}
41
+ elsif @template.is_a?(Pathname)
42
+ return {file: @template }
43
+ end
44
+ end
45
+
46
+ end
47
+ end
@@ -1,5 +1,6 @@
1
1
  require "will_paginate"
2
2
  require 'will_paginate/view_helpers/action_view'
3
+ require 'will_paginate/array'
3
4
 
4
5
  module PolicyManager
5
6
  class PaginatorRenderer < WillPaginate::ActionView::LinkRenderer
@@ -14,22 +14,19 @@ module PolicyManager
14
14
  include WillPaginate::ViewHelpers #if defined?(WillPaginate)
15
15
  include WillPaginate::ActionView #if defined?(WillPaginate)
16
16
 
17
- attr_accessor :template, :base_path
17
+ attr_accessor :template, :base_path, :assigns
18
18
 
19
19
  def self.template
20
20
  "Welcome, <%= @name %>"
21
21
  end
22
22
 
23
- def initialize(vars={}, options={}, date=Time.now)
24
- # collection or member, or wathever!?
25
- vars.each{|k, v| self.instance_variable_set("@#{k}", v)}
23
+ def initialize(options={}, date=Time.now)
26
24
  @base_path = options[:base_path]
27
25
  @build_path = options[:build_path]
28
-
26
+ self.assigns = options[:assigns]
29
27
  index_path
30
-
31
28
  @template = options.fetch(:template, self.class.template)
32
-
29
+ return self
33
30
  end
34
31
 
35
32
  def index_path
@@ -47,60 +44,39 @@ module PolicyManager
47
44
  end
48
45
  end
49
46
 
50
- def image_tag(remote_image, opts={})
51
- begin
52
- basename = File.basename(remote_image)
53
- id = opts[:id] || SecureRandom.hex(10)
54
- composed_name = [id, basename].compact.join("-")
55
- path = "#{File.dirname(base_path)}/#{composed_name}"
56
- self.save_image(remote_image, path)
57
- tag(:img, {src: "./#{id}-#{File.basename(URI(remote_image).path)}" }.merge(opts))
58
- rescue => e
59
- Config.error_notifier_method(e)
60
- content_tag(:p, "broken image")
61
- end
62
- end
63
-
64
- def save_image(remote_image, path)
65
- open(URI(path).path, 'wb') do |file|
66
- file << open(remote_image).read
67
- end
68
- end
69
-
70
47
  def render()
71
- #template_layout = Tilt::ERBTemplate.new {PolicyManager::Config.exporter.layout}
72
48
  context = self
73
- #template_layout.render {
74
- # view = Tilt::ERBTemplate.new{handled_template}
75
- # view.render(context)
76
- #}
77
-
78
- render_with_layout()
79
- end
80
-
81
- def render_with_layout(context = self)
82
- render_layout do
83
- ERB.new(handled_template).result(binding)
84
- end
85
- end
86
-
87
- def render_layout
88
- layout = PolicyManager::Config.exporter.layout #File.read('views/layouts/app.html.erb')
89
- ERB.new(layout).result(binding)
49
+ ac = PolicyManager::ExporterController.new()
50
+ options = handled_template.merge!({
51
+ assigns: self.assigns.merge!({
52
+ base_path: base_path,
53
+ build_path: @build_path,
54
+ index_path: index_path
55
+ }),
56
+ layout: PolicyManager::Config.exporter.layout
57
+ })
58
+ ac.render_to_string(options)
90
59
  end
91
60
 
92
-
93
61
  def save(file)
94
62
  File.open(file, "w+") do |f|
95
63
  f.write(render)
96
64
  end
97
65
  end
98
66
 
67
+ # TODO: method duplicated from json
99
68
  def handled_template
69
+ begin
70
+ if URI.parse(@template)
71
+ return {template: @template}
72
+ end
73
+ rescue URI::InvalidURIError
74
+ end
75
+
100
76
  if @template.is_a?(String)
101
- @template
77
+ return {inline: @template}
102
78
  elsif @template.is_a?(Pathname)
103
- File.open(@template).read
79
+ return {file: @template }
104
80
  end
105
81
  end
106
82
 
@@ -1,6 +1,13 @@
1
1
  module PolicyManager
2
2
  class PortabilityRule
3
- attr_accessor :name, :methods, :formats, :per, :collection, :member, :template
3
+ attr_accessor :name,
4
+ :methods,
5
+ :formats,
6
+ :per,
7
+ :collection,
8
+ :member,
9
+ :template,
10
+ :json_template
4
11
 
5
12
  def initialize(opts={})
6
13
  self.collection = opts[:collection]
@@ -9,6 +16,7 @@ module PolicyManager
9
16
  self.name = opts[:name]
10
17
  self.formats = opts[:formats]
11
18
  self.template = opts[:template]
19
+ self.json_template = opts[:json_template]
12
20
  end
13
21
 
14
22
  end
@@ -1,3 +1,3 @@
1
1
  module PolicyManager
2
- VERSION = '0.2.4'
2
+ VERSION = '0.3.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gdpr_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miguel Michelson
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-05-11 00:00:00.000000000 Z
12
+ date: 2018-05-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -206,11 +206,13 @@ files:
206
206
  - app/assets/stylesheets/scaffold.css
207
207
  - app/controllers/policy_manager/application_controller.rb
208
208
  - app/controllers/policy_manager/categories_controller.rb
209
+ - app/controllers/policy_manager/exporter_controller.rb
209
210
  - app/controllers/policy_manager/portability_requests_controller.rb
210
211
  - app/controllers/policy_manager/terms_controller.rb
211
212
  - app/controllers/policy_manager/user_portability_requests_controller.rb
212
213
  - app/controllers/policy_manager/user_terms_controller.rb
213
214
  - app/helpers/policy_manager/application_helper.rb
215
+ - app/helpers/policy_manager/exporter_helper.rb
214
216
  - app/helpers/policy_manager/portability_requests_helper.rb
215
217
  - app/helpers/policy_manager/scripts_helper.rb
216
218
  - app/helpers/policy_manager/terms_helper.rb
@@ -258,6 +260,8 @@ files:
258
260
  - lib/policy_manager/engine.rb
259
261
  - lib/policy_manager/exporter.rb
260
262
  - lib/policy_manager/exporter/handler.rb
263
+ - lib/policy_manager/exporter/json_link.rb
264
+ - lib/policy_manager/exporter/json_view.rb
261
265
  - lib/policy_manager/exporter/paginator_renderer.rb
262
266
  - lib/policy_manager/exporter/view.rb
263
267
  - lib/policy_manager/exporter/zip_generator.rb