decidim-verifications 0.30.9 → 0.31.0.rc1

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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -5
  3. data/app/commands/decidim/verifications/csv_census/admin/create_census_data.rb +5 -4
  4. data/app/commands/decidim/verifications/csv_census/admin/create_census_record.rb +23 -0
  5. data/app/commands/decidim/verifications/csv_census/admin/update_census_record.rb +15 -0
  6. data/app/controllers/concerns/decidim/verifications/admin/filterable.rb +26 -0
  7. data/app/controllers/decidim/verifications/authorizations_controller.rb +1 -2
  8. data/app/controllers/decidim/verifications/csv_census/admin/census_controller.rb +57 -16
  9. data/app/controllers/decidim/verifications/csv_census/admin/census_records_controller.rb +63 -0
  10. data/app/controllers/decidim/verifications/id_documents/admin/config_controller.rb +1 -1
  11. data/app/controllers/decidim/verifications/id_documents/admin/confirmations_controller.rb +2 -3
  12. data/app/controllers/decidim/verifications/id_documents/admin/offline_confirmations_controller.rb +1 -1
  13. data/app/controllers/decidim/verifications/id_documents/admin/rejections_controller.rb +1 -2
  14. data/app/controllers/decidim/verifications/id_documents/authorizations_controller.rb +2 -2
  15. data/app/controllers/decidim/verifications/postal_letter/admin/postages_controller.rb +1 -2
  16. data/app/controllers/decidim/verifications/postal_letter/authorizations_controller.rb +2 -2
  17. data/app/controllers/decidim/verifications/sms/authorizations_controller.rb +2 -2
  18. data/app/forms/decidim/verifications/csv_census/admin/census_data_form.rb +29 -3
  19. data/app/forms/decidim/verifications/csv_census/admin/census_form.rb +29 -0
  20. data/app/forms/decidim/verifications/sms/mobile_phone_form.rb +2 -2
  21. data/app/jobs/decidim/verifications/csv_census/process_census_data_job.rb +49 -0
  22. data/app/models/decidim/verifications/csv_census/data.rb +13 -1
  23. data/app/models/decidim/verifications/csv_datum.rb +21 -0
  24. data/app/packs/entrypoints/decidim_verifications.js +3 -0
  25. data/app/packs/src/csv_census.js +47 -0
  26. data/app/presenters/decidim/verifications/admin_log/csv_datum_presenter.rb +45 -0
  27. data/app/services/decidim/authorization_handler.rb +1 -1
  28. data/app/views/decidim/verifications/authorizations/new.html.erb +1 -1
  29. data/app/views/decidim/verifications/authorizations/onboarding_pending.html.erb +1 -1
  30. data/app/views/decidim/verifications/csv_census/admin/census/_csv_census_drawer.html.erb +5 -0
  31. data/app/views/decidim/verifications/csv_census/admin/census/index.html.erb +73 -51
  32. data/app/views/decidim/verifications/csv_census/admin/census/new_import.html.erb +27 -0
  33. data/app/views/decidim/verifications/csv_census/admin/census_records/_form.html.erb +9 -0
  34. data/app/views/decidim/verifications/csv_census/admin/census_records/edit_record.html.erb +14 -0
  35. data/app/views/decidim/verifications/csv_census/admin/census_records/new_record.html.erb +14 -0
  36. data/app/views/decidim/verifications/id_documents/admin/confirmations/new.html.erb +1 -1
  37. data/app/views/decidim/verifications/id_documents/admin/pending_authorizations/index.html.erb +1 -1
  38. data/app/views/decidim/verifications/id_documents/authorizations/_form.html.erb +1 -3
  39. data/app/views/decidim/verifications/postal_letter/admin/pending_authorizations/index.html.erb +33 -17
  40. data/config/assets.rb +2 -2
  41. data/config/locales/ar.yml +5 -5
  42. data/config/locales/bg.yml +6 -12
  43. data/config/locales/ca-IT.yml +65 -20
  44. data/config/locales/ca.yml +65 -20
  45. data/config/locales/cs.yml +48 -16
  46. data/config/locales/de.yml +67 -17
  47. data/config/locales/el.yml +5 -5
  48. data/config/locales/en.yml +62 -17
  49. data/config/locales/es-MX.yml +67 -22
  50. data/config/locales/es-PY.yml +67 -22
  51. data/config/locales/es.yml +65 -20
  52. data/config/locales/eu.yml +67 -22
  53. data/config/locales/fi-plain.yml +66 -21
  54. data/config/locales/fi.yml +66 -21
  55. data/config/locales/fr-CA.yml +11 -12
  56. data/config/locales/fr.yml +11 -12
  57. data/config/locales/gl.yml +6 -5
  58. data/config/locales/hu.yml +6 -12
  59. data/config/locales/id-ID.yml +5 -5
  60. data/config/locales/is-IS.yml +1 -0
  61. data/config/locales/it.yml +6 -5
  62. data/config/locales/ja.yml +64 -19
  63. data/config/locales/lt.yml +6 -12
  64. data/config/locales/lv.yml +5 -5
  65. data/config/locales/nl.yml +6 -5
  66. data/config/locales/no.yml +6 -5
  67. data/config/locales/pl.yml +6 -12
  68. data/config/locales/pt-BR.yml +5 -124
  69. data/config/locales/pt.yml +6 -5
  70. data/config/locales/ro-RO.yml +52 -17
  71. data/config/locales/ru.yml +1 -0
  72. data/config/locales/sk.yml +5 -153
  73. data/config/locales/sv.yml +68 -34
  74. data/config/locales/tr-TR.yml +6 -12
  75. data/config/locales/uk.yml +1 -0
  76. data/config/locales/zh-CN.yml +5 -5
  77. data/config/locales/zh-TW.yml +6 -12
  78. data/lib/decidim/verifications/adapter.rb +3 -3
  79. data/lib/decidim/verifications/csv_census/admin_engine.rb +10 -2
  80. data/lib/decidim/verifications/engine.rb +1 -1
  81. data/lib/decidim/verifications/version.rb +1 -1
  82. data/lib/decidim/verifications/workflows.rb +3 -58
  83. data/lib/decidim/verifications.rb +1 -1
  84. data/lib/tasks/revoke.rake +16 -0
  85. metadata +22 -11
  86. data/app/controllers/concerns/decidim/verifications/admin/pending_authorization_loader.rb +0 -21
  87. data/app/jobs/decidim/verifications/csv_census/remove_duplicates_job.rb +0 -30
  88. data/lib/decidim/verifications/registry.rb +0 -43
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4a228b31c634cc5bfa2dfcef5a67b941ec4c88118b861fd544675de57aa6e5b9
4
- data.tar.gz: 55e0d4f261d03c2077141f07d6e103cd3eebf86537d0acfd6ad7523951c21dbc
3
+ metadata.gz: 7f5e445b04ef228652e17ed056aa508198045f6f2a8709a06e6f918ae32e31a2
4
+ data.tar.gz: e1ef5356582bcab1d2eadb41a71fde9c3980751ee08495c54e175410f10c83ec
5
5
  SHA512:
6
- metadata.gz: 8b82a6b2fd9b77908c4bb9b5568e9a25420382cdf32f7ae301122baca830fd9676fba599281ab8a4e7bafae1426b1d2b9d86be099515ac7ac035909c33acc1ef
7
- data.tar.gz: 34d1d452bd53c2afa63e27e6cf0bb781a42068c5b58bcc5b10e9864dd8cb764e3aca757595fbe333720c493db678614240b7ca840948483be591d8a777c79dd5
6
+ metadata.gz: 1a46cbde1f71b5818775a8ef8b6f741945fd2b7bc5c3368ae849aa93e66cccf2e963cec21e7c7118616f294cd5f9b028d9c853433870fa942a8e8d2995f7976d
7
+ data.tar.gz: 78f7b084de6123dfd783f868d9ef674b25e9f35a0f2beba5150f18153fc635ca25dcf6edaa06379ad8bcbda46ba5ecdf7d4fa3e50e6cede99ce01b3ebca7da7c
data/README.md CHANGED
@@ -59,7 +59,7 @@ Decidim implements two type of authorization methods:
59
59
  To register your handler, use
60
60
 
61
61
  ```ruby
62
- # config/initializers/decidim.rb
62
+ # config/initializers/decidim_verifications.rb
63
63
 
64
64
  Decidim::Verifications.register_workflow(:census) do |workflow|
65
65
  workflow.form = "<myAuthorizationHandlerClass>"
@@ -74,7 +74,7 @@ Decidim implements two type of authorization methods:
74
74
  For example:
75
75
 
76
76
  ```ruby
77
- # config/initializers/decidim.rb
77
+ # config/initializers/decidim_verifications.rb
78
78
 
79
79
  Decidim::Verifications.register_workflow(:my_verification) do |workflow|
80
80
  workflow.engine = Decidim::Verifications::MyVerification::Engine
@@ -103,7 +103,7 @@ Decidim implements two type of authorization methods:
103
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
104
 
105
105
  ```ruby
106
- # config/initializers/decidim.rb
106
+ # config/initializers/decidim_verifications.rb
107
107
 
108
108
  Decidim::Verifications.register_workflow(:census) do |workflow|
109
109
  workflow.form = "myAuthorizationHandlerClass"
@@ -146,7 +146,7 @@ SMS code using your preferred provider.
146
146
  In order to setup Decidim with SMS verification you need to:
147
147
 
148
148
  1. Create a class that accepts two parameters when initializing it (mobile phone and code) and a method named `deliver_code` that will send an SMS and return a truthy or falsey value if the delivery was OK or not.
149
- 1. Set the `sms_gateway_service` configuration variable to the name of the class that you just created (use a String, not the actual class) at `config/initializers/decidim.rb`.
149
+ 1. Set the `sms_gateway_service` configuration variable to the name of the class that you just created (use a String, not the actual class) using the `DECIDIM_SMS_GATEWAY_SERVICE` environment variable
150
150
 
151
151
  Keep in mind that Decidim will not store a free text version of the mobile phone, only a hashed
152
152
  version so we can avoid duplicates and guarantee the users' privacy.
@@ -217,7 +217,7 @@ To be used by the verification method, this class should be referenced by name i
217
217
  its workflow manifest:
218
218
 
219
219
  ```ruby
220
- # config/initializers/decidim.rb
220
+ # config/initializers/decidim_verifications.rb
221
221
 
222
222
  Decidim::Verifications.register_workflow(:my_verification) do |workflow|
223
223
  workflow.engine = Decidim::Verifications::MyVerification::Engine
@@ -7,9 +7,10 @@ module Decidim
7
7
  # A command with the business logic to create census data for a
8
8
  # organization.
9
9
  class CreateCensusData < Decidim::Command
10
- def initialize(form, organization)
10
+ def initialize(form, current_user)
11
11
  @form = form
12
- @organization = organization
12
+ @current_user = current_user
13
+ @organization = current_user.organization
13
14
  end
14
15
 
15
16
  # Executes the command. Broadcast this events:
@@ -21,13 +22,13 @@ module Decidim
21
22
  return broadcast(:invalid) unless @form.file
22
23
 
23
24
  data = @form.data
24
- return broadcast(:invalid) unless data
25
+ return broadcast(:invalid) if data.blank? || data.values.empty?
25
26
 
26
27
  # rubocop:disable Rails/SkipsModelValidations
27
28
  CsvDatum.insert_all(@organization, data.values)
28
29
  # rubocop:enable Rails/SkipsModelValidations
29
- RemoveDuplicatesJob.perform_later(@organization)
30
30
 
31
+ ProcessCensusDataJob.perform_later(data.values, @current_user)
31
32
  broadcast(:ok)
32
33
  end
33
34
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Verifications
5
+ module CsvCensus
6
+ module Admin
7
+ # A command with the business logic to create census data for a
8
+ # organization.
9
+ class CreateCensusRecord < Decidim::Commands::CreateResource
10
+ fetch_form_attributes :email, :organization
11
+
12
+ private
13
+
14
+ def resource_class = Decidim::Verifications::CsvDatum
15
+
16
+ def run_after_hooks
17
+ @resource.authorize!
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Verifications
5
+ module CsvCensus
6
+ module Admin
7
+ # A command with the business logic to create census data for a
8
+ # organization.
9
+ class UpdateCensusRecord < Decidim::Commands::UpdateResource
10
+ fetch_form_attributes :email
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+
5
+ module Decidim
6
+ module Verifications
7
+ module Admin
8
+ module Filterable
9
+ extend ActiveSupport::Concern
10
+
11
+ included do
12
+ include Decidim::Admin::Filterable
13
+
14
+ private
15
+
16
+ def base_query
17
+ CsvDatum
18
+ .where(organization: current_organization)
19
+ .page(params[:page])
20
+ .per(15)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -15,7 +15,6 @@ module Decidim
15
15
  include Decidim::HtmlSafeFlash
16
16
  include Decidim::Verifications::Renewable
17
17
  helper Decidim::DecidimFormHelper
18
- helper Decidim::CtaButtonHelper
19
18
  helper Decidim::AuthorizationFormHelper
20
19
  helper Decidim::TranslationsHelper
21
20
 
@@ -87,7 +86,7 @@ module Decidim
87
86
 
88
87
  on(:invalid) do
89
88
  flash[:alert] = t("authorizations.create.error", scope: "decidim.verifications")
90
- render action: :new
89
+ render action: :new, status: :unprocessable_entity
91
90
  end
92
91
  end
93
92
  end
@@ -10,53 +10,94 @@ module Decidim
10
10
  before_action :show_instructions,
11
11
  unless: :csv_census_active?
12
12
 
13
+ include Decidim::Verifications::Admin::Filterable
13
14
  include Decidim::Admin::WorkflowsBreadcrumb
15
+ include Decidim::Paginable
14
16
 
15
17
  add_breadcrumb_item_from_menu :workflows_menu
16
18
 
17
- def index
18
- enforce_permission_to :index, :authorization
19
+ helper_method :csv_census_data, :last_login
20
+
21
+ def index; end
22
+
23
+ def destroy
24
+ Decidim::Commands::DestroyResource.call(census_data, current_user) do
25
+ on(:ok) do
26
+ flash[:notice] = I18n.t("census.destroy.success", scope: "decidim.verifications.csv_census.admin")
27
+ redirect_to census_logs_path
28
+ end
29
+ end
30
+ end
19
31
 
20
- @form = form(CensusDataForm).instance
32
+ def new_import
33
+ @form = form(CensusDataForm).from_params(params)
21
34
  @status = Status.new(current_organization)
22
35
  end
23
36
 
24
- def create
37
+ def create_import
25
38
  enforce_permission_to :create, :authorization
26
-
27
39
  @form = form(CensusDataForm).from_params(params)
28
40
  @status = Status.new(current_organization)
29
- CreateCensusData.call(@form, current_organization) do
41
+
42
+ @form.validate_csv
43
+
44
+ if @form.errors.any?
45
+ error_messages = @form.errors.full_messages.map { |msg| "<li>#{msg}</li>" }.join
46
+ flash[:alert] = "<ul>#{error_messages}</ul>"
47
+ redirect_to(census_logs_path) && return
48
+ end
49
+
50
+ CreateCensusData.call(@form, current_user) do
30
51
  on(:ok) do
31
- flash[:notice] = t(".success", count: @form.data.values.count, errors: @form.data.errors.count)
32
- redirect_to census_path
52
+ flash[:notice] = I18n.t("census.create_import.success", scope: "decidim.verifications.csv_census.admin", count: @form.data.values.count)
53
+ redirect_to census_logs_path
33
54
  end
34
55
 
35
56
  on(:invalid) do
36
- flash[:alert] = t(".error")
37
- render :index
57
+ flash[:alert] = I18n.t("census.create_import.error", scope: "decidim.verifications.csv_census.admin")
58
+ redirect_to census_logs_path
38
59
  end
39
60
  end
40
61
  end
41
62
 
42
- def destroy_all
43
- enforce_permission_to :destroy, :authorization
44
- CsvDatum.clear(current_organization)
63
+ private
45
64
 
46
- redirect_to census_path, notice: t(".success")
65
+ def census_data
66
+ @census_data ||= CsvDatum.where(organization: current_organization).find(params[:id])
47
67
  end
48
68
 
49
- private
69
+ def csv_census_data
70
+ @csv_census_data ||= filtered_collection
71
+ end
72
+
73
+ def collection
74
+ @collection ||= CsvDatum.where(organization: current_organization)
75
+ end
50
76
 
51
77
  def show_instructions
52
78
  enforce_permission_to :index, :authorization
53
-
54
79
  render :instructions
55
80
  end
56
81
 
57
82
  def csv_census_active?
58
83
  current_organization.available_authorizations.include?("csv_census")
59
84
  end
85
+
86
+ def last_login(data)
87
+ user = current_organization.users.available.find_by(email: data.email)
88
+
89
+ return { icon: nil, text: t(".no_user"), last_sign_in: nil } unless user
90
+
91
+ authorized = Decidim::Authorization.where(name: "csv_census", user:)
92
+ .where.not(granted_at: nil)
93
+ .exists?
94
+
95
+ icon = authorized ? "checkbox-circle-line" : "close-circle-line"
96
+ text = authorized ? t("index.authorized", scope: "decidim.verifications.csv_census.admin") : t("index.no_authorized", scope: "decidim.verifications.csv_census.admin")
97
+ last_sign_in = user.last_sign_in_at ? l(user.last_sign_in_at, format: :decidim_short) : t(".no_sign_in")
98
+
99
+ { icon:, text:, last_sign_in: }
100
+ end
60
101
  end
61
102
  end
62
103
  end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Verifications
5
+ module CsvCensus
6
+ module Admin
7
+ class CensusRecordsController < Decidim::Admin::ApplicationController
8
+ layout false
9
+
10
+ helper_method :csv_census_data
11
+
12
+ def new_record
13
+ @form = form(Admin::CensusForm).instance
14
+ end
15
+
16
+ def create_record
17
+ @form = form(Admin::CensusForm).from_params(params)
18
+ Admin::CreateCensusRecord.call(@form) do
19
+ on(:ok) do
20
+ flash[:notice] = I18n.t("census_records.create_record.success", scope: "decidim.verifications.csv_census.admin")
21
+ render json: { redirect_url: census_logs_path }, status: :ok
22
+ end
23
+
24
+ on(:invalid) do
25
+ render :new_record, status: :unprocessable_entity
26
+ end
27
+ end
28
+ end
29
+
30
+ def edit_record
31
+ @form = form(Admin::CensusForm).from_model(census_data)
32
+ end
33
+
34
+ def update_record
35
+ @form = form(Admin::CensusForm).from_params(params)
36
+
37
+ Admin::UpdateCensusRecord.call(@form, census_data) do
38
+ on(:ok) do
39
+ flash[:notice] = I18n.t("census_records.update_record.success", scope: "decidim.verifications.csv_census.admin")
40
+ render json: { redirect_url: census_logs_path }, status: :ok
41
+ end
42
+
43
+ on(:invalid) do
44
+ flash.now[:alert] = I18n.t("census_records.update_record.invalid", scope: "decidim.verifications.csv_census.admin")
45
+ render action: "edit_record", status: :unprocessable_entity
46
+ end
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def census_data
53
+ @census_data ||= CsvDatum.where(organization: current_organization).find_by(id: params[:id])
54
+ end
55
+
56
+ def csv_census_data
57
+ @csv_census_data ||= CsvDatum.where(organization: current_organization)
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -33,7 +33,7 @@ module Decidim
33
33
 
34
34
  on(:invalid) do
35
35
  flash.now[:alert] = t("config.update.error", scope: "decidim.verifications.id_documents.admin")
36
- render action: :edit
36
+ render action: :edit, status: :unprocessable_entity
37
37
  end
38
38
  end
39
39
  end
@@ -13,7 +13,6 @@ module Decidim
13
13
  before_action :load_pending_authorization
14
14
 
15
15
  include Decidim::Admin::WorkflowsBreadcrumb
16
- include Decidim::Verifications::Admin::PendingAuthorizationLoader
17
16
 
18
17
  add_breadcrumb_item_from_menu :workflows_menu
19
18
 
@@ -36,7 +35,7 @@ module Decidim
36
35
 
37
36
  on(:invalid) do
38
37
  flash.now[:alert] = t("confirmations.create.error", scope: "decidim.verifications.id_documents.admin")
39
- render action: :new
38
+ render action: :new, status: :unprocessable_entity
40
39
  end
41
40
  end
42
41
  end
@@ -44,7 +43,7 @@ module Decidim
44
43
  private
45
44
 
46
45
  def load_pending_authorization
47
- @pending_authorization = load_pending_authorization!("id_documents", params[:pending_authorization_id])
46
+ @pending_authorization = Authorization.find(params[:pending_authorization_id])
48
47
  end
49
48
  end
50
49
  end
@@ -33,7 +33,7 @@ module Decidim
33
33
 
34
34
  on(:invalid) do
35
35
  flash.now[:alert] = t("offline_confirmations.create.error", scope: "decidim.verifications.id_documents.admin")
36
- render action: :new
36
+ render action: :new, status: :unprocessable_entity
37
37
  end
38
38
  end
39
39
  end
@@ -13,7 +13,6 @@ module Decidim
13
13
  before_action :load_pending_authorization
14
14
 
15
15
  include Decidim::Admin::WorkflowsBreadcrumb
16
- include Decidim::Verifications::Admin::PendingAuthorizationLoader
17
16
 
18
17
  add_breadcrumb_item_from_menu :workflows_menu
19
18
 
@@ -33,7 +32,7 @@ module Decidim
33
32
  private
34
33
 
35
34
  def load_pending_authorization
36
- @pending_authorization = load_pending_authorization!("id_documents", params[:pending_authorization_id])
35
+ @pending_authorization = Authorization.find(params[:pending_authorization_id])
37
36
  end
38
37
  end
39
38
  end
@@ -42,7 +42,7 @@ module Decidim
42
42
 
43
43
  on(:invalid) do
44
44
  flash.now[:alert] = t("authorizations.create.error", scope: "decidim.verifications.id_documents")
45
- render action: :new
45
+ render action: :new, status: :unprocessable_entity
46
46
  end
47
47
  end
48
48
  end
@@ -72,7 +72,7 @@ module Decidim
72
72
 
73
73
  on(:invalid) do
74
74
  flash.now[:alert] = t("authorizations.update.error", scope: "decidim.verifications.id_documents")
75
- render action: :edit
75
+ render action: :edit, status: :unprocessable_entity
76
76
  end
77
77
  end
78
78
  end
@@ -13,7 +13,6 @@ module Decidim
13
13
  before_action :load_pending_authorization
14
14
 
15
15
  include Decidim::Admin::WorkflowsBreadcrumb
16
- include Decidim::Verifications::Admin::PendingAuthorizationLoader
17
16
 
18
17
  add_breadcrumb_item_from_menu :workflows_menu
19
18
 
@@ -37,7 +36,7 @@ module Decidim
37
36
  private
38
37
 
39
38
  def load_pending_authorization
40
- @pending_authorization = load_pending_authorization!("postal_letter", params[:pending_authorization_id])
39
+ @pending_authorization = Authorization.find(params[:pending_authorization_id])
41
40
  end
42
41
  end
43
42
  end
@@ -29,7 +29,7 @@ module Decidim
29
29
 
30
30
  on(:invalid) do
31
31
  flash.now[:alert] = t("authorizations.create.error", scope: "decidim.verifications.postal_letter")
32
- render :new
32
+ render :new, status: :unprocessable_entity
33
33
  end
34
34
  end
35
35
  end
@@ -53,7 +53,7 @@ module Decidim
53
53
 
54
54
  on(:invalid) do
55
55
  flash.now[:alert] = t("authorizations.update.error", scope: "decidim.verifications.postal_letter")
56
- render :edit
56
+ render :edit, status: :unprocessable_entity
57
57
  end
58
58
  end
59
59
  end
@@ -27,7 +27,7 @@ module Decidim
27
27
  end
28
28
  on(:invalid) do
29
29
  flash.now[:alert] = t("authorizations.create.error", scope: "decidim.verifications.sms")
30
- render :new
30
+ render :new, status: :unprocessable_entity
31
31
  end
32
32
  end
33
33
  end
@@ -52,7 +52,7 @@ module Decidim
52
52
 
53
53
  on(:invalid) do
54
54
  flash.now[:alert] = t("authorizations.update.error", scope: "decidim.verifications.sms")
55
- render :edit
55
+ render :edit, status: :unprocessable_entity
56
56
  end
57
57
  end
58
58
  end
@@ -6,16 +6,42 @@ module Decidim
6
6
  module Admin
7
7
  # A form to temporarily upload csv census data
8
8
  class CensusDataForm < Form
9
+ include Decidim::HasUploadValidations
10
+ include Decidim::ProcessesFileLocally
9
11
  mimic :census_data
10
12
 
11
- attribute :file
13
+ attribute :file, Decidim::Attributes::Blob
14
+
15
+ validates :file, presence: true, file_content_type: { allow: ["text/csv"] }
12
16
 
13
17
  def data
14
- CsvCensus::Data.new(file.path)
18
+ @data ||= process_data
19
+ end
20
+
21
+ def process_data
22
+ process_file_locally(file) do |file_path|
23
+ CsvCensus::Data.new(file_path)
24
+ end
15
25
  rescue CSV::MalformedCSVError
16
26
  errors.add(:file, :malformed)
27
+ end
28
+
29
+ def validate_csv
30
+ return unless data
31
+
32
+ errors.add(:base, I18n.t("decidim.verifications.errors.wrong_number_columns", expected: 1, actual: data.count)) if data.count != 1
33
+
34
+ errors.add(:base, I18n.t("decidim.verifications.errors.no_emails")) if data.values.empty?
35
+
36
+ data.values.each do |value|
37
+ errors.add(:base, I18n.t("decidim.verifications.errors.invalid_emails", invalid_emails: value)) unless valid_email?(value)
38
+ end
39
+ end
40
+
41
+ private
17
42
 
18
- nil
43
+ def valid_email?(email)
44
+ URI::MailTo::EMAIL_REGEXP.match?(email)
19
45
  end
20
46
  end
21
47
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Verifications
5
+ module CsvCensus
6
+ module Admin
7
+ # A form to temporarily upload csv census data
8
+ class CensusForm < Form
9
+ attribute :email
10
+
11
+ validates :email, presence: true, "valid_email_2/email": { disposable: true }
12
+ validate :unique_email
13
+
14
+ private
15
+
16
+ def unique_email
17
+ return true if CsvDatum.where(
18
+ organization: context.current_organization,
19
+ email:
20
+ ).empty?
21
+
22
+ errors.add :email, :taken
23
+ false
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -17,7 +17,7 @@ module Decidim
17
17
 
18
18
  # A mobile phone can only be verified once but it should be private.
19
19
  def unique_id
20
- Digest::MD5.hexdigest(
20
+ Digest::SHA256.hexdigest(
21
21
  "#{mobile_phone_number}-#{Rails.application.secret_key_base}"
22
22
  )
23
23
  end
@@ -57,7 +57,7 @@ module Decidim
57
57
  end
58
58
 
59
59
  def generated_code
60
- @generated_code ||= SecureRandom.random_number(1_000_000).to_s
60
+ @generated_code ||= format("%06d", SecureRandom.random_number(1_000_000))
61
61
  end
62
62
  end
63
63
  end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Verifications
5
+ module CsvCensus
6
+ class ProcessCensusDataJob < ApplicationJob
7
+ queue_as :default
8
+ attr_reader :imported_records, :failed, :user
9
+
10
+ def perform(data, user)
11
+ @user = user
12
+ @imported_records = []
13
+ @failed = []
14
+
15
+ data.each do |email|
16
+ record = CsvDatum.find_or_create_by(email:, organization: user.organization)
17
+ if record && record.valid?
18
+ @imported_records << record
19
+ else
20
+ @failed << email
21
+ Rails.logger.warn(I18n.t("census.new_import.errors.email_exists", scope: "decidim.verifications.csv_census.admin", email:, organization: user.organization.id))
22
+ end
23
+
24
+ record.authorize!
25
+ end
26
+
27
+ log_import_action
28
+ end
29
+
30
+ private
31
+
32
+ def log_import_action
33
+ return if imported_records.blank?
34
+
35
+ Decidim::ActionLogger.log(
36
+ "import",
37
+ user,
38
+ imported_records.first,
39
+ nil,
40
+ extra: {
41
+ imported_records:,
42
+ failed_count: failed.count
43
+ }
44
+ )
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -14,20 +14,32 @@ module Decidim
14
14
  #
15
15
  # Returns nothing
16
16
  class Data
17
- attr_reader :errors, :values
17
+ attr_reader :errors, :values, :file
18
18
 
19
19
  def initialize(file)
20
20
  @file = file
21
21
  @values = []
22
22
  @errors = []
23
+ @column_count = nil
23
24
 
24
25
  CSV.foreach(@file, encoding: "BOM|UTF-8") do |row|
25
26
  process_row(row)
27
+ @column_count ||= row.size
26
28
  end
29
+
30
+ @errors << I18n.t("decidim.verifications.errors.wrong_number_columns", expected: 1, actual: @column_count) if @column_count && @column_count > 1
31
+ end
32
+
33
+ def count
34
+ @column_count || 0
27
35
  end
28
36
 
29
37
  private
30
38
 
39
+ def valid_email?(email)
40
+ URI::MailTo::EMAIL_REGEXP.match?(email)
41
+ end
42
+
31
43
  def process_row(row)
32
44
  user_mail = row.first
33
45
  if user_mail.present? && user_mail.match?(::Devise.email_regexp)