cmor_legal 0.0.45.pre

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.
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,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmor
4
+ module Legal
5
+ class PrivacyPolicy < Cmor::Cms::Page
6
+ after_initialize :set_defaults, if: :new_record?
7
+ before_validation :set_locale_dependent_defaults, if: :new_record?
8
+
9
+ default_scope { where(pathname: "/cmor/legal/", basename: "show") }
10
+
11
+ private
12
+ def set_defaults
13
+ self.pathname ||= "/cmor/legal/"
14
+ self.basename ||= "privacy_policy"
15
+ self.handler ||= "textile"
16
+ end
17
+
18
+ def set_locale_dependent_defaults
19
+ return unless self.locale.present?
20
+ self.title ||= I18n.with_locale(self.locale) { I18n.t("cmor.legal.privacy_policy.default_title") }
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmor
4
+ module Legal
5
+ class PersonalDataRegistry
6
+ extend ActiveModel::Translation
7
+ extend ActiveModel::Naming
8
+
9
+ attr_accessor :personal_data
10
+
11
+ delegate :first, :last, :[], :each, :map, :collect, to: :personal_data
12
+
13
+ def initialize
14
+ @personal_data = []
15
+ end
16
+
17
+ def self.instance
18
+ @@instance
19
+ end
20
+
21
+ def self.all
22
+ instance.personal_data
23
+ end
24
+
25
+ def self.count
26
+ instance.personal_data.size
27
+ end
28
+
29
+ def self.attribute_names
30
+ [:personal_data]
31
+ end
32
+
33
+ def register(root, options, &block)
34
+ self.personal_data << PersonalData.new(root: root, options: options, block: block)
35
+ end
36
+
37
+ @@instance = Cmor::Legal::PersonalDataRegistry.new
38
+
39
+ private_class_method :new
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmor
4
+ module Legal
5
+ class PrivacyPolicyResolver < Cmor::Cms::PageResolver
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmor
4
+ module Legal
5
+ class ApplicationViewHelper < Rao::ViewHelper::Base
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,22 @@
1
+ = resource_table(resource: Cmor::Legal::Configuration) do |t|
2
+ = t.row :enforce_ssl do |resource|
3
+ - capture_haml do
4
+ - if resource.enforce_ssl
5
+ %span.label.label-success= t('true')
6
+ - else
7
+ %span.label.label-danger= t('false')
8
+ = t.row :filtered_log_parameters do |resource|
9
+ - resource.filter_personal_data_attributes.collect { |p| "<span class=\"label label-success\">#{p}</span>&nbsp;" }.join.html_safe
10
+ = t.row :enable_cookie_consent_banner do |resource|
11
+ - capture_haml do
12
+ - if resource.enable_cookie_consent_banner
13
+ %span.label.label-success= t('true')
14
+ - else
15
+ %span.label.label-danger= t('false')
16
+ - I18n.available_locales.each do |locale|
17
+ = t.row "privacy_policy_available_for_#{locale}" do |resource|
18
+ - capture_haml do
19
+ - if resource.privacy_policy_available_for(locale)
20
+ %span.label.label-success= t('true')
21
+ - else
22
+ %span.label.label-danger= t('false')
@@ -0,0 +1 @@
1
+ = table.column :root
@@ -0,0 +1 @@
1
+ = ap(@resource.to_hash.as_json).html_safe
@@ -0,0 +1 @@
1
+ = table.row :root
@@ -0,0 +1,14 @@
1
+ .well
2
+ = form.input :locale, collection: I18n.available_locales.map(&:to_s)
3
+
4
+ .well
5
+ ~ form.input :title
6
+ ~ form.input :meta_description, as: :string
7
+ ~ form.input :body
8
+
9
+ .well
10
+ = form.input :format, collection: Mime::SET.symbols
11
+ = form.input :handler, collection: ActionView::Template::Handlers.extensions
12
+
13
+ .well
14
+ = form.input :published, as: :boolean
@@ -0,0 +1,6 @@
1
+ = table.column :locale, sort: true
2
+ = table.acts_as_published_actions
3
+ - if table.method(:timestamps).arity > 0
4
+ = table.timestamps(sort: true)
5
+ - else
6
+ = table.timestamps
@@ -0,0 +1,8 @@
1
+ = table.row :locale
2
+ = table.row :meta_description
3
+ = table.row :body do |resource|
4
+ - capture_haml do
5
+ %pre= resource.body
6
+ = table.row :layout
7
+ = table.timestamp :published_at
8
+ = table.timestamps
@@ -0,0 +1,2 @@
1
+ Rails.application.config.assets.precompile += %w( cmor_legal.css )
2
+ Rails.application.config.assets.precompile += %w( cmor_legal.js )
@@ -0,0 +1,3 @@
1
+ Cmor.configure do |config|
2
+ config.administrador.register_engine('Cmor::Legal::Engine', {})
3
+ end
@@ -0,0 +1,20 @@
1
+ de:
2
+ classes:
3
+ cmor/legal/engine: Juristisches
4
+ routes:
5
+ cmor-legal-engine: juristisches
6
+ activerecord:
7
+ models:
8
+ cmor/legal/privacy_policy:
9
+ one: Datenschutzerklärung
10
+ other: Datenschutzerklärungen
11
+ activemodel:
12
+ models:
13
+ cmor/legal/cookie_preferences:
14
+ one: Cookie-Einstellungen
15
+ other: Cookie-Einstellungen
16
+ cmor/legal/personal_data:
17
+ one: Persönliche Daten
18
+ other: Persönliche Daten
19
+
20
+
@@ -0,0 +1,15 @@
1
+ en:
2
+ classes:
3
+ cmor/legal/engine: Legal
4
+ routes:
5
+ cmor-legal-engine: legal
6
+ activemodel:
7
+ models:
8
+ cmor/legal/cookie_preferences:
9
+ one: Cookie preferences
10
+ other: Cookie preferences
11
+ cmor/legal/personal_data:
12
+ one: Personal Data
13
+ other: Personal Data
14
+
15
+
@@ -0,0 +1,7 @@
1
+ Cmor::Legal::Engine.routes.draw do
2
+ resources :privacy_policies do
3
+ post :toggle_published, on: :member
4
+ end
5
+ resources :personal_data, :only => [:index, :show]
6
+ root to: 'home#index'
7
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmor::Legal
4
+ module Configuration
5
+ def configure
6
+ yield self
7
+ end
8
+
9
+ mattr_accessor :resources_controllers do
10
+ -> { [] }
11
+ end
12
+
13
+ mattr_accessor :resource_controllers do
14
+ -> { [] }
15
+ end
16
+
17
+ mattr_accessor :service_controllers do
18
+ -> { [] }
19
+ end
20
+
21
+ mattr_accessor :sidebar_controllers do
22
+ -> { [] }
23
+ end
24
+
25
+ mattr_accessor :resources do
26
+ {}
27
+ end
28
+ mattr_accessor(:personal_data_root_classes) { [] }
29
+ mattr_accessor(:filter_personal_data_attributes) { [:email, :firstname, :lastname, :birthdate] }
30
+ mattr_accessor(:enforce_ssl) { true }
31
+ mattr_accessor(:enable_cookie_consent_banner) { true }
32
+ mattr_accessor(:cookies) do
33
+ ->(cookie_store = ::Cmor::Legal::CookieStore.new({})) { [
34
+ ::Cmor::Legal::Cookie.new(identifier: :basic, adjustable: false, default: true, cookie_store: cookie_store)
35
+ ]}
36
+ end
37
+ mattr_accessor(:cookie_prefix) { "#{Rails.application.class.name.deconstantize.underscore}-eu_gdpr-" }
38
+ mattr_accessor(:cookie_storage) { :cookies }
39
+
40
+ def personal_data
41
+ @personal_data ||= ::Cmor::Legal::PersonalDataRegistry.instance
42
+ end
43
+
44
+ def self.enforce_ssl?
45
+ enforce_ssl
46
+ end
47
+
48
+ def self.enable_cookie_consent_banner?
49
+ enable_cookie_consent_banner
50
+ end
51
+
52
+ def self.privacy_policy_defaults_for(locale)
53
+ privacy_policy_defaults[locale.to_sym]
54
+ end
55
+
56
+ def self.privacy_policy_available_for(locale)
57
+ Cmor::Legal::PrivacyPolicy.where(locale: locale).any?
58
+ end
59
+
60
+ def self.filtered_log_parameters
61
+ Rails.application.config.filter_parameters
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmor::Legal
4
+ class Engine < ::Rails::Engine
5
+ isolate_namespace Cmor::Legal
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cmor/version"
4
+
5
+ module Cmor
6
+ module Legal
7
+ VERSION = ::Cmor::VERSION
8
+ end
9
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cmor_core"
4
+ require "cmor_core_backend"
5
+ require "cmor_cms"
6
+
7
+ require "cmor/legal/version"
8
+ require "cmor/legal/configuration"
9
+ require "cmor/legal/engine"
10
+
11
+ module Cmor
12
+ module Legal
13
+ extend Configuration
14
+ end
15
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cmor::Legal
4
+ module Generators
5
+ class InstallGenerator < Rails::Generators::Base
6
+ desc "Generates the initializer"
7
+
8
+ source_root File.expand_path("../templates", __FILE__)
9
+
10
+ attr_reader :base_controller_class_name
11
+
12
+ def initialize(*args)
13
+ super
14
+ @base_controller_class_name = ENV.fetch("BASE_CONTROLLER_CLASS_NAME") { "::ApplicationController" }
15
+ end
16
+
17
+ def generate_initializer
18
+ template "initializer.rb", "config/initializers/cmor_legal.rb"
19
+ end
20
+
21
+ def generate_routes
22
+ route File.read(File.join(File.expand_path("../templates", __FILE__), "routes.source"))
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,69 @@
1
+ Cmor::Legal.configure do |config|
2
+ # Set the resources, that will be shown in the backend menu.
3
+ #
4
+ # Default: config.registered_controllers = -> {[
5
+ # Cmor::Legal::PrivacyPoliciesController,
6
+ # Cmor::Legal::PersonalDataController
7
+ # ]}
8
+ #
9
+ config.resources_controllers = -> {[
10
+ Cmor::Legal::PrivacyPoliciesController,
11
+ Cmor::Legal::PersonalDataController
12
+ ]}
13
+
14
+ # Add these attributes to the rails logging filter
15
+ #
16
+ # default: config.filter_personal_data_attributes = [:email, :firstname, :lastname, :birthdate]
17
+ #
18
+ config.filter_personal_data_attributes = [:email, :firstname, :lastname, :birthdate]
19
+
20
+ # If set to true and force_ssl is not set to true in production it will raise
21
+ # an exception when trying to boot rails.
22
+ #
23
+ # default: config.enforce_ssl = true
24
+ #
25
+ config.enforce_ssl = true
26
+
27
+ # Enables or disables the cookie message.
28
+ #
29
+ # default: config.enable_cookie_consent_banner = true
30
+ #
31
+ config.enable_cookie_consent_banner = true
32
+
33
+ config.cookies = ->(cookie_store = Cmor::Legal::CookieStore.new({})) {[
34
+ Cmor::Legal::Cookie.new(identifier: :basic, adjustable: false, default: true, cookie_store: cookie_store),
35
+ Cmor::Legal::Cookie.new(identifier: :analytics, adjustable: true, default: true, cookie_store: cookie_store),
36
+ Cmor::Legal::Cookie.new(identifier: :marketing, adjustable: true, default: true, cookie_store: cookie_store),
37
+ Cmor::Legal::Cookie.new(identifier: :social_media, adjustable: true, default: false, cookie_store: cookie_store)
38
+ ]}
39
+
40
+ # Sets the prefix to use for the consent cookies
41
+ #
42
+ # default: config.cookie_prefix = "#{Rails.application.class.name.deconstantize.underscore}-eu_gdpr-"
43
+ #
44
+ config.cookie_prefix = "#{Rails.application.class.name.deconstantize.underscore}-eu_gdpr-"
45
+
46
+ # Sets the cookie storage method. Can be either :session or :cookies
47
+ #
48
+ # default: config.cookie_storage = :cookies
49
+ #
50
+ config.cookie_storage = :cookies
51
+
52
+ # config.personal_data.register('User', log_removals: true, forget_with: :anonymization) do |u|
53
+ # u.attribute(:email, anonymize_with: :scrambler)
54
+ # u.attribute(:firstname, anonymize_with: :scrambler)
55
+ # u.attribute(:lastname, anonymize_with: :scrambler)
56
+ # u.attribute(:last_ip, anonymize_with: :nullifier)
57
+ # u.association(:posts) do |p|
58
+ # p.attribute(:title)
59
+ # p.attribute(:body)
60
+ # p.association(:gallery) do |g|
61
+ # g.attribute(:name)
62
+ # g.association(:pictures) do |p|
63
+ # p.attribute(:title)
64
+ # p.attribute(:asset) { |r| r.base64_encoded_asset }
65
+ # end
66
+ # end
67
+ # end
68
+ # end
69
+ end
@@ -0,0 +1,4 @@
1
+
2
+ localized do
3
+ mount Cmor::Legal::Engine, at: '/backend/cmor-legal-engine'
4
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ # namespace :cmor_legal do
4
+ # desc "Explaining what the task does"
5
+ # task :example do
6
+ # # Task goes here
7
+ # end
8
+ # end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :cmor_legal_privacy_policy, class: Cmor::Legal::PrivacyPolicy do
5
+ locale { I18n.locale }
6
+ end
7
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails_helper"
4
+
5
+ RSpec.describe "/de/backend/juristisches/privacy_policies", type: :feature do
6
+ # let(:resource_class) { EuGdpr::PrivacyPolicy }
7
+ let(:resource_class) { Cmor::Legal::PrivacyPolicy }
8
+ let(:resource) { create(:cmor_legal_privacy_policy) }
9
+ let(:resources) { I18n.available_locales.map { |l| create(:cmor_legal_privacy_policy, locale: l) } }
10
+
11
+ # List
12
+ it { resources; expect(subject).to implement_index_action(self) }
13
+
14
+ # Create
15
+ it {
16
+ expect(subject).to implement_create_action(self)
17
+ .for(resource_class)
18
+ .within_form("#new_privacy_policy") {
19
+ # fill the needed form inputs via capybara here
20
+ #
21
+ # Example:
22
+ #
23
+ # select 'de', from: 'slider[locale]'
24
+ # fill_in 'slider[name]', with: 'My first slider'
25
+ # check 'slider[auto_start]'
26
+ # fill_in 'slider[interval]', with: '3'
27
+ select "en", from: "privacy_policy[locale]"
28
+ fill_in "privacy_policy[title]", with: "Privacy Policy"
29
+ fill_in "privacy_policy[body]", with: "<h1>Privacy Policy</h1>"
30
+ }
31
+ .increasing { Cmor::Legal::PrivacyPolicy.count }.by(1)
32
+ }
33
+
34
+ # Read
35
+ it { expect(subject).to implement_show_action(self).for(resource) }
36
+
37
+ # Update
38
+ it {
39
+ expect(subject).to implement_update_action(self)
40
+ .for(resource)
41
+ .within_form(".edit_privacy_policy") {
42
+ # fill the needed form inputs via capybara here
43
+ #
44
+ # Example:
45
+ #
46
+ # fill_in 'slider[name]', with: 'New name'
47
+ fill_in "privacy_policy[body]", with: "<h1>Privacy Policy (v2.0)</h1>"
48
+ }
49
+ .updating
50
+ .from(resource.attributes)
51
+ .to("body" => "<h1>Privacy Policy (v2.0)</h1>") # Example: .to({ 'name' => 'New name' })
52
+ }
53
+
54
+ # Delete
55
+ it {
56
+ expect(subject).to implement_delete_action(self)
57
+ .for(resource)
58
+ .reducing { resource_class.count }.by(1)
59
+ }
60
+ end