gdpr_rails 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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>
|