decidim-initiatives 0.16.1 → 0.17.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/decidim/initiatives/scoped_type.js +13 -10
- data/app/assets/stylesheet/decidim/initiatives/initiatives-votes.css.scss +97 -0
- data/app/cells/decidim/initiatives/initiative_m_cell.rb +1 -1
- data/app/cells/decidim/initiatives_votes/vote/show.erb +29 -0
- data/app/cells/decidim/initiatives_votes/vote_cell.rb +51 -0
- data/app/commands/decidim/initiatives/admin/create_initiative_type.rb +8 -1
- data/app/commands/decidim/initiatives/admin/update_initiative.rb +7 -6
- data/app/commands/decidim/initiatives/admin/update_initiative_answer.rb +76 -0
- data/app/commands/decidim/initiatives/admin/update_initiative_type.rb +17 -1
- data/app/commands/decidim/initiatives/create_initiative.rb +12 -0
- data/app/commands/decidim/initiatives/spawn_committee_request.rb +8 -7
- data/app/commands/decidim/initiatives/validate_mobile_phone.rb +61 -0
- data/app/commands/decidim/initiatives/validate_sms_code.rb +40 -0
- data/app/commands/decidim/initiatives/vote_initiative.rb +23 -7
- data/app/controllers/concerns/decidim/initiatives/needs_initiative.rb +12 -1
- data/app/controllers/decidim/initiatives/admin/answers_controller.rb +46 -0
- data/app/controllers/decidim/initiatives/admin/initiatives_controller.rb +31 -5
- data/app/controllers/decidim/initiatives/admin/initiatives_types_controller.rb +1 -0
- data/app/controllers/decidim/initiatives/admin/initiatives_types_permissions_controller.rb +20 -0
- data/app/controllers/decidim/initiatives/admin/moderations_controller.rb +16 -0
- data/app/controllers/decidim/initiatives/application_controller.rb +0 -2
- data/app/controllers/decidim/initiatives/authorization_sign_modals_controller.rb +26 -0
- data/app/controllers/decidim/initiatives/committee_requests_controller.rb +4 -1
- data/app/controllers/decidim/initiatives/create_initiative_controller.rb +16 -5
- data/app/controllers/decidim/initiatives/initiative_signatures_controller.rb +207 -0
- data/app/controllers/decidim/initiatives/initiative_votes_controller.rb +3 -1
- data/app/controllers/decidim/initiatives/initiatives_type_signature_types_controller.rb +21 -0
- data/app/forms/decidim/initiatives/admin/initiative_answer_form.rb +29 -0
- data/app/forms/decidim/initiatives/admin/initiative_form.rb +25 -7
- data/app/forms/decidim/initiatives/admin/initiative_type_form.rb +14 -0
- data/app/forms/decidim/initiatives/committee_member_form.rb +30 -0
- data/app/forms/decidim/initiatives/initiative_form.rb +5 -0
- data/app/forms/decidim/initiatives/vote_form.rb +151 -0
- data/app/helpers/decidim/initiatives/create_initiative_helper.rb +25 -12
- data/app/helpers/decidim/initiatives/initiative_helper.rb +18 -0
- data/app/models/decidim/initiative.rb +54 -3
- data/app/models/decidim/initiatives_committee_member.rb +1 -0
- data/app/models/decidim/initiatives_type.rb +30 -0
- data/app/permissions/decidim/initiatives/admin/permissions.rb +12 -3
- data/app/permissions/decidim/initiatives/permissions.rb +37 -8
- data/app/queries/decidim/initiatives/admin/admin_users.rb +39 -0
- data/app/services/decidim/initiatives/data_encryptor.rb +26 -0
- data/app/services/decidim/initiatives/dummy_timestamp.rb +22 -0
- data/app/services/decidim/initiatives/pdf_signature_example.rb +121 -0
- data/app/views/decidim/initiatives/admin/answers/_info_initiative.html.erb +23 -0
- data/app/views/decidim/initiatives/admin/answers/edit.html.erb +35 -0
- data/app/views/decidim/initiatives/admin/initiatives/_form.html.erb +17 -16
- data/app/views/decidim/initiatives/admin/initiatives/edit.html.erb +10 -3
- data/app/views/decidim/initiatives/admin/initiatives/export_pdf_signatures.pdf.erb +35 -0
- data/app/views/decidim/initiatives/admin/initiatives/index.html.erb +6 -0
- data/app/views/decidim/initiatives/admin/initiatives_types/_form.html.erb +36 -0
- data/app/views/decidim/initiatives/admin/initiatives_types/index.html.erb +2 -0
- data/app/views/decidim/initiatives/create_initiative/fill_data.html.erb +3 -3
- data/app/views/decidim/initiatives/create_initiative/finish.html.erb +2 -2
- data/app/views/decidim/initiatives/create_initiative/previous_form.html.erb +2 -2
- data/app/views/decidim/initiatives/create_initiative/promotal_committee.html.erb +3 -3
- data/app/views/decidim/initiatives/create_initiative/select_initiative_type.html.erb +37 -22
- data/app/views/decidim/initiatives/initiative_signatures/_wizard_steps.html.erb +19 -0
- data/app/views/decidim/initiatives/initiative_signatures/fill_personal_data.html.erb +43 -0
- data/app/views/decidim/initiatives/initiative_signatures/finish.html.erb +17 -0
- data/app/views/decidim/initiatives/initiative_signatures/sms_code.html.erb +22 -0
- data/app/views/decidim/initiatives/initiative_signatures/sms_phone_number.html.erb +22 -0
- data/app/views/decidim/initiatives/initiative_signatures/update_buttons_and_counters.js.erb +21 -0
- data/app/views/decidim/initiatives/initiative_votes/update_buttons_and_counters.js.erb +1 -1
- data/app/views/decidim/initiatives/initiatives/_author.html.erb +1 -1
- data/app/views/decidim/initiatives/initiatives/_interactions.html.erb +11 -0
- data/app/views/decidim/initiatives/initiatives/_progress_bar.html.erb +9 -0
- data/app/views/decidim/initiatives/initiatives/_result.html.erb +3 -3
- data/app/views/decidim/initiatives/initiatives/_vote_button.html.erb +39 -18
- data/app/views/decidim/initiatives/initiatives/_vote_cabin.html.erb +9 -9
- data/app/views/decidim/initiatives/initiatives/show.html.erb +12 -12
- data/app/views/decidim/initiatives/initiatives/signature_identities.html.erb +19 -9
- data/app/views/decidim/initiatives/initiatives_type_signature_types/search.html.erb +1 -0
- data/app/views/layouts/decidim/_initiative_creation_header.html.erb +24 -34
- data/app/views/layouts/decidim/_initiative_signature_creation_header.html.erb +27 -0
- data/app/views/layouts/decidim/admin/initiative.html.erb +22 -15
- data/app/views/layouts/decidim/admin/initiatives_votes.pdf.erb +11 -0
- data/app/views/layouts/decidim/initiative_creation.html.erb +15 -3
- data/app/views/layouts/decidim/initiative_signature_creation.html.erb +12 -0
- data/config/initializers/wicked_pdf.rb +23 -0
- data/config/locales/ar-SA.yml +138 -7
- data/config/locales/ca.yml +120 -28
- data/config/locales/cs-CZ.yml +103 -9
- data/config/locales/cs.yml +494 -0
- data/config/locales/de.yml +101 -9
- data/config/locales/en.yml +133 -40
- data/config/locales/es-MX.yml +101 -9
- data/config/locales/es-PY.yml +101 -9
- data/config/locales/es.yml +124 -32
- data/config/locales/eu.yml +101 -9
- data/config/locales/fi-pl.yml +101 -9
- data/config/locales/fi-plain.yml +478 -0
- data/config/locales/fi.yml +117 -25
- data/config/locales/fr.yml +102 -10
- data/config/locales/gl.yml +101 -9
- data/config/locales/hu.yml +102 -10
- data/config/locales/id-ID.yml +100 -9
- data/config/locales/it.yml +101 -9
- data/config/locales/nl.yml +101 -9
- data/config/locales/pl.yml +104 -10
- data/config/locales/pt-BR.yml +101 -9
- data/config/locales/pt.yml +101 -9
- data/config/locales/ru.yml +4 -9
- data/config/locales/sv.yml +101 -9
- data/config/locales/tr-TR.yml +101 -9
- data/config/locales/uk.yml +4 -9
- data/db/migrate/20181212154456_add_collect_extra_user_fields_to_initiatives_types.rb +7 -0
- data/db/migrate/20181212155125_add_online_signature_enabled_to_initiative_type.rb +7 -0
- data/db/migrate/20181212155740_add_extra_fields_legal_information_to_initiatives_types.rb +7 -0
- data/db/migrate/20181213184712_add_min_committee_members_to_initiative_type.rb +7 -0
- data/db/migrate/20181220134322_add_encrypted_metadata_to_decidim_initiatives_votes.rb +7 -0
- data/db/migrate/20181224100803_add_timestamp_to_decidim_initiatives_votes.rb +7 -0
- data/db/migrate/20181224101041_add_hash_id_to_decidim_initiatives_votes.rb +7 -0
- data/db/migrate/20190124170442_add_validate_sms_code_on_votes_to_initiatives_types.rb +7 -0
- data/db/migrate/20190125131847_add_document_number_authorization_handler_to_initiatives_types.rb +7 -0
- data/db/migrate/20190213184301_add_undo_online_signatures_enabled_to_initiatives_types.rb +7 -0
- data/lib/decidim/initiatives.rb +12 -0
- data/lib/decidim/initiatives/admin_engine.rb +12 -0
- data/lib/decidim/initiatives/engine.rb +3 -0
- data/lib/decidim/initiatives/participatory_space.rb +6 -1
- data/lib/decidim/initiatives/test/factories.rb +39 -0
- data/lib/decidim/initiatives/version.rb +1 -1
- metadata +115 -14
- data/app/views/decidim/initiatives/initiatives/_statistics.html.erb +0 -21
- data/app/views/decidim/initiatives/initiatives/_votes_count.html.erb +0 -12
@@ -4,22 +4,16 @@ module Decidim
|
|
4
4
|
module Initiatives
|
5
5
|
# Helper methods for the create initiative wizard.
|
6
6
|
module CreateInitiativeHelper
|
7
|
-
def signature_type_options
|
7
|
+
def signature_type_options(initiative_form)
|
8
|
+
return all_signature_type_options unless initiative_form.signature_type_updatable?
|
8
9
|
return online_signature_type_options unless Decidim::Initiatives.face_to_face_voting_allowed
|
9
|
-
return offline_signature_type_options unless
|
10
|
+
return offline_signature_type_options unless online_signature_allowed?(initiative_form)
|
10
11
|
|
11
|
-
|
12
|
-
Initiative.signature_types.each_key do |type|
|
13
|
-
options << [
|
14
|
-
I18n.t(
|
15
|
-
type,
|
16
|
-
scope: %w(activemodel attributes initiative signature_type_values)
|
17
|
-
), type
|
18
|
-
]
|
19
|
-
end
|
20
|
-
options
|
12
|
+
all_signature_type_options
|
21
13
|
end
|
22
14
|
|
15
|
+
private
|
16
|
+
|
23
17
|
def online_signature_type_options
|
24
18
|
[
|
25
19
|
[
|
@@ -41,6 +35,25 @@ module Decidim
|
|
41
35
|
]
|
42
36
|
]
|
43
37
|
end
|
38
|
+
|
39
|
+
def all_signature_type_options
|
40
|
+
Initiative.signature_types.keys.map do |type|
|
41
|
+
[
|
42
|
+
I18n.t(
|
43
|
+
type,
|
44
|
+
scope: %w(activemodel attributes initiative signature_type_values)
|
45
|
+
), type
|
46
|
+
]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def online_signature_allowed?(initiative_form)
|
51
|
+
Decidim::Initiatives.online_voting_allowed && online_signature_enabled_in_type?(initiative_form)
|
52
|
+
end
|
53
|
+
|
54
|
+
def online_signature_enabled_in_type?(initiative_form)
|
55
|
+
::Decidim::InitiativesType.find(initiative_form.type_id).online_signature_enabled
|
56
|
+
end
|
44
57
|
end
|
45
58
|
end
|
46
59
|
end
|
@@ -79,6 +79,24 @@ module Decidim
|
|
79
79
|
def popularity_level5?(initiative)
|
80
80
|
initiative.percentage >= 100
|
81
81
|
end
|
82
|
+
|
83
|
+
def authorized_vote_modal_button(initiative, html_options, &block)
|
84
|
+
return if current_user && action_authorized_to("vote", resource: initiative, permissions_holder: initiative.type).ok?
|
85
|
+
|
86
|
+
tag = "button"
|
87
|
+
html_options ||= {}
|
88
|
+
|
89
|
+
if !current_user
|
90
|
+
html_options["data-open"] = "loginModal"
|
91
|
+
else
|
92
|
+
html_options["data-open"] = "authorizationModal"
|
93
|
+
html_options["data-open-url"] = authorization_sign_modal_initiative_path(initiative)
|
94
|
+
end
|
95
|
+
|
96
|
+
html_options["onclick"] = "event.preventDefault();"
|
97
|
+
|
98
|
+
send("#{tag}_to", "", html_options, &block)
|
99
|
+
end
|
82
100
|
end
|
83
101
|
end
|
84
102
|
end
|
@@ -57,6 +57,8 @@ module Decidim
|
|
57
57
|
|
58
58
|
validates :title, :description, :state, presence: true
|
59
59
|
validates :signature_type, presence: true
|
60
|
+
validate :signature_type_allowed
|
61
|
+
|
60
62
|
validates :hashtag,
|
61
63
|
uniqueness: true,
|
62
64
|
allow_blank: true,
|
@@ -78,6 +80,7 @@ module Decidim
|
|
78
80
|
scope :with_state, ->(state) { where(state: state) if state.present? }
|
79
81
|
|
80
82
|
scope :public_spaces, -> { published }
|
83
|
+
scope :signature_type_updatable, -> { created }
|
81
84
|
|
82
85
|
scope :order_by_most_recent, -> { order(created_at: :desc) }
|
83
86
|
scope :order_by_supports, -> { order(Arel.sql("initiative_votes_count + coalesce(offline_votes, 0) desc")) }
|
@@ -172,12 +175,22 @@ module Decidim
|
|
172
175
|
# RETURNS string
|
173
176
|
delegate :banner_image, to: :type
|
174
177
|
|
178
|
+
delegate :document_number_authorization_handler, to: :type
|
179
|
+
delegate :supports_required, to: :scoped_type
|
180
|
+
|
175
181
|
def votes_enabled?
|
176
182
|
published? &&
|
177
183
|
signature_start_date <= Date.current &&
|
178
184
|
signature_end_date >= Date.current
|
179
185
|
end
|
180
186
|
|
187
|
+
# Public: Check if the user has voted the question.
|
188
|
+
#
|
189
|
+
# Returns Boolean.
|
190
|
+
def voted_by?(user)
|
191
|
+
votes.where(author: user).any?
|
192
|
+
end
|
193
|
+
|
181
194
|
# Public: Checks if the organization has given an answer for the initiative.
|
182
195
|
#
|
183
196
|
# Returns Boolean.
|
@@ -239,9 +252,14 @@ module Decidim
|
|
239
252
|
|
240
253
|
# Public: Returns the percentage of required supports reached
|
241
254
|
def percentage
|
242
|
-
|
243
|
-
|
244
|
-
|
255
|
+
return 100 if supports_goal_reached?
|
256
|
+
|
257
|
+
supports_count * 100 / supports_required
|
258
|
+
end
|
259
|
+
|
260
|
+
# Public: Whether the supports required objective has been reached
|
261
|
+
def supports_goal_reached?
|
262
|
+
supports_count >= supports_required
|
245
263
|
end
|
246
264
|
|
247
265
|
# Public: Overrides slug attribute from participatory processes.
|
@@ -281,8 +299,41 @@ module Decidim
|
|
281
299
|
published?
|
282
300
|
end
|
283
301
|
|
302
|
+
def accepts_online_votes?
|
303
|
+
Decidim::Initiatives.online_voting_allowed &&
|
304
|
+
(online? || any?) &&
|
305
|
+
votes_enabled?
|
306
|
+
end
|
307
|
+
|
308
|
+
def accepts_online_unvotes?
|
309
|
+
accepts_online_votes? && type.undo_online_signatures_enabled?
|
310
|
+
end
|
311
|
+
|
312
|
+
def minimum_committee_members
|
313
|
+
type.minimum_committee_members || Decidim::Initiatives.minimum_committee_members
|
314
|
+
end
|
315
|
+
|
316
|
+
def enough_committee_members?
|
317
|
+
committee_members.approved.count >= minimum_committee_members
|
318
|
+
end
|
319
|
+
|
320
|
+
# PUBLIC
|
321
|
+
#
|
322
|
+
# Checks if the type the initiative belongs to enables SMS code
|
323
|
+
# verification step. Tis configuration is ignored if the organization
|
324
|
+
# doesn't have the sms authorization available
|
325
|
+
#
|
326
|
+
# RETURNS boolean
|
327
|
+
def validate_sms_code_on_votes?
|
328
|
+
organization.available_authorizations.include?("sms") && type.validate_sms_code_on_votes?
|
329
|
+
end
|
330
|
+
|
284
331
|
private
|
285
332
|
|
333
|
+
def signature_type_allowed
|
334
|
+
errors.add(:signature_type, :invalid) if !published? && type.allowed_signature_types_for_initiatives.exclude?(signature_type)
|
335
|
+
end
|
336
|
+
|
286
337
|
def notify_state_change
|
287
338
|
return unless saved_change_to_state?
|
288
339
|
notifier = Decidim::Initiatives::StatusChangeNotifier.new(initiative: self)
|
@@ -19,5 +19,6 @@ module Decidim
|
|
19
19
|
|
20
20
|
scope :approved, -> { where(state: :accepted) }
|
21
21
|
scope :non_deleted, -> { includes(:user).where(decidim_users: { deleted_at: nil }) }
|
22
|
+
scope :excluding_author, -> { joins(:initiative).where.not("decidim_users_id = decidim_author_id") }
|
22
23
|
end
|
23
24
|
end
|
@@ -3,7 +3,10 @@
|
|
3
3
|
module Decidim
|
4
4
|
# Initiative type.
|
5
5
|
class InitiativesType < ApplicationRecord
|
6
|
+
include Decidim::HasResourcePermission
|
7
|
+
|
6
8
|
validates :title, :description, presence: true
|
9
|
+
validates :online_signature_enabled, inclusion: { in: [true, false] }
|
7
10
|
|
8
11
|
mount_uploader :banner_image, Decidim::BannerImageUploader
|
9
12
|
|
@@ -16,5 +19,32 @@ module Decidim
|
|
16
19
|
class_name: "Decidim::InitiativesTypeScope",
|
17
20
|
dependent: :destroy,
|
18
21
|
inverse_of: :type
|
22
|
+
|
23
|
+
def allowed_signature_types_for_initiatives
|
24
|
+
signature_types = []
|
25
|
+
|
26
|
+
signature_types << "online" if Decidim::Initiatives.online_voting_allowed && online_signature_enabled
|
27
|
+
signature_types << "offline" if Decidim::Initiatives.face_to_face_voting_allowed
|
28
|
+
signature_types << "any" if signature_types.size == (Initiative.signature_types.size - 1)
|
29
|
+
|
30
|
+
signature_types
|
31
|
+
end
|
32
|
+
|
33
|
+
def initiatives
|
34
|
+
initiatives_ids = scopes.map { |scope| scope.initiatives.pluck(:id) }.flatten
|
35
|
+
Initiative.where(id: initiatives_ids)
|
36
|
+
end
|
37
|
+
|
38
|
+
def allow_resource_permissions?
|
39
|
+
true
|
40
|
+
end
|
41
|
+
|
42
|
+
def mounted_admin_engine
|
43
|
+
"decidim_admin_initiatives"
|
44
|
+
end
|
45
|
+
|
46
|
+
def mounted_params
|
47
|
+
{ host: organization.host }
|
48
|
+
end
|
19
49
|
end
|
20
50
|
end
|
@@ -35,6 +35,7 @@ module Decidim
|
|
35
35
|
initiative_type_scope_action?
|
36
36
|
initiative_committee_action?
|
37
37
|
initiative_admin_user_action?
|
38
|
+
moderator_action?
|
38
39
|
allow! if permission_action.subject == :attachment
|
39
40
|
|
40
41
|
permission_action
|
@@ -82,7 +83,7 @@ module Decidim
|
|
82
83
|
end
|
83
84
|
|
84
85
|
def initiative_type_action?
|
85
|
-
return unless permission_action.subject
|
86
|
+
return unless [:initiative_type, :initiatives_type].include? permission_action.subject
|
86
87
|
|
87
88
|
initiative_type = context.fetch(:initiative_type, nil)
|
88
89
|
|
@@ -136,6 +137,8 @@ module Decidim
|
|
136
137
|
toggle_allow(initiative.published?)
|
137
138
|
when :discard
|
138
139
|
toggle_allow(initiative.validating?)
|
140
|
+
when :export_pdf_signatures
|
141
|
+
toggle_allow(initiative.published? || initiative.accepted? || initiative.rejected?)
|
139
142
|
when :export_votes
|
140
143
|
toggle_allow(initiative.offline? || initiative.any?)
|
141
144
|
when :accept
|
@@ -153,6 +156,12 @@ module Decidim
|
|
153
156
|
end
|
154
157
|
end
|
155
158
|
|
159
|
+
def moderator_action?
|
160
|
+
return unless permission_action.subject == :moderation
|
161
|
+
|
162
|
+
allow!
|
163
|
+
end
|
164
|
+
|
156
165
|
def read_initiative_list_action?
|
157
166
|
return unless permission_action.subject == :initiative &&
|
158
167
|
permission_action.action == :list
|
@@ -171,8 +180,8 @@ module Decidim
|
|
171
180
|
toggle_allow(initiative.created?)
|
172
181
|
when :send_to_technical_validation
|
173
182
|
allowed = initiative.created? && (
|
174
|
-
!initiative.
|
175
|
-
|
183
|
+
!initiative.created_by_individual? ||
|
184
|
+
initiative.enough_committee_members?
|
176
185
|
)
|
177
186
|
|
178
187
|
toggle_allow(allowed)
|
@@ -14,6 +14,7 @@ module Decidim
|
|
14
14
|
return permission_action if permission_action.scope != :public
|
15
15
|
|
16
16
|
# Non-logged users permissions
|
17
|
+
public_report_content_action?
|
17
18
|
list_public_initiatives?
|
18
19
|
read_public_initiative?
|
19
20
|
search_initiative_types_and_scopes?
|
@@ -24,6 +25,7 @@ module Decidim
|
|
24
25
|
request_membership?
|
25
26
|
|
26
27
|
vote_initiative?
|
28
|
+
sign_initiative?
|
27
29
|
unvote_initiative?
|
28
30
|
|
29
31
|
permission_action
|
@@ -51,7 +53,7 @@ module Decidim
|
|
51
53
|
|
52
54
|
def search_initiative_types_and_scopes?
|
53
55
|
return unless permission_action.action == :search
|
54
|
-
return unless [:initiative_type, :initiative_type_scope].include?(permission_action.subject)
|
56
|
+
return unless [:initiative_type, :initiative_type_scope, :initiative_type_signature_types].include?(permission_action.subject)
|
55
57
|
|
56
58
|
allow!
|
57
59
|
end
|
@@ -104,30 +106,57 @@ module Decidim
|
|
104
106
|
return unless permission_action.action == :vote &&
|
105
107
|
permission_action.subject == :initiative
|
106
108
|
|
107
|
-
can_vote
|
108
|
-
|
109
|
-
|
110
|
-
|
109
|
+
toggle_allow(can_vote?)
|
110
|
+
end
|
111
|
+
|
112
|
+
def authorized?(permission_action, resource: nil, permissions_holder: nil)
|
113
|
+
return unless resource || permissions_holder
|
111
114
|
|
112
|
-
|
115
|
+
ActionAuthorizer.new(user, permission_action, permissions_holder, resource).authorize.ok?
|
113
116
|
end
|
114
117
|
|
115
118
|
def unvote_initiative?
|
116
119
|
return unless permission_action.action == :unvote &&
|
117
120
|
permission_action.subject == :initiative
|
118
121
|
|
119
|
-
can_unvote = initiative.
|
122
|
+
can_unvote = initiative.accepts_online_unvotes? &&
|
120
123
|
initiative.organization&.id == user.organization&.id &&
|
121
124
|
initiative.votes.where(decidim_author_id: user.id, decidim_user_group_id: decidim_user_group_id).any? &&
|
122
|
-
(can_user_support?(initiative) || Decidim::UserGroups::ManageableUserGroups.for(user).verified.any?)
|
125
|
+
(can_user_support?(initiative) || Decidim::UserGroups::ManageableUserGroups.for(user).verified.any?) &&
|
126
|
+
authorized?(:vote, resource: initiative, permissions_holder: initiative.type)
|
123
127
|
|
124
128
|
toggle_allow(can_unvote)
|
125
129
|
end
|
126
130
|
|
131
|
+
def public_report_content_action?
|
132
|
+
return unless permission_action.action == :create &&
|
133
|
+
permission_action.subject == :moderation
|
134
|
+
|
135
|
+
allow!
|
136
|
+
end
|
137
|
+
|
138
|
+
def sign_initiative?
|
139
|
+
return unless permission_action.action == :sign_initiative &&
|
140
|
+
permission_action.subject == :initiative
|
141
|
+
|
142
|
+
can_sign = can_vote? &&
|
143
|
+
context.fetch(:signature_has_steps, false)
|
144
|
+
|
145
|
+
toggle_allow(can_sign)
|
146
|
+
end
|
147
|
+
|
127
148
|
def decidim_user_group_id
|
128
149
|
context.fetch(:group_id, nil)
|
129
150
|
end
|
130
151
|
|
152
|
+
def can_vote?
|
153
|
+
initiative.votes_enabled? &&
|
154
|
+
initiative.organization&.id == user.organization&.id &&
|
155
|
+
initiative.votes.where(decidim_author_id: user.id, decidim_user_group_id: decidim_user_group_id).empty? &&
|
156
|
+
(can_user_support?(initiative) || Decidim::UserGroups::ManageableUserGroups.for(user).verified.any?) &&
|
157
|
+
authorized?(:vote, resource: initiative, permissions_holder: initiative.type)
|
158
|
+
end
|
159
|
+
|
131
160
|
def can_user_support?(initiative)
|
132
161
|
!initiative.offline? && (
|
133
162
|
Decidim::Initiatives.do_not_require_authorization ||
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Initiatives
|
5
|
+
module Admin
|
6
|
+
# A class used to find the admins for an initiative.
|
7
|
+
class AdminUsers < Rectify::Query
|
8
|
+
# Syntactic sugar to initialize the class and return the queried objects.
|
9
|
+
#
|
10
|
+
# initiative - Decidim::Initiative
|
11
|
+
def self.for(initiative)
|
12
|
+
new(initiative).query
|
13
|
+
end
|
14
|
+
|
15
|
+
# Initializes the class.
|
16
|
+
#
|
17
|
+
# initiative - Decidim::Initiative
|
18
|
+
def initialize(initiative)
|
19
|
+
@initiative = initiative
|
20
|
+
end
|
21
|
+
|
22
|
+
# Finds organization admins and the users with role admin for the given initiative.
|
23
|
+
#
|
24
|
+
# Returns an ActiveRecord::Relation.
|
25
|
+
def query
|
26
|
+
Decidim::User.where(id: organization_admins)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
attr_reader :initiative
|
32
|
+
|
33
|
+
def organization_admins
|
34
|
+
initiative.organization.admins
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Initiatives
|
5
|
+
# Service to encrypt and decrypt metadata
|
6
|
+
class DataEncryptor
|
7
|
+
attr_reader :secret
|
8
|
+
|
9
|
+
def initialize(args = {})
|
10
|
+
@secret = args.fetch(:secret) || "default"
|
11
|
+
@key = ActiveSupport::KeyGenerator.new(secret).generate_key(
|
12
|
+
Rails.application.secrets.secret_key_base, ActiveSupport::MessageEncryptor.key_len
|
13
|
+
)
|
14
|
+
@encryptor = ActiveSupport::MessageEncryptor.new(@key)
|
15
|
+
end
|
16
|
+
|
17
|
+
def encrypt(data)
|
18
|
+
@encryptor.encrypt_and_sign(data)
|
19
|
+
end
|
20
|
+
|
21
|
+
def decrypt(encrypted_data)
|
22
|
+
@encryptor.decrypt_and_verify(encrypted_data)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Initiatives
|
5
|
+
# Example of service to generate a timestamp for a document
|
6
|
+
class DummyTimestamp
|
7
|
+
attr_accessor :document
|
8
|
+
|
9
|
+
# Public: Initializes the service.
|
10
|
+
# document - The document for which the timestamp is going to be generated
|
11
|
+
# signature_type
|
12
|
+
def initialize(args = {})
|
13
|
+
@document = args.fetch(:document)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Public: Timestamp generated from data
|
17
|
+
def timestamp
|
18
|
+
@timestamp ||= Base64.encode64(OpenSSL::Digest::SHA1.digest("#{@document}-#{Time.current}")).chop
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|