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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +27 -0
- data/Rakefile +21 -0
- data/app/assets/config/manifest.js +2 -0
- data/app/assets/javascripts/cmor/legal/application.js +2 -0
- data/app/assets/javascripts/cmor/legal/application/keep.js +0 -0
- data/app/assets/javascripts/cmor_legal.js +2 -0
- data/app/assets/stylesheets/cmor/legal/application.css +3 -0
- data/app/assets/stylesheets/cmor/legal/application/keep.css +0 -0
- data/app/assets/stylesheets/cmor_legal.css +3 -0
- data/app/builders/cmor/legal/personal_data_hash_builder.rb +50 -0
- data/app/controllers/cmor/legal/home_controller.rb +8 -0
- data/app/controllers/cmor/legal/personal_data_controller.rb +24 -0
- data/app/controllers/cmor/legal/privacy_policies_controller.rb +18 -0
- data/app/models/cmor/legal/cookie.rb +87 -0
- data/app/models/cmor/legal/cookie_preferences.rb +47 -0
- data/app/models/cmor/legal/cookie_store.rb +39 -0
- data/app/models/cmor/legal/personal_data.rb +60 -0
- data/app/models/cmor/legal/privacy_policy.rb +24 -0
- data/app/registries/cmor/legal/personal_data_registry.rb +42 -0
- data/app/resolvers/cmor/legal/privacy_policy_resolver.rb +8 -0
- data/app/view_helpers/cmor/legal/application_view_helper.rb +8 -0
- data/app/views/cmor/legal/home/_index_extras.html.haml +22 -0
- data/app/views/cmor/legal/personal_data/_index_table.haml +1 -0
- data/app/views/cmor/legal/personal_data/_show_extras.haml +1 -0
- data/app/views/cmor/legal/personal_data/_show_table.haml +1 -0
- data/app/views/cmor/legal/privacy_policies/_form.haml +14 -0
- data/app/views/cmor/legal/privacy_policies/_index_table.haml +6 -0
- data/app/views/cmor/legal/privacy_policies/_show_table.html.haml +8 -0
- data/config/initializers/assets.rb +2 -0
- data/config/initializers/cmor.rb +3 -0
- data/config/locales/de.yml +20 -0
- data/config/locales/en.yml +15 -0
- data/config/routes.rb +7 -0
- data/lib/cmor/legal/configuration.rb +64 -0
- data/lib/cmor/legal/engine.rb +7 -0
- data/lib/cmor/legal/version.rb +9 -0
- data/lib/cmor_legal.rb +15 -0
- data/lib/generators/cmor/legal/install/install_generator.rb +26 -0
- data/lib/generators/cmor/legal/install/templates/initializer.rb +69 -0
- data/lib/generators/cmor/legal/install/templates/routes.source +4 -0
- data/lib/tasks/cmor/legal_tasks.rake +8 -0
- data/spec/factories/cmor_legal_privacy_policies.rb +7 -0
- data/spec/features/de/backend/juristisches/privacy_policies_feature_spec.rb +60 -0
- data/spec/lib/cmor/legal/version_spec.rb +7 -0
- data/spec/models/cmor/legal/cookie_spec.rb +63 -0
- data/spec/rails_helper.rb +62 -0
- data/spec/spec_helper.rb +98 -0
- data/spec/support/active_job.rb +3 -0
- data/spec/support/capybara.rb +3 -0
- data/spec/support/factory_bot.rb +16 -0
- data/spec/support/pry.rb +3 -0
- data/spec/support/rao-shoulda_matchers.rb +7 -0
- 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,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> " }.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,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
|
+
|
data/config/routes.rb
ADDED
@@ -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
|
data/lib/cmor_legal.rb
ADDED
@@ -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,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
|