decidim-verifications 0.19.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) 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/models/decidim/verifications/csv_census/data.rb +1 -1
  22. data/app/queries/decidim/verifications/authorizations_before_date.rb +51 -0
  23. data/app/services/decidim/authorization_handler.rb +4 -0
  24. data/app/views/decidim/verifications/authorizations/_granted_authorization.html.erb +29 -24
  25. data/app/views/decidim/verifications/authorizations/first_login.html.erb +2 -2
  26. data/app/views/decidim/verifications/authorizations/index.html.erb +20 -11
  27. data/app/views/decidim/verifications/authorizations/new.html.erb +2 -2
  28. data/app/views/decidim/verifications/authorizations/renew_modal.html.erb +38 -0
  29. data/app/views/decidim/verifications/id_documents/authorizations/_form.html.erb +2 -0
  30. data/app/views/decidim/verifications/postal_letter/authorizations/edit.html.erb +2 -0
  31. data/app/views/decidim/verifications/postal_letter/authorizations/new.html.erb +2 -0
  32. data/app/views/decidim/verifications/sms/authorizations/edit.html.erb +2 -0
  33. data/app/views/decidim/verifications/sms/authorizations/new.html.erb +2 -0
  34. data/config/locales/ar.yml +2 -0
  35. data/config/locales/bg-BG.yml +17 -0
  36. data/config/locales/ca.yml +30 -0
  37. data/config/locales/cs.yml +30 -0
  38. data/config/locales/da-DK.yml +1 -0
  39. data/config/locales/de.yml +31 -0
  40. data/config/locales/el-GR.yml +1 -0
  41. data/config/locales/el.yml +258 -0
  42. data/config/locales/en.yml +30 -0
  43. data/config/locales/es-MX.yml +30 -0
  44. data/config/locales/es-PY.yml +30 -0
  45. data/config/locales/es.yml +30 -0
  46. data/config/locales/et-EE.yml +1 -0
  47. data/config/locales/eu.yml +2 -0
  48. data/config/locales/fi-plain.yml +30 -0
  49. data/config/locales/fi.yml +40 -10
  50. data/config/locales/fr-CA.yml +258 -0
  51. data/config/locales/fr.yml +30 -0
  52. data/config/locales/ga-IE.yml +1 -0
  53. data/config/locales/gl.yml +2 -0
  54. data/config/locales/hr-HR.yml +1 -0
  55. data/config/locales/hu.yml +23 -0
  56. data/config/locales/id-ID.yml +2 -0
  57. data/config/locales/is-IS.yml +120 -0
  58. data/config/locales/it.yml +31 -0
  59. data/config/locales/ja-JP.yml +257 -0
  60. data/config/locales/lt-LT.yml +1 -0
  61. data/config/locales/lv-LV.yml +250 -0
  62. data/config/locales/mt-MT.yml +1 -0
  63. data/config/locales/nl.yml +52 -22
  64. data/config/locales/no.yml +226 -0
  65. data/config/locales/pl.yml +31 -0
  66. data/config/locales/pt-BR.yml +3 -1
  67. data/config/locales/pt.yml +125 -94
  68. data/config/locales/ro-RO.yml +259 -0
  69. data/config/locales/sk-SK.yml +258 -0
  70. data/config/locales/sk.yml +258 -0
  71. data/config/locales/sl.yml +5 -0
  72. data/config/locales/sr-CS.yml +1 -0
  73. data/config/locales/sv.yml +31 -0
  74. data/config/locales/tr-TR.yml +2 -0
  75. data/lib/decidim/verifications/adapter.rb +12 -0
  76. data/lib/decidim/verifications/csv_census/engine.rb +3 -1
  77. data/lib/decidim/verifications/engine.rb +13 -0
  78. data/lib/decidim/verifications/id_documents/engine.rb +1 -0
  79. data/lib/decidim/verifications/postal_letter/engine.rb +3 -1
  80. data/lib/decidim/verifications/sms/engine.rb +3 -1
  81. data/lib/decidim/verifications/version.rb +1 -1
  82. data/lib/decidim/verifications/workflow_manifest.rb +3 -0
  83. data/lib/decidim/verifications/workflows.rb +1 -1
  84. metadata +39 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2031448fe03c504353397420e98549ea5f90c353591ac4b7846f3f119e3413df
4
- data.tar.gz: 5d27d011a65c64c4cc2c8b5c2a6e5b75bbaaccca6a4af0f9998e76d7d23661a2
3
+ metadata.gz: ee208339d39a5f1b778599a3c9645999e76475fb1f413e72a78c276e5fe09e1a
4
+ data.tar.gz: 48d43893269f7caf25a6cad9d9139e140f9f746b298e776e05d50dc8469bea35
5
5
  SHA512:
6
- metadata.gz: ce6e22177bebe2537209cb415a70127fb53aff4a85822d271f5296c4893ff8fa7ae33da902b5b1abcf0a7c3de2ec48c2cb7d5532dca346ae88086b84c6e5fda0
7
- data.tar.gz: 8dd934602ce6e073edc198e964207dec7ea3d6d052dea2a78f145ff6a13c0d5c25779e3b4b3abaa8e9c3adc440da99d57c05d4597a5465adf6688c8e288ec418
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