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.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/decidim/initiatives/scoped_type.js +13 -10
  3. data/app/assets/stylesheet/decidim/initiatives/initiatives-votes.css.scss +97 -0
  4. data/app/cells/decidim/initiatives/initiative_m_cell.rb +1 -1
  5. data/app/cells/decidim/initiatives_votes/vote/show.erb +29 -0
  6. data/app/cells/decidim/initiatives_votes/vote_cell.rb +51 -0
  7. data/app/commands/decidim/initiatives/admin/create_initiative_type.rb +8 -1
  8. data/app/commands/decidim/initiatives/admin/update_initiative.rb +7 -6
  9. data/app/commands/decidim/initiatives/admin/update_initiative_answer.rb +76 -0
  10. data/app/commands/decidim/initiatives/admin/update_initiative_type.rb +17 -1
  11. data/app/commands/decidim/initiatives/create_initiative.rb +12 -0
  12. data/app/commands/decidim/initiatives/spawn_committee_request.rb +8 -7
  13. data/app/commands/decidim/initiatives/validate_mobile_phone.rb +61 -0
  14. data/app/commands/decidim/initiatives/validate_sms_code.rb +40 -0
  15. data/app/commands/decidim/initiatives/vote_initiative.rb +23 -7
  16. data/app/controllers/concerns/decidim/initiatives/needs_initiative.rb +12 -1
  17. data/app/controllers/decidim/initiatives/admin/answers_controller.rb +46 -0
  18. data/app/controllers/decidim/initiatives/admin/initiatives_controller.rb +31 -5
  19. data/app/controllers/decidim/initiatives/admin/initiatives_types_controller.rb +1 -0
  20. data/app/controllers/decidim/initiatives/admin/initiatives_types_permissions_controller.rb +20 -0
  21. data/app/controllers/decidim/initiatives/admin/moderations_controller.rb +16 -0
  22. data/app/controllers/decidim/initiatives/application_controller.rb +0 -2
  23. data/app/controllers/decidim/initiatives/authorization_sign_modals_controller.rb +26 -0
  24. data/app/controllers/decidim/initiatives/committee_requests_controller.rb +4 -1
  25. data/app/controllers/decidim/initiatives/create_initiative_controller.rb +16 -5
  26. data/app/controllers/decidim/initiatives/initiative_signatures_controller.rb +207 -0
  27. data/app/controllers/decidim/initiatives/initiative_votes_controller.rb +3 -1
  28. data/app/controllers/decidim/initiatives/initiatives_type_signature_types_controller.rb +21 -0
  29. data/app/forms/decidim/initiatives/admin/initiative_answer_form.rb +29 -0
  30. data/app/forms/decidim/initiatives/admin/initiative_form.rb +25 -7
  31. data/app/forms/decidim/initiatives/admin/initiative_type_form.rb +14 -0
  32. data/app/forms/decidim/initiatives/committee_member_form.rb +30 -0
  33. data/app/forms/decidim/initiatives/initiative_form.rb +5 -0
  34. data/app/forms/decidim/initiatives/vote_form.rb +151 -0
  35. data/app/helpers/decidim/initiatives/create_initiative_helper.rb +25 -12
  36. data/app/helpers/decidim/initiatives/initiative_helper.rb +18 -0
  37. data/app/models/decidim/initiative.rb +54 -3
  38. data/app/models/decidim/initiatives_committee_member.rb +1 -0
  39. data/app/models/decidim/initiatives_type.rb +30 -0
  40. data/app/permissions/decidim/initiatives/admin/permissions.rb +12 -3
  41. data/app/permissions/decidim/initiatives/permissions.rb +37 -8
  42. data/app/queries/decidim/initiatives/admin/admin_users.rb +39 -0
  43. data/app/services/decidim/initiatives/data_encryptor.rb +26 -0
  44. data/app/services/decidim/initiatives/dummy_timestamp.rb +22 -0
  45. data/app/services/decidim/initiatives/pdf_signature_example.rb +121 -0
  46. data/app/views/decidim/initiatives/admin/answers/_info_initiative.html.erb +23 -0
  47. data/app/views/decidim/initiatives/admin/answers/edit.html.erb +35 -0
  48. data/app/views/decidim/initiatives/admin/initiatives/_form.html.erb +17 -16
  49. data/app/views/decidim/initiatives/admin/initiatives/edit.html.erb +10 -3
  50. data/app/views/decidim/initiatives/admin/initiatives/export_pdf_signatures.pdf.erb +35 -0
  51. data/app/views/decidim/initiatives/admin/initiatives/index.html.erb +6 -0
  52. data/app/views/decidim/initiatives/admin/initiatives_types/_form.html.erb +36 -0
  53. data/app/views/decidim/initiatives/admin/initiatives_types/index.html.erb +2 -0
  54. data/app/views/decidim/initiatives/create_initiative/fill_data.html.erb +3 -3
  55. data/app/views/decidim/initiatives/create_initiative/finish.html.erb +2 -2
  56. data/app/views/decidim/initiatives/create_initiative/previous_form.html.erb +2 -2
  57. data/app/views/decidim/initiatives/create_initiative/promotal_committee.html.erb +3 -3
  58. data/app/views/decidim/initiatives/create_initiative/select_initiative_type.html.erb +37 -22
  59. data/app/views/decidim/initiatives/initiative_signatures/_wizard_steps.html.erb +19 -0
  60. data/app/views/decidim/initiatives/initiative_signatures/fill_personal_data.html.erb +43 -0
  61. data/app/views/decidim/initiatives/initiative_signatures/finish.html.erb +17 -0
  62. data/app/views/decidim/initiatives/initiative_signatures/sms_code.html.erb +22 -0
  63. data/app/views/decidim/initiatives/initiative_signatures/sms_phone_number.html.erb +22 -0
  64. data/app/views/decidim/initiatives/initiative_signatures/update_buttons_and_counters.js.erb +21 -0
  65. data/app/views/decidim/initiatives/initiative_votes/update_buttons_and_counters.js.erb +1 -1
  66. data/app/views/decidim/initiatives/initiatives/_author.html.erb +1 -1
  67. data/app/views/decidim/initiatives/initiatives/_interactions.html.erb +11 -0
  68. data/app/views/decidim/initiatives/initiatives/_progress_bar.html.erb +9 -0
  69. data/app/views/decidim/initiatives/initiatives/_result.html.erb +3 -3
  70. data/app/views/decidim/initiatives/initiatives/_vote_button.html.erb +39 -18
  71. data/app/views/decidim/initiatives/initiatives/_vote_cabin.html.erb +9 -9
  72. data/app/views/decidim/initiatives/initiatives/show.html.erb +12 -12
  73. data/app/views/decidim/initiatives/initiatives/signature_identities.html.erb +19 -9
  74. data/app/views/decidim/initiatives/initiatives_type_signature_types/search.html.erb +1 -0
  75. data/app/views/layouts/decidim/_initiative_creation_header.html.erb +24 -34
  76. data/app/views/layouts/decidim/_initiative_signature_creation_header.html.erb +27 -0
  77. data/app/views/layouts/decidim/admin/initiative.html.erb +22 -15
  78. data/app/views/layouts/decidim/admin/initiatives_votes.pdf.erb +11 -0
  79. data/app/views/layouts/decidim/initiative_creation.html.erb +15 -3
  80. data/app/views/layouts/decidim/initiative_signature_creation.html.erb +12 -0
  81. data/config/initializers/wicked_pdf.rb +23 -0
  82. data/config/locales/ar-SA.yml +138 -7
  83. data/config/locales/ca.yml +120 -28
  84. data/config/locales/cs-CZ.yml +103 -9
  85. data/config/locales/cs.yml +494 -0
  86. data/config/locales/de.yml +101 -9
  87. data/config/locales/en.yml +133 -40
  88. data/config/locales/es-MX.yml +101 -9
  89. data/config/locales/es-PY.yml +101 -9
  90. data/config/locales/es.yml +124 -32
  91. data/config/locales/eu.yml +101 -9
  92. data/config/locales/fi-pl.yml +101 -9
  93. data/config/locales/fi-plain.yml +478 -0
  94. data/config/locales/fi.yml +117 -25
  95. data/config/locales/fr.yml +102 -10
  96. data/config/locales/gl.yml +101 -9
  97. data/config/locales/hu.yml +102 -10
  98. data/config/locales/id-ID.yml +100 -9
  99. data/config/locales/it.yml +101 -9
  100. data/config/locales/nl.yml +101 -9
  101. data/config/locales/pl.yml +104 -10
  102. data/config/locales/pt-BR.yml +101 -9
  103. data/config/locales/pt.yml +101 -9
  104. data/config/locales/ru.yml +4 -9
  105. data/config/locales/sv.yml +101 -9
  106. data/config/locales/tr-TR.yml +101 -9
  107. data/config/locales/uk.yml +4 -9
  108. data/db/migrate/20181212154456_add_collect_extra_user_fields_to_initiatives_types.rb +7 -0
  109. data/db/migrate/20181212155125_add_online_signature_enabled_to_initiative_type.rb +7 -0
  110. data/db/migrate/20181212155740_add_extra_fields_legal_information_to_initiatives_types.rb +7 -0
  111. data/db/migrate/20181213184712_add_min_committee_members_to_initiative_type.rb +7 -0
  112. data/db/migrate/20181220134322_add_encrypted_metadata_to_decidim_initiatives_votes.rb +7 -0
  113. data/db/migrate/20181224100803_add_timestamp_to_decidim_initiatives_votes.rb +7 -0
  114. data/db/migrate/20181224101041_add_hash_id_to_decidim_initiatives_votes.rb +7 -0
  115. data/db/migrate/20190124170442_add_validate_sms_code_on_votes_to_initiatives_types.rb +7 -0
  116. data/db/migrate/20190125131847_add_document_number_authorization_handler_to_initiatives_types.rb +7 -0
  117. data/db/migrate/20190213184301_add_undo_online_signatures_enabled_to_initiatives_types.rb +7 -0
  118. data/lib/decidim/initiatives.rb +12 -0
  119. data/lib/decidim/initiatives/admin_engine.rb +12 -0
  120. data/lib/decidim/initiatives/engine.rb +3 -0
  121. data/lib/decidim/initiatives/participatory_space.rb +6 -1
  122. data/lib/decidim/initiatives/test/factories.rb +39 -0
  123. data/lib/decidim/initiatives/version.rb +1 -1
  124. metadata +115 -14
  125. data/app/views/decidim/initiatives/initiatives/_statistics.html.erb +0 -21
  126. 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 Decidim::Initiatives.online_voting_allowed
10
+ return offline_signature_type_options unless online_signature_allowed?(initiative_form)
10
11
 
11
- options = []
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
- percentage = supports_count * 100 / scoped_type.supports_required
243
- percentage = 100 if percentage > 100
244
- percentage
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 == :initiative_type
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.decidim_user_group_id.nil? ||
175
- initiative.committee_members.approved.count >= Decidim::Initiatives.minimum_committee_members
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 = initiative.votes_enabled? &&
108
- initiative.organization&.id == user.organization&.id &&
109
- initiative.votes.where(decidim_author_id: user.id, decidim_user_group_id: decidim_user_group_id).empty? &&
110
- (can_user_support?(initiative) || Decidim::UserGroups::ManageableUserGroups.for(user).verified.any?)
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
- toggle_allow(can_vote)
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.votes_enabled? &&
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