gdpr_rails 0.1.0 → 0.2.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 +4 -4
- data/README.md +270 -13
- data/app/assets/javascripts/policy_manager/application.js +4 -0
- data/app/assets/javascripts/policy_manager/portability_requests.js +2 -0
- data/app/assets/javascripts/policy_manager/user_portability_requests.js +2 -0
- data/app/assets/stylesheets/policy_manager/portability_requests.css +4 -0
- data/app/assets/stylesheets/policy_manager/user_portability_requests.css +4 -0
- data/app/controllers/policy_manager/application_controller.rb +22 -0
- data/app/controllers/policy_manager/categories_controller.rb +5 -47
- data/app/controllers/policy_manager/portability_requests_controller.rb +34 -0
- data/app/controllers/policy_manager/terms_controller.rb +16 -13
- data/app/controllers/policy_manager/user_portability_requests_controller.rb +41 -0
- data/app/controllers/policy_manager/user_terms_controller.rb +68 -28
- data/app/helpers/policy_manager/application_helper.rb +28 -0
- data/app/helpers/policy_manager/portability_requests_helper.rb +4 -0
- data/app/helpers/policy_manager/scripts_helper.rb +11 -0
- data/app/helpers/policy_manager/terms_helper.rb +1 -1
- data/app/helpers/policy_manager/user_portability_requests_helper.rb +4 -0
- data/app/jobs/policy_manager/exporter_job.rb +10 -0
- data/app/mailers/policy_manager/application_mailer.rb +20 -2
- data/app/mailers/policy_manager/portability_mailer.rb +34 -0
- data/app/models/policy_manager/concerns/user_behavior.rb +80 -22
- data/app/models/policy_manager/portability_request.rb +65 -0
- data/app/models/policy_manager/term.rb +18 -0
- data/app/models/policy_manager/user_term.rb +14 -7
- data/app/views/layouts/policy_manager/application.html.erb +41 -39
- data/app/views/layouts/policy_manager/mailer.html.erb +13 -0
- data/app/views/layouts/policy_manager/mailer.text.erb +1 -0
- data/app/views/policy_manager/categories/index.html.erb +6 -12
- data/app/views/policy_manager/categories/show.html.erb +13 -20
- data/app/views/policy_manager/portability_mailer/completed_notification.erb +7 -0
- data/app/views/policy_manager/portability_mailer/progress_notification.erb +3 -0
- data/app/views/policy_manager/portability_requests/index.html.erb +42 -0
- data/app/views/policy_manager/portability_requests/index.json.jbuilder +5 -0
- data/app/views/policy_manager/terms/_form.html.erb +12 -11
- data/app/views/policy_manager/terms/edit.html.erb +6 -4
- data/app/views/policy_manager/terms/index.html.erb +12 -13
- data/app/views/policy_manager/terms/new.html.erb +5 -3
- data/app/views/policy_manager/terms/show.html.erb +12 -10
- data/app/views/policy_manager/user_portability_requests/index.html.erb +42 -0
- data/app/views/policy_manager/user_portability_requests/index.json.jbuilder +5 -0
- data/app/views/policy_manager/user_terms/pending.html.erb +10 -6
- data/app/views/policy_manager/user_terms/show.html.erb +7 -8
- data/app/views/policy_manager/user_terms/show.json.jbuilder +15 -8
- data/config/locales/en.yml +122 -0
- data/config/locales/es.yml +122 -0
- data/config/routes.rb +15 -6
- data/db/migrate/20180326193825_create_policy_manager_terms.rb +1 -0
- data/db/migrate/20180410171354_create_policy_manager_portability_requests.rb +18 -0
- data/lib/policy_manager/anonimizer.rb +18 -0
- data/lib/policy_manager/config.rb +35 -1
- data/lib/policy_manager/exporter/handler.rb +110 -0
- data/lib/policy_manager/exporter/paginator_renderer.rb +74 -0
- data/lib/policy_manager/exporter/view.rb +108 -0
- data/lib/policy_manager/exporter/zip_generator.rb +60 -0
- data/lib/policy_manager/exporter.rb +75 -0
- data/lib/policy_manager/portability_rule.rb +15 -0
- data/lib/policy_manager/rule.rb +21 -4
- data/lib/policy_manager/script.rb +56 -0
- data/lib/policy_manager/templates/index.html.erb +1 -0
- data/lib/policy_manager/version.rb +1 -1
- data/lib/policy_manager.rb +10 -0
- metadata +160 -19
- data/app/controllers/policy_manager/dashboard_controller.rb +0 -6
- data/app/helpers/policy_manager/categories_helper.rb +0 -4
- data/app/helpers/policy_manager/dashboard_helper.rb +0 -4
- data/app/helpers/policy_manager/terms_categories_helper.rb +0 -4
- data/app/views/policy_manager/categories/_form.html.erb +0 -22
- data/app/views/policy_manager/categories/edit.html.erb +0 -6
- data/app/views/policy_manager/categories/new.html.erb +0 -5
- data/app/views/policy_manager/dashboard/index.erb +0 -33
- data/app/views/policy_manager/terms_categories/_form.html.erb +0 -17
- data/app/views/policy_manager/terms_categories/edit.html.erb +0 -6
- data/app/views/policy_manager/terms_categories/index.html.erb +0 -24
- data/app/views/policy_manager/terms_categories/new.html.erb +0 -5
- data/app/views/policy_manager/terms_categories/show.html.erb +0 -4
- data/app/views/policy_manager/user_terms/_form.html.erb +0 -17
- data/app/views/policy_manager/user_terms/edit.html.erb +0 -6
- data/app/views/policy_manager/user_terms/index.html.erb +0 -24
- data/app/views/policy_manager/user_terms/new.html.erb +0 -5
@@ -1,27 +1,40 @@
|
|
1
|
-
require_dependency "
|
2
|
-
|
3
|
-
require "request_store"
|
1
|
+
require_dependency "policy_manager/application_controller"
|
4
2
|
|
5
3
|
module PolicyManager
|
6
4
|
class UserTermsController < ApplicationController
|
5
|
+
|
6
|
+
skip_before_action :user_authenticated?, only: [:show, :accept, :reject, :blocking_terms]
|
7
7
|
before_action :set_user_term, only: [:accept, :reject, :show, :edit, :update, :destroy]
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
# GET /user_terms/1
|
10
|
+
def show
|
11
|
+
@user_term = current_user.present? ? current_user.handle_policy_for(@term) : UserTerm.new(term: @term, user: nil, state: cookies["policy_rule_#{@term.rule.name}"])
|
11
12
|
end
|
12
13
|
|
13
|
-
# GET /
|
14
|
-
def
|
15
|
-
@
|
14
|
+
# GET /pending
|
15
|
+
def pending
|
16
|
+
@pending_policies = current_user.pending_policies
|
17
|
+
respond_to do |format|
|
18
|
+
format.html{ }
|
19
|
+
format.json{ render json: @pending_policies }
|
20
|
+
end
|
16
21
|
end
|
17
22
|
|
18
|
-
# GET /
|
19
|
-
def
|
20
|
-
|
23
|
+
# GET /blocking_terms
|
24
|
+
def blocking_terms
|
25
|
+
respond_to do |format|
|
26
|
+
format.html{ }
|
27
|
+
format.json{ render json: PolicyManager::Config.rules.map{|p| p.name if p.blocking == true }.compact! }
|
28
|
+
end
|
21
29
|
end
|
22
30
|
|
23
|
-
def
|
31
|
+
def accept_multiples
|
32
|
+
rules = current_user.pending_policies.map{|o| "policy_rule_#{o.name}"}
|
33
|
+
resource_params = params.require(:user).permit(rules)
|
34
|
+
current_user.update_attributes(resource_params)
|
35
|
+
|
24
36
|
@pending_policies = current_user.pending_policies
|
37
|
+
|
25
38
|
respond_to do |format|
|
26
39
|
format.html{ }
|
27
40
|
format.json{ render json: @pending_policies }
|
@@ -29,8 +42,9 @@ module PolicyManager
|
|
29
42
|
end
|
30
43
|
|
31
44
|
def accept
|
32
|
-
|
33
|
-
|
45
|
+
|
46
|
+
handle_term_accept
|
47
|
+
|
34
48
|
respond_to do |format|
|
35
49
|
format.html{
|
36
50
|
if @user_term.errors.any?
|
@@ -40,13 +54,18 @@ module PolicyManager
|
|
40
54
|
end
|
41
55
|
}
|
42
56
|
format.js
|
43
|
-
format.json
|
57
|
+
format.json{
|
58
|
+
render json: {
|
59
|
+
status: @user_term ? @user_term.state : cookies["policy_rule_#{@term.rule.name}"]
|
60
|
+
}
|
61
|
+
}
|
44
62
|
end
|
45
63
|
end
|
46
64
|
|
47
65
|
def reject
|
48
|
-
|
49
|
-
|
66
|
+
|
67
|
+
handle_term_reject
|
68
|
+
|
50
69
|
respond_to do |format|
|
51
70
|
format.html{
|
52
71
|
if @user_term.errors.any?
|
@@ -57,13 +76,13 @@ module PolicyManager
|
|
57
76
|
}
|
58
77
|
format.js
|
59
78
|
format.json{
|
60
|
-
|
61
|
-
|
62
|
-
render :json, url: root_url , notice: "hey there are some errors! #{@user_term.errors.full_messages.join()}"
|
79
|
+
if @user_term.present? && @user_term.errors.any?
|
80
|
+
render json: { url: root_url , notice: "hey there are some errors! #{@user_term.errors.full_messages.join()}" }
|
63
81
|
else
|
64
|
-
render
|
82
|
+
render json: {
|
83
|
+
state: @user_term ? @user_term.state : cookies["policy_rule_#{@term.rule.name}"]
|
84
|
+
}
|
65
85
|
end
|
66
|
-
|
67
86
|
}
|
68
87
|
end
|
69
88
|
end
|
@@ -73,10 +92,6 @@ module PolicyManager
|
|
73
92
|
@user_term = UserTerm.new
|
74
93
|
end
|
75
94
|
|
76
|
-
# GET /user_terms/1/edit
|
77
|
-
def edit
|
78
|
-
end
|
79
|
-
|
80
95
|
# POST /user_terms
|
81
96
|
def create
|
82
97
|
@user_term = UserTerm.new(user_term_params)
|
@@ -104,11 +119,36 @@ module PolicyManager
|
|
104
119
|
end
|
105
120
|
|
106
121
|
private
|
122
|
+
|
123
|
+
def handle_term_accept
|
124
|
+
if current_user
|
125
|
+
@user_term = current_user.handle_policy_for(@term)
|
126
|
+
if @user_term.accept!
|
127
|
+
@term.rule.on_accept.call(self) if @term.rule.on_accept.is_a?(Proc)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
cookies["policy_rule_#{@term.rule.name}"] = {
|
132
|
+
:value => "accepted",
|
133
|
+
:expires => 1.year.from_now
|
134
|
+
}
|
135
|
+
end
|
136
|
+
|
137
|
+
def handle_term_reject
|
138
|
+
if current_user
|
139
|
+
@user_term = current_user.handle_policy_for(@term)
|
140
|
+
if @user_term.reject!
|
141
|
+
@term.rule.on_reject.call(self) if @term.rule.on_reject.is_a?(Proc)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
cookies.delete("policy_rule_#{@term.rule.name}")
|
146
|
+
end
|
147
|
+
|
107
148
|
# Use callbacks to share common setup or constraints between actions.
|
108
149
|
def set_user_term
|
109
|
-
@category =
|
150
|
+
@category = PolicyManager::Config.rules.find{|o| o.name == params[:id]}
|
110
151
|
@term = @category.terms.last
|
111
|
-
#@term = Term.find(params[:id])
|
112
152
|
end
|
113
153
|
|
114
154
|
# Only allow a trusted parameter "white list" through.
|
@@ -1,4 +1,32 @@
|
|
1
1
|
module PolicyManager
|
2
2
|
module ApplicationHelper
|
3
|
+
|
4
|
+
def bootstrap_class_for flash_type
|
5
|
+
{ success: "alert-success", error: "alert-danger", alert: "alert-warning", notice: "alert-info" }[flash_type.to_sym] || flash_type.to_s
|
6
|
+
end
|
7
|
+
|
8
|
+
def flash_messages(opts = {})
|
9
|
+
|
10
|
+
flash.each do |msg_type, message|
|
11
|
+
flash.delete(msg_type)
|
12
|
+
concat(content_tag(:div, message, class: "alert #{bootstrap_class_for(msg_type)}") do
|
13
|
+
concat content_tag(:button, "<i class='fa fa-times-circle'></i>".html_safe, class: "close", data: { dismiss: 'alert' })
|
14
|
+
concat message
|
15
|
+
end)
|
16
|
+
end
|
17
|
+
|
18
|
+
session.delete(:flash)
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
def chart(data)
|
24
|
+
begin
|
25
|
+
column_chart(data.call)
|
26
|
+
rescue Groupdate::Error
|
27
|
+
content_tag(:p, "chart not displayed, Be sure to install time zone support - https://github.com/ankane/groupdate#for-mysql", class: "alert alert-danger")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
3
31
|
end
|
4
32
|
end
|
@@ -1,6 +1,24 @@
|
|
1
1
|
module PolicyManager
|
2
2
|
class ApplicationMailer < ActionMailer::Base
|
3
|
-
default from:
|
3
|
+
default from: Config.from_email
|
4
4
|
layout 'mailer'
|
5
|
+
|
6
|
+
# configurable mailer helpers
|
7
|
+
Config.exporter.mail_helpers.each do |helpers|
|
8
|
+
add_template_helper(helpers)
|
9
|
+
end
|
10
|
+
|
11
|
+
def send!(opts = {})
|
12
|
+
|
13
|
+
I18n.locale = Config.user_language(@user)
|
14
|
+
|
15
|
+
default_opts = {
|
16
|
+
:to => @user.email,
|
17
|
+
:subject => @subject
|
18
|
+
}.merge(opts)
|
19
|
+
|
20
|
+
mail(default_opts)
|
21
|
+
end
|
22
|
+
|
5
23
|
end
|
6
|
-
end
|
24
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module PolicyManager
|
2
|
+
class PortabilityMailer < ApplicationMailer
|
3
|
+
|
4
|
+
def progress_notification(portability_request_id)
|
5
|
+
@portability_request = PortabilityRequest.find(portability_request_id)
|
6
|
+
@user = User.find(@portability_request.user_id)
|
7
|
+
@subject = I18n.t("terms_app.mails.progress.subject")
|
8
|
+
|
9
|
+
opts = {}
|
10
|
+
opts.merge!({
|
11
|
+
template_path: PolicyManager::Config.exporter.mailer_templates[:path].to_s,
|
12
|
+
template_name: PolicyManager::Config.exporter.mailer_templates[:progress]
|
13
|
+
}) if PolicyManager::Config.exporter.mailer_templates.present?
|
14
|
+
|
15
|
+
send!(opts)
|
16
|
+
end
|
17
|
+
|
18
|
+
def completed_notification(portability_request_id)
|
19
|
+
@portability_request = PortabilityRequest.find(portability_request_id)
|
20
|
+
@user = User.find(@portability_request.user_id)
|
21
|
+
@subject = I18n.t("terms_app.mails.completed.subject")
|
22
|
+
@link = @portability_request.download_link
|
23
|
+
|
24
|
+
opts = {}
|
25
|
+
opts.merge!({
|
26
|
+
template_path: PolicyManager::Config.exporter.mailer_templates[:path].to_s,
|
27
|
+
template_name: PolicyManager::Config.exporter.mailer_templates[:complete]
|
28
|
+
}) if PolicyManager::Config.exporter.mailer_templates.present?
|
29
|
+
|
30
|
+
send!(opts)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -3,8 +3,73 @@ module PolicyManager::Concerns::UserBehavior
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
included do
|
6
|
-
has_many :user_terms, class_name: "PolicyManager::UserTerm"
|
6
|
+
has_many :user_terms, class_name: "PolicyManager::UserTerm", autosave: true
|
7
7
|
has_many :terms, through: :user_terms
|
8
|
+
has_many :portability_requests, class_name: "PolicyManager::PortabilityRequest"
|
9
|
+
|
10
|
+
# adds policies
|
11
|
+
PolicyManager::Config.rules.each do |rule|
|
12
|
+
# next if rule. !internal?
|
13
|
+
rule_name = "policy_rule_#{rule.name}".to_sym
|
14
|
+
attr_accessor rule_name
|
15
|
+
|
16
|
+
if rule.validates_on
|
17
|
+
|
18
|
+
validate :"check_#{rule_name}", :on => rule.validates_on, :if => ->(o){
|
19
|
+
return true if rule.if.nil?
|
20
|
+
rule.if.call(o) rescue true
|
21
|
+
}
|
22
|
+
|
23
|
+
define_method :"check_#{rule_name}" do
|
24
|
+
if self.send(rule_name).blank? && needs_policy_confirmation_for?(rule.name)
|
25
|
+
errors.add(rule_name, "needs confirmation")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
define_method :"has_consented_#{rule.name}?" do
|
31
|
+
!needs_policy_confirmation_for?(rule.name)
|
32
|
+
end
|
33
|
+
|
34
|
+
define_method :"#{rule_name}=" do |val=true|
|
35
|
+
self.instance_variable_set("@#{rule_name}", val)
|
36
|
+
ut = user_terms.new
|
37
|
+
ut.term = policy_term_on(rule.name)
|
38
|
+
val ? ut.accept : ut.reject
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# adds portability rules
|
43
|
+
PolicyManager::Config.portability_rules.each do |rule|
|
44
|
+
if rule.collection
|
45
|
+
define_method :"portability_collection_#{rule.name}" do |page=1|
|
46
|
+
portability_collection_for(rule, page)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
if rule.member
|
51
|
+
define_method :"portability_member_#{rule.name}" do
|
52
|
+
portability_member_for(rule)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def
|
59
|
+
|
60
|
+
def portability_schema
|
61
|
+
PolicyManager::Config.portability_rules.map(&:name)
|
62
|
+
end
|
63
|
+
|
64
|
+
def portability_member_for(rule)
|
65
|
+
self.send(rule.member)
|
66
|
+
end
|
67
|
+
|
68
|
+
def portability_collection_for(rule, page)
|
69
|
+
# if kaminari
|
70
|
+
# self.send(rule.collection).page(1)
|
71
|
+
# if will paginate
|
72
|
+
self.send(rule.collection).paginate(page: page, per_page: rule.per)
|
8
73
|
end
|
9
74
|
|
10
75
|
def pending_policies
|
@@ -15,6 +80,12 @@ module PolicyManager::Concerns::UserBehavior
|
|
15
80
|
end
|
16
81
|
end
|
17
82
|
|
83
|
+
def pending_blocking_policies
|
84
|
+
PolicyManager::Config.rules.select do |c|
|
85
|
+
c.blocking && self.needs_policy_confirmation_for?(c.name)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
18
89
|
def confirm_all_policies!
|
19
90
|
peding_policies.each do |c|
|
20
91
|
term = c.terms.last
|
@@ -31,27 +102,20 @@ module PolicyManager::Concerns::UserBehavior
|
|
31
102
|
|
32
103
|
def needs_policy_confirmation_for?(rule)
|
33
104
|
term = policy_term_on(rule)
|
34
|
-
user_term = policy_user_term_on(
|
35
|
-
return false if term.blank?
|
105
|
+
user_term = policy_user_term_on(term)
|
36
106
|
return true if user_term.blank?
|
107
|
+
return true if user_term.rejected?
|
37
108
|
term.created_at > user_term.created_at
|
38
109
|
end
|
39
110
|
|
40
|
-
def is_confirmed?
|
41
|
-
end
|
42
|
-
|
43
|
-
def block_feature?
|
44
|
-
end
|
45
|
-
|
46
111
|
def policy_term_on(rule)
|
47
112
|
category = PolicyManager::Config.rules.find{|o| o.name == rule}
|
48
|
-
term = category.terms.last
|
49
|
-
|
113
|
+
term = category.terms.where(state: "published").last
|
114
|
+
raise "no term for #{rule} policy" if term.blank?
|
50
115
|
term
|
51
116
|
end
|
52
117
|
|
53
|
-
def policy_user_term_on(
|
54
|
-
term = policy_term_on(rule)
|
118
|
+
def policy_user_term_on(term)
|
55
119
|
return if term.blank?
|
56
120
|
self.user_terms.where(term_id: term.id).first
|
57
121
|
end
|
@@ -62,14 +126,8 @@ module PolicyManager::Concerns::UserBehavior
|
|
62
126
|
end
|
63
127
|
end
|
64
128
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
#######
|
69
|
-
|
70
|
-
|
71
|
-
#######
|
72
|
-
## DATA FOGOTTABILITY
|
73
|
-
#######
|
129
|
+
def can_request_portability?
|
130
|
+
self.portability_requests.select{|p| p.pending? || p.progress?}.blank?
|
131
|
+
end
|
74
132
|
|
75
133
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require "paperclip"
|
2
|
+
require "aasm"
|
3
|
+
|
4
|
+
module PolicyManager
|
5
|
+
class PortabilityRequest < ApplicationRecord
|
6
|
+
include Paperclip::Glue
|
7
|
+
|
8
|
+
belongs_to :user
|
9
|
+
|
10
|
+
has_attached_file :attachment,
|
11
|
+
path: Config.exporter.try(:attachment_path) || Rails.root.join("tmp/portability/:id/build.zip").to_s,
|
12
|
+
storage: Config.exporter.try(:attachment_storage) || :filesystem,
|
13
|
+
s3_permissions: :private
|
14
|
+
|
15
|
+
do_not_validate_attachment_file_type :attachment
|
16
|
+
|
17
|
+
include AASM
|
18
|
+
|
19
|
+
aasm column: :state do
|
20
|
+
state :pending, :initial => true
|
21
|
+
state :progress, :after_enter => :handle_progress
|
22
|
+
state :completed, :after_enter => :notify_completeness
|
23
|
+
|
24
|
+
event :confirm do
|
25
|
+
transitions from: :pending, to: :progress
|
26
|
+
end
|
27
|
+
|
28
|
+
event :complete do
|
29
|
+
transitions from: :progress, to: :completed
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def user_email
|
34
|
+
self.user.email
|
35
|
+
end
|
36
|
+
|
37
|
+
def file_remote_url=(url_value)
|
38
|
+
self.attachment = File.open(url_value) unless url_value.blank?
|
39
|
+
self.save
|
40
|
+
self.complete!
|
41
|
+
end
|
42
|
+
|
43
|
+
def download_link
|
44
|
+
self.attachment.expiring_url(PolicyManager::Config.exporter.expiration_link)
|
45
|
+
end
|
46
|
+
|
47
|
+
def handle_progress
|
48
|
+
notify_progress
|
49
|
+
perform_job
|
50
|
+
end
|
51
|
+
|
52
|
+
def perform_job
|
53
|
+
ExporterJob.set(queue: :default).perform_later(self.user.id)
|
54
|
+
end
|
55
|
+
|
56
|
+
def notify_progress
|
57
|
+
PortabilityMailer.progress_notification(self.id).deliver_now
|
58
|
+
end
|
59
|
+
|
60
|
+
def notify_completeness
|
61
|
+
PortabilityMailer.completed_notification(self.id).deliver_now
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
@@ -1,9 +1,27 @@
|
|
1
1
|
require "redcarpet"
|
2
|
+
require "aasm"
|
2
3
|
|
3
4
|
module PolicyManager
|
4
5
|
class Term < ApplicationRecord
|
6
|
+
include AASM
|
5
7
|
|
6
8
|
validates_presence_of :rule
|
9
|
+
validates_presence_of :description
|
10
|
+
validates_presence_of :state
|
11
|
+
|
12
|
+
aasm :column => :state do
|
13
|
+
state :draft, :initial => true # db column's default
|
14
|
+
state :published
|
15
|
+
|
16
|
+
event :publish do
|
17
|
+
transitions from: :draft, to: :published
|
18
|
+
end
|
19
|
+
|
20
|
+
event :unpublish do
|
21
|
+
transitions from: :published, to: :draft
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
7
25
|
|
8
26
|
def self.renderer
|
9
27
|
@markdown = markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, autolink: true, tables: true)
|
@@ -1,18 +1,25 @@
|
|
1
|
+
require "aasm"
|
2
|
+
|
1
3
|
module PolicyManager
|
2
4
|
class UserTerm < ApplicationRecord
|
5
|
+
include AASM
|
6
|
+
|
3
7
|
belongs_to :user
|
4
8
|
belongs_to :term
|
5
9
|
|
6
10
|
validates_uniqueness_of :term_id, :scope => :user_id
|
7
11
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
+
aasm :column => :state do
|
13
|
+
state :rejected, :initial => true
|
14
|
+
state :accepted
|
15
|
+
|
16
|
+
event :accept do
|
17
|
+
transitions from: :rejected, to: :accepted
|
18
|
+
end
|
12
19
|
|
13
|
-
|
14
|
-
|
15
|
-
|
20
|
+
event :reject do
|
21
|
+
transitions from: :accepted, to: :rejected
|
22
|
+
end
|
16
23
|
end
|
17
24
|
|
18
25
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<!DOCTYPE html>
|
2
2
|
<html>
|
3
3
|
<head>
|
4
|
-
<title
|
4
|
+
<title><%= I18n.t("terms_app.title") %></title>
|
5
5
|
|
6
6
|
<%= csrf_meta_tags %>
|
7
7
|
|
@@ -15,77 +15,79 @@
|
|
15
15
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.css">
|
16
16
|
<script src="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.js"></script>
|
17
17
|
|
18
|
-
|
19
|
-
|
18
|
+
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.10/css/all.css" integrity="sha384-+d0P83n9kaQMCwj8F4RJB66tzIwOKmrdb46+porD/OvrJ+37WqIM7UoBtwHO6Nlg" crossorigin="anonymous">
|
19
|
+
|
20
|
+
<%= javascript_include_tag "https://www.gstatic.com/charts/loader.js" %>
|
21
|
+
<%= stylesheet_link_tag "policy_manager/application", media: "all" %>
|
22
|
+
<%= javascript_include_tag "policy_manager/application", debug: false %>
|
20
23
|
|
21
24
|
</head>
|
22
25
|
<body>
|
23
26
|
|
24
27
|
<nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0">
|
25
|
-
<a class="navbar-brand col-sm-3 col-md-2 mr-0" href="
|
26
|
-
|
28
|
+
<a class="navbar-brand col-sm-3 col-md-2 mr-0" href="/">
|
29
|
+
<%= I18n.t("terms_app.sub_title") %></a>
|
27
30
|
<ul class="navbar-nav px-3">
|
28
31
|
<li class="nav-item text-nowrap">
|
29
|
-
|
32
|
+
<% if PolicyManager::Config.logout_url.present? %>
|
33
|
+
<a class="nav-link" href="<%= PolicyManager::Config.logout_url %>"><%= I18n.t("terms_app.sign_out") %></a>
|
34
|
+
<% end %>
|
30
35
|
</li>
|
31
36
|
</ul>
|
32
37
|
</nav>
|
33
38
|
|
34
39
|
<div class="container-fluid">
|
35
|
-
|
36
|
-
|
37
40
|
<div class="row">
|
38
41
|
<nav class="col-md-2 d-none d-md-block bg-light sidebar">
|
39
42
|
<div class="sidebar-sticky">
|
40
43
|
<ul class="nav flex-column">
|
44
|
+
<% if PolicyManager::Config.is_admin?(current_user) %>
|
45
|
+
<li class="nav-item">
|
46
|
+
<a class="nav-link" href="<%= categories_path %>">
|
47
|
+
<i class="fas fa-balance-scale"></i>
|
48
|
+
<%= I18n.t("terms_app.menu.policies") %>
|
49
|
+
</a>
|
50
|
+
</li>
|
51
|
+
<% end %>
|
52
|
+
|
53
|
+
|
54
|
+
<% if PolicyManager::Config.is_admin?(current_user) %>
|
55
|
+
<li class="nav-item">
|
56
|
+
<a class="nav-link" href="<%= portability_requests_path %>">
|
57
|
+
<i class="fas fa-suitcase"></i>
|
58
|
+
<%= I18n.t("terms_app.menu.portability_requests") %>
|
59
|
+
</a>
|
60
|
+
</li>
|
61
|
+
<% end %>
|
62
|
+
|
63
|
+
<li class="separator"></li>
|
64
|
+
|
41
65
|
<li class="nav-item">
|
42
|
-
<a class="nav-link
|
43
|
-
<
|
44
|
-
|
66
|
+
<a class="nav-link" href="<%= pending_user_terms_path %>">
|
67
|
+
<i class="fas fa-user-secret"></i>
|
68
|
+
<%= I18n.t("terms_app.menu.user_pending_policies") %>
|
45
69
|
</a>
|
46
70
|
</li>
|
71
|
+
|
47
72
|
<li class="nav-item">
|
48
|
-
<a class="nav-link" href="<%=
|
49
|
-
<
|
50
|
-
|
51
|
-
</a>
|
52
|
-
</li>
|
53
|
-
|
54
|
-
|
55
|
-
<li class="nav-item">
|
56
|
-
<a class="nav-link" href="<%= pending_user_terms_path %>">
|
57
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file"><path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path><polyline points="13 2 13 9 20 9"></polyline></svg>
|
58
|
-
user's pending policies
|
73
|
+
<a class="nav-link" href="<%= user_portability_requests_path %>">
|
74
|
+
<i class="fas fa-suitcase"></i>
|
75
|
+
<%= I18n.t("terms_app.menu.user_portability_requests") %>
|
59
76
|
</a>
|
60
77
|
</li>
|
78
|
+
|
61
79
|
</ul>
|
62
80
|
|
63
81
|
</div>
|
64
82
|
</nav>
|
65
83
|
|
66
84
|
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
|
67
|
-
|
68
|
-
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pb-2 mb-3 border-bottom">
|
69
|
-
<h1 class="h2">Policies</h1>
|
70
|
-
<div class="btn-toolbar mb-2 mb-md-0">
|
71
|
-
<div class="btn-group mr-2">
|
72
|
-
<button class="btn btn-sm btn-outline-secondary">Share</button>
|
73
|
-
<button class="btn btn-sm btn-outline-secondary">Export</button>
|
74
|
-
</div>
|
75
|
-
</div>
|
76
|
-
</div>
|
77
|
-
|
78
85
|
<p id="notice">
|
79
|
-
<%=
|
86
|
+
<%= flash_messages %>
|
80
87
|
</p>
|
81
|
-
|
82
88
|
<%= yield %>
|
83
89
|
</main>
|
84
90
|
</div>
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
91
|
</div>
|
90
92
|
|
91
93
|
</body>
|