cmor_legal 0.0.45.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +27 -0
  4. data/Rakefile +21 -0
  5. data/app/assets/config/manifest.js +2 -0
  6. data/app/assets/javascripts/cmor/legal/application.js +2 -0
  7. data/app/assets/javascripts/cmor/legal/application/keep.js +0 -0
  8. data/app/assets/javascripts/cmor_legal.js +2 -0
  9. data/app/assets/stylesheets/cmor/legal/application.css +3 -0
  10. data/app/assets/stylesheets/cmor/legal/application/keep.css +0 -0
  11. data/app/assets/stylesheets/cmor_legal.css +3 -0
  12. data/app/builders/cmor/legal/personal_data_hash_builder.rb +50 -0
  13. data/app/controllers/cmor/legal/home_controller.rb +8 -0
  14. data/app/controllers/cmor/legal/personal_data_controller.rb +24 -0
  15. data/app/controllers/cmor/legal/privacy_policies_controller.rb +18 -0
  16. data/app/models/cmor/legal/cookie.rb +87 -0
  17. data/app/models/cmor/legal/cookie_preferences.rb +47 -0
  18. data/app/models/cmor/legal/cookie_store.rb +39 -0
  19. data/app/models/cmor/legal/personal_data.rb +60 -0
  20. data/app/models/cmor/legal/privacy_policy.rb +24 -0
  21. data/app/registries/cmor/legal/personal_data_registry.rb +42 -0
  22. data/app/resolvers/cmor/legal/privacy_policy_resolver.rb +8 -0
  23. data/app/view_helpers/cmor/legal/application_view_helper.rb +8 -0
  24. data/app/views/cmor/legal/home/_index_extras.html.haml +22 -0
  25. data/app/views/cmor/legal/personal_data/_index_table.haml +1 -0
  26. data/app/views/cmor/legal/personal_data/_show_extras.haml +1 -0
  27. data/app/views/cmor/legal/personal_data/_show_table.haml +1 -0
  28. data/app/views/cmor/legal/privacy_policies/_form.haml +14 -0
  29. data/app/views/cmor/legal/privacy_policies/_index_table.haml +6 -0
  30. data/app/views/cmor/legal/privacy_policies/_show_table.html.haml +8 -0
  31. data/config/initializers/assets.rb +2 -0
  32. data/config/initializers/cmor.rb +3 -0
  33. data/config/locales/de.yml +20 -0
  34. data/config/locales/en.yml +15 -0
  35. data/config/routes.rb +7 -0
  36. data/lib/cmor/legal/configuration.rb +64 -0
  37. data/lib/cmor/legal/engine.rb +7 -0
  38. data/lib/cmor/legal/version.rb +9 -0
  39. data/lib/cmor_legal.rb +15 -0
  40. data/lib/generators/cmor/legal/install/install_generator.rb +26 -0
  41. data/lib/generators/cmor/legal/install/templates/initializer.rb +69 -0
  42. data/lib/generators/cmor/legal/install/templates/routes.source +4 -0
  43. data/lib/tasks/cmor/legal_tasks.rake +8 -0
  44. data/spec/factories/cmor_legal_privacy_policies.rb +7 -0
  45. data/spec/features/de/backend/juristisches/privacy_policies_feature_spec.rb +60 -0
  46. data/spec/lib/cmor/legal/version_spec.rb +7 -0
  47. data/spec/models/cmor/legal/cookie_spec.rb +63 -0
  48. data/spec/rails_helper.rb +62 -0
  49. data/spec/spec_helper.rb +98 -0
  50. data/spec/support/active_job.rb +3 -0
  51. data/spec/support/capybara.rb +3 -0
  52. data/spec/support/factory_bot.rb +16 -0
  53. data/spec/support/pry.rb +3 -0
  54. data/spec/support/rao-shoulda_matchers.rb +7 -0
  55. metadata +447 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 726b8847cf2f2dd601b19e2a2c274791519ba598ebfeddfe3507938bf11daf6e
4
+ data.tar.gz: 1f5313a37e144c24e6087d80c2a377dc64e7a3be5cd423075ecb4df4a5bd4068
5
+ SHA512:
6
+ metadata.gz: 16958f751012d2a40da403acb98d05adcb1967ced86fbb7fb78143c248cbb6a8cafde58c2241ec6ef01560ad38f20903a7007c3d950e91e2e8bf20d5cc122701
7
+ data.tar.gz: 1197a0bdc717c8754acc61c6687071e92a10ef9e6d76b186c96455fede242e7bc3bad7800b5b302a0ddd4cec5e6f1ce9ee824dc727339c04063cf89cdde22f65
@@ -0,0 +1,20 @@
1
+ Copyright 2020 Roberto Vasquez Angel
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.
@@ -0,0 +1,27 @@
1
+ # Cmor::Legal
2
+ Short description and motivation.
3
+
4
+ ## Usage
5
+ How to use my plugin.
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'cmor_legal'
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+ ```bash
21
+ $ gem install cmor_legal
22
+ ```
23
+ ## Contributing
24
+ Contribution directions go here.
25
+
26
+ ## License
27
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require "bundler/setup"
5
+ rescue LoadError
6
+ puts "You must `gem install bundler` and `bundle install` to run rake tasks"
7
+ end
8
+
9
+ require "rdoc/task"
10
+
11
+ RDoc::Task.new(:rdoc) do |rdoc|
12
+ rdoc.rdoc_dir = "rdoc"
13
+ rdoc.title = "Cmor::Legal"
14
+ rdoc.options << "--line-numbers"
15
+ rdoc.rdoc_files.include("README.md")
16
+ rdoc.rdoc_files.include("lib/**/*.rb")
17
+ end
18
+
19
+ Bundler::GemHelper.install_tasks
20
+
21
+ require "rails/dummy/tasks"
@@ -0,0 +1,2 @@
1
+ //= link_directory ../javascripts/cmor/legal .js
2
+ //= link_directory ../stylesheets/cmor/legal .css
@@ -0,0 +1,2 @@
1
+ //= require_tree ./application
2
+
@@ -0,0 +1,2 @@
1
+ //= require ./cmor/legal/application
2
+
@@ -0,0 +1,3 @@
1
+ /*
2
+ *= require_tree ./application
3
+ */
@@ -0,0 +1,3 @@
1
+ /*
2
+ *= require ./cmor/legal/application
3
+ */
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmor
4
+ module Legal
5
+ class PersonalDataHashBuilder
6
+ include ActiveModel::Model
7
+ attr_accessor :root, :options, :block
8
+
9
+ def initialize(attributes, options = {})
10
+ super(attributes)
11
+ @builder_options = options
12
+ invoke_block
13
+ end
14
+
15
+ def attribute(name, options = {})
16
+ if with_options?
17
+ hash[:attributes][name] = { options: options }
18
+ else
19
+ hash[:attributes] << name
20
+ end
21
+ end
22
+
23
+ def association(name, options = {}, &block)
24
+ if with_options?
25
+ hash[:associations][name] = { options: options, attributes: Cmor::Legal::PersonalDataHashBuilder.new(block: block).hash }
26
+ else
27
+ hash[name] = Cmor::Legal::PersonalDataHashBuilder.new({ block: block }, @builder_options).hash
28
+ end
29
+ end
30
+
31
+ def hash
32
+ if with_options?
33
+ @hash ||= { root: root, options: options, attributes: {}, associations: {} }
34
+ else
35
+ @hash ||= { attributes: [] }
36
+ end
37
+ end
38
+
39
+ private
40
+ def invoke_block
41
+ self.block.call(self)
42
+ end
43
+
44
+ def with_options?
45
+ @builder_options[:with_options] = true if @builder_options[:with_options].nil?
46
+ @builder_options[:with_options]
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmor
4
+ module Legal
5
+ class HomeController < Cmor::Core::Backend::HomeController::Base
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmor
4
+ module Legal
5
+ class PersonalDataController < Cmor::Core::Backend::ResourcesController::Base
6
+ def self.resource_class
7
+ Cmor::Legal::PersonalData
8
+ end
9
+
10
+ def self.available_rest_actions
11
+ super - %i(edit new)
12
+ end
13
+
14
+ private
15
+ def load_collection
16
+ @collection = Kaminari.paginate_array(load_collection_scope.all).page(params[:page])
17
+ end
18
+
19
+ def permitted_params
20
+ params.require(:personal_data_registry).permit()
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmor
4
+ module Legal
5
+ class PrivacyPoliciesController < Cmor::Core::Backend::ResourcesController::Base
6
+ include Rao::ResourcesController::ActsAsPublishedConcern
7
+
8
+ def self.resource_class
9
+ Cmor::Legal::PrivacyPolicy
10
+ end
11
+
12
+ private
13
+ def permitted_params
14
+ params.require(:privacy_policy).permit(:locale, :meta_description, :title, :body, :format, :handler, :published)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmor
4
+ module Legal
5
+ class Cookie
6
+ include ActiveModel::Model
7
+
8
+ attr_accessor :identifier, :adjustable, :default, :value, :cookie_store
9
+
10
+ def initialize(attributes = {})
11
+ attributes.each do |key, value|
12
+ send("#{key}=", value)
13
+ end
14
+ end
15
+
16
+ def self.to_boolean(string)
17
+ return true if ["true", true, "1", 1].include?(string)
18
+ return false if ["false", false, "0", 0, nil].include?(string)
19
+ raise "Can't translate #{string} to boolean"
20
+ end
21
+
22
+ def self.all(cookie_store = nil)
23
+ Cmor::Legal::Configuration.cookies.call(cookie_store)
24
+ end
25
+
26
+ def self.first(cookie_store = nil)
27
+ all(cookie_store).first
28
+ end
29
+
30
+ def self.accepted(cookie_store = nil)
31
+ all(cookie_store).select { |resource| resource.accepted? }
32
+ end
33
+
34
+ def value
35
+ initialize_value if @value.nil?
36
+ self.class.to_boolean(@value)
37
+ end
38
+
39
+ def value=(value)
40
+ @value = self.class.to_boolean(value)
41
+ end
42
+
43
+ def value_from_cookie_store
44
+ cookie_store.get_value(identifier)
45
+ end
46
+
47
+ def accepted?
48
+ # First check if the user has made a decision on this cookie.
49
+ if pending?
50
+ # The user has not decided on this cookie.
51
+ #
52
+ # If the cookie can't be changed by the user take the default value
53
+ # otherwise set it to false.
54
+ readonly? ? default : false
55
+ else
56
+ # The has accepted/rejected the cookie. Use the actual value.
57
+ !!value
58
+ end
59
+ end
60
+
61
+ def readonly?
62
+ !adjustable
63
+ end
64
+
65
+ def save
66
+ cookie_store.set_value(identifier, value, default_expire)
67
+ end
68
+
69
+ def pending?
70
+ value_from_cookie_store.nil?
71
+ end
72
+
73
+ private
74
+ def default_expire
75
+ 1.year.from_now
76
+ end
77
+
78
+ def initialize_value
79
+ @value = pending? ? default : value_from_cookie_store
80
+ end
81
+
82
+ def cookie_store
83
+ @cookie_store ||= ::Cmor::Legal::CookieStore.new({})
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmor
4
+ module Legal
5
+ class CookiePreferences
6
+ include ActiveModel::Model
7
+
8
+ attr_accessor :cookies, :cookie_store
9
+
10
+ def initialize(*attrs)
11
+ super
12
+ @cookies ||= ::Cmor::Legal::Configuration.cookies.call(cookie_store)
13
+ @cookies.map(&:identifier).each do |identifier|
14
+ singleton_class.class_eval do
15
+ # attr_accessor c
16
+ define_method(identifier) do
17
+ @cookies.find { |c| c.identifier == identifier }.value
18
+ end
19
+
20
+ define_method("#{identifier}=") do |value|
21
+ @cookies.find { |c| c.identifier == identifier }.value = value
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ def update_attributes(attributes)
28
+ attributes.each do |identifier, value|
29
+ @cookies.find { |c| c.identifier == identifier.to_sym }.value = value
30
+ end
31
+ save
32
+ end
33
+
34
+ def save
35
+ @cookies.each { |c| c.save }
36
+ end
37
+
38
+ def accepted?(identifier)
39
+ send(identifier)
40
+ end
41
+
42
+ def accepted_cookies
43
+ cookies.select { |c| c.accepted? }
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmor
4
+ module Legal
5
+ class CookieStore
6
+ attr_accessor :cookies
7
+
8
+ def initialize(store)
9
+ @store = store
10
+ end
11
+
12
+ def self.cookie_prefix
13
+ ::Cmor::Legal::Configuration.cookie_prefix
14
+ end
15
+
16
+ def self.add_prefix_to_identifier(identifier)
17
+ "#{cookie_prefix}#{identifier}"
18
+ end
19
+
20
+ def get_value(identifier)
21
+ @store[self.class.add_prefix_to_identifier(identifier)]
22
+ end
23
+
24
+ def set_value(identifier, value, expires = nil)
25
+ if @store.is_a?(ActionDispatch::Cookies::CookieJar)
26
+ @store[self.class.add_prefix_to_identifier(identifier)] = { value: value, expires: expires }
27
+ else
28
+ @store[self.class.add_prefix_to_identifier(identifier)] = value
29
+ end
30
+ end
31
+
32
+ def cookies
33
+ @store.select { |key, value| key.to_s.start_with?(self.class.cookie_prefix) }.each_with_object({}) do |(k, v), m|
34
+ m[k.gsub(self.class.cookie_prefix, "")] = v
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmor
4
+ module Legal
5
+ class PersonalData
6
+ include ActiveModel::Model
7
+
8
+ attr_accessor :root, :options, :block
9
+
10
+ def to_hash_with_options
11
+ @hash ||= build_hash_with_options!
12
+ end
13
+
14
+ def build_hash_with_options!
15
+ Cmor::Legal::PersonalDataHashBuilder.new({ root: root, options: options, block: block }, { with_options: true }).hash
16
+ end
17
+
18
+ def to_hash
19
+ @hash ||= build_hash!
20
+ end
21
+
22
+ def build_hash!
23
+ Cmor::Legal::PersonalDataHashBuilder.new({ root: root, options: options, block: block }, { with_options: false }).hash
24
+ end
25
+
26
+ def self.all
27
+ Cmor::Legal::PersonalDataRegistry.all
28
+ end
29
+
30
+ def self.count
31
+ Cmor::Legal::PersonalDataRegistry.count
32
+ end
33
+
34
+ def self.attribute_names
35
+ [:root, :options, :block]
36
+ end
37
+
38
+ def self.find(id)
39
+ all.find { |x| x.root == id.gsub("-", "/").camelize }
40
+ end
41
+
42
+ def id
43
+ root.underscore.gsub("/", "-")
44
+ end
45
+
46
+ def to_param
47
+ id
48
+ end
49
+
50
+ def to_s
51
+ [self.class.model_name.human, root_model_human].compact.join(" - ")
52
+ end
53
+
54
+ def root_model_human
55
+ return if root.nil?
56
+ root.constantize.model_name.human
57
+ end
58
+ end
59
+ end
60
+ end