decidim-verifications 0.21.0 → 0.22.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +17 -1
  3. data/app/cells/decidim/verifications/authorization_metadata/show.erb +13 -0
  4. data/app/cells/decidim/verifications/authorization_metadata_cell.rb +22 -0
  5. data/app/cells/decidim/verifications/revocations/show.erb +40 -0
  6. data/app/cells/decidim/verifications/revocations_cell.rb +19 -0
  7. data/app/commands/decidim/verifications/confirm_user_authorization.rb +49 -9
  8. data/app/commands/decidim/verifications/destroy_user_authorization.rb +24 -0
  9. data/app/commands/decidim/verifications/revoke_all_authorizations.rb +48 -0
  10. data/app/commands/decidim/verifications/revoke_by_condition_authorizations.rb +68 -0
  11. data/app/controllers/concerns/decidim/verifications/renewable.rb +37 -0
  12. data/app/controllers/decidim/verifications/admin/verifications_controller.rb +40 -0
  13. data/app/controllers/decidim/verifications/application_controller.rb +5 -1
  14. data/app/controllers/decidim/verifications/authorizations_controller.rb +18 -2
  15. data/app/controllers/decidim/verifications/csv_census/authorizations_controller.rb +3 -1
  16. data/app/controllers/decidim/verifications/id_documents/admin/confirmations_controller.rb +1 -1
  17. data/app/controllers/decidim/verifications/id_documents/authorizations_controller.rb +2 -0
  18. data/app/controllers/decidim/verifications/postal_letter/authorizations_controller.rb +3 -1
  19. data/app/controllers/decidim/verifications/sms/authorizations_controller.rb +3 -1
  20. data/app/forms/decidim/verifications/admin/revocations_before_date_form.rb +16 -0
  21. data/app/queries/decidim/verifications/authorizations_before_date.rb +51 -0
  22. data/app/services/decidim/authorization_handler.rb +4 -0
  23. data/app/views/decidim/verifications/authorizations/_granted_authorization.html.erb +29 -24
  24. data/app/views/decidim/verifications/authorizations/first_login.html.erb +2 -2
  25. data/app/views/decidim/verifications/authorizations/index.html.erb +20 -11
  26. data/app/views/decidim/verifications/authorizations/new.html.erb +2 -2
  27. data/app/views/decidim/verifications/authorizations/renew_modal.html.erb +38 -0
  28. data/app/views/decidim/verifications/id_documents/authorizations/_form.html.erb +2 -0
  29. data/app/views/decidim/verifications/postal_letter/authorizations/edit.html.erb +2 -0
  30. data/app/views/decidim/verifications/postal_letter/authorizations/new.html.erb +2 -0
  31. data/app/views/decidim/verifications/sms/authorizations/edit.html.erb +2 -0
  32. data/app/views/decidim/verifications/sms/authorizations/new.html.erb +2 -0
  33. data/config/locales/ar.yml +2 -0
  34. data/config/locales/bg-BG.yml +17 -0
  35. data/config/locales/ca.yml +30 -0
  36. data/config/locales/cs.yml +30 -0
  37. data/config/locales/da-DK.yml +1 -0
  38. data/config/locales/de.yml +31 -0
  39. data/config/locales/el.yml +257 -0
  40. data/config/locales/en.yml +30 -0
  41. data/config/locales/es-MX.yml +30 -0
  42. data/config/locales/es-PY.yml +30 -0
  43. data/config/locales/es.yml +30 -0
  44. data/config/locales/et-EE.yml +1 -0
  45. data/config/locales/eu.yml +2 -0
  46. data/config/locales/fi-plain.yml +30 -0
  47. data/config/locales/fi.yml +40 -10
  48. data/config/locales/fr-CA.yml +258 -0
  49. data/config/locales/fr.yml +30 -0
  50. data/config/locales/ga-IE.yml +1 -0
  51. data/config/locales/gl.yml +2 -0
  52. data/config/locales/hr-HR.yml +1 -0
  53. data/config/locales/hu.yml +23 -0
  54. data/config/locales/id-ID.yml +2 -0
  55. data/config/locales/it.yml +30 -0
  56. data/config/locales/ja-JP.yml +257 -0
  57. data/config/locales/lt-LT.yml +1 -0
  58. data/config/locales/lv-LV.yml +250 -0
  59. data/config/locales/mt-MT.yml +1 -0
  60. data/config/locales/nl.yml +30 -0
  61. data/config/locales/no.yml +2 -0
  62. data/config/locales/pl.yml +31 -0
  63. data/config/locales/pt-BR.yml +3 -1
  64. data/config/locales/pt.yml +125 -94
  65. data/config/locales/ro-RO.yml +259 -0
  66. data/config/locales/sk-SK.yml +258 -0
  67. data/config/locales/sk.yml +258 -0
  68. data/config/locales/sl.yml +5 -0
  69. data/config/locales/sr-CS.yml +1 -0
  70. data/config/locales/sv.yml +30 -0
  71. data/config/locales/tr-TR.yml +2 -0
  72. data/lib/decidim/verifications/adapter.rb +12 -0
  73. data/lib/decidim/verifications/csv_census/engine.rb +3 -1
  74. data/lib/decidim/verifications/engine.rb +13 -0
  75. data/lib/decidim/verifications/id_documents/engine.rb +1 -0
  76. data/lib/decidim/verifications/postal_letter/engine.rb +3 -1
  77. data/lib/decidim/verifications/sms/engine.rb +3 -1
  78. data/lib/decidim/verifications/version.rb +1 -1
  79. data/lib/decidim/verifications/workflow_manifest.rb +3 -0
  80. data/lib/decidim/verifications/workflows.rb +1 -1
  81. metadata +35 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9c914bf8725d476212afdde6db64fc538308bae0b39cef0d96e835be16e6a92d
4
- data.tar.gz: 19845e9b6f88a45489af575d42865e4c17eb7a8db4bc1c5b21fc84319d9e205e
3
+ metadata.gz: ee208339d39a5f1b778599a3c9645999e76475fb1f413e72a78c276e5fe09e1a
4
+ data.tar.gz: 48d43893269f7caf25a6cad9d9139e140f9f746b298e776e05d50dc8469bea35
5
5
  SHA512:
6
- metadata.gz: b406e8086b02340cca468b7cf4d3f018de59f3330b98d28976a4aa6c5bc939b87dd35376310279b44ec41831c8468dfbb9a20da4d974293a468024764f637894
7
- data.tar.gz: 55461cef2fd47cc4e5d3de10654bc90c985020c0f857b807f8800af3de06bcfe7cc9a5c2b145b8a509f0865c90c1471d337707357a4c650948c4cdbe168cb59a
6
+ metadata.gz: ae51a4e909b47ff69057eef77063336fd8a3e31a27cb94d03761199558d5fddf4be312b583257b3d9d8be8d962e413fbadd57a567d9e20a1308cb34f78e4e29b
7
+ data.tar.gz: 2f483e0bace8f874d488e47148b3041d078fcea5cb60ee10ece631e38697cd14cb6e9c4ee5ce0887f6619e98357d771688afd0815ba526f6b65cba9ee4ffd0d6
data/README.md CHANGED
@@ -62,7 +62,7 @@ Decidim implements two type of authorization methods:
62
62
  # config/initializers/decidim.rb
63
63
 
64
64
  Decidim::Verifications.register_workflow(:census) do |workflow|
65
- workflow.form = "<myAuthorizationHandlerClass"
65
+ workflow.form = "<myAuthorizationHandlerClass>"
66
66
  end
67
67
  ```
68
68
 
@@ -97,6 +97,22 @@ Decidim implements two type of authorization methods:
97
97
  * `edit_authorization_path`: This is the entry point to resume an existing
98
98
  authorization process.
99
99
 
100
+ * _Renewable authorizations_.
101
+ By default a participant can't renew its authorization, but this can be enabled when registering the workflow, the time between renewals can be configured (one day by default).
102
+
103
+ Optionally to change the renew modal content part of the data stored, you can set a new value for the cell used to render the metadata.
104
+
105
+ ```ruby
106
+ # config/initializers/decidim.rb
107
+
108
+ Decidim::Verifications.register_workflow(:census) do |workflow|
109
+ workflow.form = "myAuthorizationHandlerClass"
110
+ workflow.renewable = true
111
+ workflow.time_between_renewals = 1.day
112
+ workflow.metadata_cell = "decidim/verifications/authorization_metadata"
113
+ end
114
+ ```
115
+
100
116
  ### SMS verification
101
117
 
102
118
  Decidim comes with a verification workflow designed to verify users by sending
@@ -0,0 +1,13 @@
1
+ <p>
2
+ <%= t("authorization_metadata.info", scope: "decidim.verifications.authorizations") %>
3
+ </p>
4
+
5
+ <ul>
6
+ <% if model.metadata.present? %>
7
+ <% model.metadata.symbolize_keys.except(:extras).each do |data| %>
8
+ <%= metadata(data) %>
9
+ <% end %>
10
+ <% else %>
11
+ <li> <%= t("authorization_metadata.no_data_stored", scope: "decidim.verifications.authorizations") %></li>
12
+ <% end %>
13
+ </ul>
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Verifications
5
+ # This cell is to render the authorization metadata in the renew modal
6
+ class AuthorizationMetadataCell < Decidim::ViewModel
7
+ private
8
+
9
+ def metadata(data)
10
+ "<li>#{metadata_key(data)} <strong>#{metadata_value(data)}</strong></li>"
11
+ end
12
+
13
+ def metadata_key(data)
14
+ "#{t("#{model.name}.fields.#{data.first}", scope: "decidim.authorization_handlers")}:"
15
+ end
16
+
17
+ def metadata_value(data)
18
+ data.second
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,40 @@
1
+ <div class="card-divider">
2
+ <h2 class="card-title">
3
+ <%= t("decidim.admin.menu.authorization_revocation.title") %>
4
+ </h2>
5
+ </div>
6
+ <div class="card-section">
7
+ <% if model.count > 0 %>
8
+ <div class="revoke_all_box">
9
+ <p><%= t("decidim.admin.menu.authorization_revocation.info", count: model.count ) %></p>
10
+ <%= link_to t("decidim.admin.menu.authorization_revocation.button"),
11
+ decidim_verifications.admin_verifications_destroy_all_path,
12
+ method: :delete,
13
+ class: "button",
14
+ data: { confirm: t("decidim.admin.menu.authorization_revocation.destroy.confirm_all") } %>
15
+ </div>
16
+ <br>
17
+ <div class="revoke_before_date_box">
18
+ <%= decidim_form_for(@form, url: decidim_verifications.admin_verifications_destroy_before_date_path, html: { class: "form" } ) do |form| %>
19
+ <div class="card">
20
+ <div class="card-section">
21
+ <div class="row column">
22
+ <%= form.check_box :impersonated_only %>
23
+ </div>
24
+ <div class="row column">
25
+ <%= form.date_field :before_date, value: Date.today.prev_month.strftime("%d/%m/%Y"), autocomplete: "off" %>
26
+ <%= label_tag(:before_date_info, t("decidim.admin.menu.authorization_revocation.before_date_info")) %>
27
+ </div>
28
+ <div class="button--double">
29
+ <%= form.submit t("decidim.admin.menu.authorization_revocation.button_before"), data: { confirm: t("decidim.admin.menu.authorization_revocation.destroy.confirm") } %>
30
+ </div>
31
+ </div>
32
+ </div>
33
+ <% end %>
34
+ </div>
35
+ <% else %>
36
+ <div class="revoke_no_data">
37
+ <%= t("decidim.admin.menu.authorization_revocation.no_data") %>
38
+ </div>
39
+ <% end %>
40
+ </div>
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Verifications
5
+ # This cell renders revocation options - Revoke all or Revoke before date
6
+ class RevocationsCell < Decidim::ViewModel
7
+ def show
8
+ @form = Decidim::Verifications::Admin::RevocationsBeforeDateForm.from_params(params)
9
+ render
10
+ end
11
+
12
+ protected
13
+
14
+ def decidim_verifications
15
+ Decidim::Verifications::Engine.routes.url_helpers
16
+ end
17
+ end
18
+ end
19
+ end
@@ -4,13 +4,17 @@ module Decidim
4
4
  module Verifications
5
5
  # A command to confirm a previous partial authorization.
6
6
  class ConfirmUserAuthorization < Rectify::Command
7
+ # Number of failed confirmation attempts before throttling.
8
+ MAX_FAILED_ATTEMPTS = 2
9
+
7
10
  # Public: Initializes the command.
8
11
  #
9
12
  # authorization - An Authorization to be confirmed.
10
13
  # form - A form object with the verification data to confirm it.
11
- def initialize(authorization, form)
14
+ def initialize(authorization, form, session)
12
15
  @authorization = authorization
13
16
  @form = form
17
+ @session = session
14
18
  end
15
19
 
16
20
  # Executes the command. Broadcasts these events:
@@ -20,19 +24,19 @@ module Decidim
20
24
  #
21
25
  # Returns nothing.
22
26
  def call
23
- return broadcast(:already_confirmed) if authorization.granted?
27
+ return already_confirmed! if authorization.granted?
24
28
 
25
- return broadcast(:invalid) unless form.valid?
29
+ return invalid! unless form.valid?
26
30
 
27
- if confirmation_successful?
28
- authorization.grant!
31
+ throttle! if too_many_failed_attempts?
29
32
 
30
- broadcast(:ok)
33
+ if confirmation_successful?
34
+ valid!
31
35
  else
32
- broadcast(:invalid)
36
+ invalid!
33
37
  end
34
38
  rescue StandardError => e
35
- broadcast(:invalid, e.message)
39
+ invalid!(e.message)
36
40
  end
37
41
 
38
42
  protected
@@ -45,7 +49,43 @@ module Decidim
45
49
 
46
50
  private
47
51
 
48
- attr_reader :authorization, :form
52
+ def valid!
53
+ authorization.grant!
54
+ reset_failed_attempts!
55
+ broadcast(:ok)
56
+ end
57
+
58
+ def invalid!(message = nil)
59
+ record_failed_attempt!
60
+ broadcast(:invalid, message)
61
+ end
62
+
63
+ def already_confirmed!
64
+ reset_failed_attempts!
65
+ broadcast(:already_confirmed)
66
+ end
67
+
68
+ def too_many_failed_attempts?
69
+ failed_attempts > MAX_FAILED_ATTEMPTS
70
+ end
71
+
72
+ def failed_attempts
73
+ session[:failed_attempts] ||= 0
74
+ end
75
+
76
+ def reset_failed_attempts!
77
+ session[:failed_attempts] = 0
78
+ end
79
+
80
+ def record_failed_attempt!
81
+ session[:failed_attempts] = failed_attempts + 1
82
+ end
83
+
84
+ def throttle!
85
+ sleep rand * failed_attempts
86
+ end
87
+
88
+ attr_reader :authorization, :form, :session
49
89
  end
50
90
  end
51
91
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Verifications
5
+ # A command to Destroy the Authorization of a user.
6
+ class DestroyUserAuthorization < Rectify::Command
7
+ def initialize(authorization)
8
+ @authorization = authorization
9
+ end
10
+
11
+ def call
12
+ return broadcast(:invalid) unless authorization
13
+
14
+ authorization.destroy!
15
+
16
+ broadcast(:ok, authorization)
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :authorization
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Verifications
5
+ # A command to revoke authorizations
6
+ class RevokeAllAuthorizations < Rectify::Command
7
+ # Public: Initializes the command.
8
+ #
9
+ # organization - Organization object.
10
+ # current_user - The current user.
11
+ def initialize(organization, current_user)
12
+ @organization = organization
13
+ @current_user = current_user
14
+ end
15
+
16
+ # Executes the command. Broadcasts these events:
17
+ #
18
+ # - :ok when everything is valid.
19
+ # - :invalid if the handler wasn't valid and we couldn't proceed.
20
+ #
21
+ # Returns nothing.
22
+ def call
23
+ return broadcast(:invalid) unless @organization
24
+
25
+ auths = Decidim::Verifications::Authorizations.new(
26
+ organization: organization,
27
+ granted: true
28
+ ).query
29
+
30
+ auths.find_each do |auth|
31
+ Decidim.traceability.perform_action!(
32
+ :destroy,
33
+ auth,
34
+ current_user
35
+ ) do
36
+ auth.destroy
37
+ end
38
+ end
39
+
40
+ broadcast(:ok)
41
+ end
42
+
43
+ private
44
+
45
+ attr_reader :organization, :current_user
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Verifications
5
+ # A command to revoke authorizations with filter
6
+ class RevokeByConditionAuthorizations < Rectify::Command
7
+ # Public: Initializes the command.
8
+ #
9
+ # organization - Organization object.
10
+ # current_user - The current user.
11
+ # form - A form object with the verification data to confirm it.
12
+ def initialize(organization, current_user, form)
13
+ @organization = organization
14
+ @current_user = current_user
15
+ @form = form
16
+ end
17
+
18
+ # Executes the command. Broadcasts these events:
19
+ #
20
+ # - :ok when everything is valid.
21
+ # - :invalid if the handler wasn't valid and we couldn't proceed.
22
+ #
23
+ # Returns nothing.
24
+ def call
25
+ return broadcast(:invalid) unless @organization
26
+ return broadcast(:invalid) unless @form.valid?
27
+
28
+ # Check before date
29
+ if @form.before_date.present?
30
+ authorizations_to_revoke = if @form.impersonated_only?
31
+ Decidim::Verifications::AuthorizationsBeforeDate.new(
32
+ organization: organization,
33
+ date: @form.before_date,
34
+ granted: true,
35
+ impersonated_only: @form.impersonated_only
36
+ )
37
+ else
38
+ Decidim::Verifications::AuthorizationsBeforeDate.new(
39
+ organization: organization,
40
+ date: @form.before_date,
41
+ granted: true
42
+ )
43
+ end
44
+
45
+ auths = authorizations_to_revoke.query
46
+ auths.find_each do |auth|
47
+ Decidim.traceability.perform_action!(
48
+ :destroy,
49
+ auth,
50
+ current_user
51
+ ) do
52
+ auth.destroy
53
+ end
54
+ end
55
+
56
+ broadcast(:ok)
57
+
58
+ else
59
+ broadcast(:invalid)
60
+ end
61
+ end
62
+
63
+ private
64
+
65
+ attr_reader :organization, :current_user, :form
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+
5
+ module Decidim
6
+ module Verifications
7
+ # Common logic to renew authorizations
8
+ module Renewable
9
+ extend ActiveSupport::Concern
10
+ included do
11
+ def renew
12
+ enforce_permission_to :renew, :authorization, authorization: authorization
13
+
14
+ DestroyUserAuthorization.call(authorization) do
15
+ on(:ok, authorization) do
16
+ flash[:notice] = t("authorizations.destroy.success", scope: "decidim.verifications")
17
+ redirect_to new_authorization_path(handler: authorization.name)
18
+ end
19
+
20
+ on(:invalid) do
21
+ flash[:alert] = t("authorizations.destroy.error", scope: "decidim.verifications")
22
+ redirect_to authorizations_path
23
+ end
24
+ end
25
+ end
26
+
27
+ def renew_modal
28
+ enforce_permission_to :renew, :authorization, authorization: authorization
29
+
30
+ respond_to do |format|
31
+ format.html { render layout: nil }
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Verifications
5
+ module Admin
6
+ class VerificationsController < Decidim::Admin::ApplicationController
7
+ def destroy_before_date
8
+ enforce_permission_to :destroy, :authorization
9
+ return unless params.has_key?(:revocations_before_date)
10
+
11
+ form = RevocationsBeforeDateForm.from_params(params[:revocations_before_date])
12
+ RevokeByConditionAuthorizations.call(current_organization, current_user, form) do
13
+ on(:ok) do
14
+ flash[:notice] = t("authorization_revocation.destroy_ok", scope: "decidim.admin.menu")
15
+ redirect_to decidim_admin.authorization_workflows_url
16
+ end
17
+ on(:invalid) do
18
+ flash.now[:alert] = t("authorization_revocation.destroy_nok", scope: "decidim.admin.menu")
19
+ redirect_to decidim_admin.authorization_workflows_url
20
+ end
21
+ end
22
+ end
23
+
24
+ def destroy_all
25
+ enforce_permission_to :destroy, :authorization
26
+ RevokeAllAuthorizations.call(current_organization, current_user) do
27
+ on(:ok) do
28
+ flash[:notice] = t("authorization_revocation.destroy_ok", scope: "decidim.admin.menu")
29
+ redirect_to decidim_admin.authorization_workflows_url
30
+ end
31
+ on(:invalid) do
32
+ flash.now[:alert] = t("authorization_revocation.destroy_nok", scope: "decidim.admin.menu")
33
+ redirect_to decidim_admin.authorization_workflows_url
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end