decidim-file_authorization_handler 0.27.1.5

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 (40) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +661 -0
  3. data/README.md +137 -0
  4. data/Rakefile +3 -0
  5. data/app/controllers/decidim/file_authorization_handler/admin/censuses_controller.rb +34 -0
  6. data/app/jobs/decidim/file_authorization_handler/application_job.rb +8 -0
  7. data/app/jobs/decidim/file_authorization_handler/remove_duplicates_job.rb +30 -0
  8. data/app/models/decidim/file_authorization_handler/application_record.rb +9 -0
  9. data/app/models/decidim/file_authorization_handler/census_datum.rb +70 -0
  10. data/app/models/decidim/file_authorization_handler/csv_data.rb +40 -0
  11. data/app/models/decidim/file_authorization_handler/status.rb +27 -0
  12. data/app/permissions/decidim/file_authorization_handler/admin/permissions.rb +27 -0
  13. data/app/services/file_authorization_handler.rb +59 -0
  14. data/app/views/decidim/file_authorization_handler/admin/censuses/show.html.erb +39 -0
  15. data/app/views/layouts/file_authorization_handler/application.html.erb +14 -0
  16. data/config/locales/ca.yml +50 -0
  17. data/config/locales/en.yml +50 -0
  18. data/config/locales/es.yml +50 -0
  19. data/db/migrate/20171110120821_create_decidim_file_authorization_handler_census_datum.rb +15 -0
  20. data/db/migrate/20221207143742_add_extras_to_census_datum.rb +7 -0
  21. data/lib/decidim/file_authorization_handler/admin.rb +10 -0
  22. data/lib/decidim/file_authorization_handler/admin_engine.rb +23 -0
  23. data/lib/decidim/file_authorization_handler/engine.rb +22 -0
  24. data/lib/decidim/file_authorization_handler/version.rb +12 -0
  25. data/lib/decidim/file_authorization_handler.rb +11 -0
  26. data/spec/controllers/decidim/file_authorization_handler/admin/censuses_controller_spec.rb +57 -0
  27. data/spec/factories/census_datum.rb +14 -0
  28. data/spec/factories/factories.rb +3 -0
  29. data/spec/fixtures/files/data-with_extras.csv +5 -0
  30. data/spec/fixtures/files/data1.csv +4 -0
  31. data/spec/fixtures/files/with-errors.csv +7 -0
  32. data/spec/helpers/decidim/file_authorization_handler/encoding_helper.rb +11 -0
  33. data/spec/jobs/decidim/file_authorization_handler/remove_duplicates_job_spec.rb +20 -0
  34. data/spec/models/decidim/file_authorization_handler/census_datum_spec.rb +75 -0
  35. data/spec/models/decidim/file_authorization_handler/csv_data_spec.rb +41 -0
  36. data/spec/models/decidim/file_authorization_handler/status_spec.rb +21 -0
  37. data/spec/permissions/decidim/file_authorization_handler/admin/permissions_spec.rb +58 -0
  38. data/spec/services/decidim/file_authorization_handler/file_authorization_handler_spec.rb +77 -0
  39. data/spec/spec_helper.rb +23 -0
  40. metadata +196 -0
data/README.md ADDED
@@ -0,0 +1,137 @@
1
+ # Decidim File Authorization Handler
2
+
3
+ > A plugin to add a csv based authorization handler to the Decidim platform
4
+
5
+ Allows admin users to upload a CSV file containing Document IDs and birthdates
6
+ to a given organization.
7
+ This information is used by a Decidim authorization handler to authorize real
8
+ users.
9
+
10
+ ## Usage
11
+
12
+ This module provides a model `Decidim::FileAuthorizationHandler::CensusDatum`
13
+ to store census information (identity document and birth date) in a hashed way
14
+ (real data is never stored).
15
+
16
+ It has an admin controller to upload CSV files with the information. When
17
+ importing files all records are inserted and the duplicates are removed in a
18
+ background job for performance reasons.
19
+
20
+ To keep the plugin simple the uploaded file is processed when the file is
21
+ uploaded.
22
+ Uploading the file to a temporary storage system and processing it in
23
+ background is kept out of the scope for the first release.
24
+
25
+ ### CSV file format
26
+
27
+ The CSV file format is not configurable, but is extendable. The plugin expects a comma separated
28
+ CSV with headers:
29
+
30
+ ```console
31
+ ID_NUMBER,BIRTH_DATE
32
+ 00000000Z,07/03/2014
33
+ ```
34
+
35
+ - ID_NUMBER: No format restrictions
36
+ - BIRTHDATE: `dd/mm/YYYY` format
37
+
38
+ The CSV separator can be overriden at installation level by using an
39
+ initializer:
40
+
41
+ ```ruby
42
+ # config/initializers/file_authorization_handler.rb
43
+ Decidim::FileAuthorizationHandler::CsvData.col_sep= ";"
44
+ ```
45
+
46
+ #### Extra columns
47
+
48
+ Sometimes extra fields must be provided in order for Authorizers to do some census segmentation. This, for example,
49
+ happens when a specific authorizer checks for the district of the citizen.
50
+
51
+ Since v0.26.2.5 this module supports a variable number of extra columns for each user. These columns are then persisted
52
+ in the `CensusDatum#extras` column as a hash of fields.
53
+
54
+ Take, for example, the following CSV file
55
+
56
+ ```console
57
+ ID_NUMBER,BIRTH_DATE,DISTRICT
58
+ 00000000Z,07/03/2014,17600
59
+ ```
60
+
61
+ it will be imported into the `CensusDatum` as `{"district" => "17600"}`.
62
+
63
+ Then, once the user is verified, all `CensusDaum#extras` will be added to the `Authorization#metadata` together with the `birthdate`. This way, custom authorizers will be able to make use of this information.
64
+
65
+ Implementors and administrators must respect User Privacy and be aware of the corresponding Rules.
66
+
67
+ ### Overriding Authorization Handler name
68
+
69
+ The authorization handler name is a default one not suitable for end users.
70
+ Depending on the use case of the gem needs to be overriden accordingly.
71
+
72
+ Override the following keys to modify the name of the authorization handler and
73
+ its description:
74
+
75
+ `decidim.authorization_handlers.file_authorization_handler.name`
76
+ `decidim.authorization_handlers.file_authorization_handler.description`
77
+
78
+ You can also override the name of the ID document and birthdate fields:
79
+
80
+ `activemodel.attributes.file_authorization_handler.id_document`
81
+ `activemodel.attributes.file_authorization_handler.birthdate`
82
+
83
+ ## Installation
84
+
85
+ Add this line to your application's Gemfile:
86
+
87
+ ```ruby
88
+ gem 'decidim-file_authorization_handler'
89
+ ```
90
+
91
+ And then execute:
92
+
93
+ ```bash
94
+ bundle
95
+ bin/rails decidim_file_authorization_handler:install:migrations
96
+ bin/rails db:migrate
97
+ ```
98
+
99
+ Finally, add the following line to your `config/routes.rb` file:
100
+
101
+ ```ruby
102
+ mount Decidim::FileAuthorizationHandler::AdminEngine => '/admin'
103
+ ```
104
+
105
+ ## Run tests
106
+
107
+ Node 16.9.1 is required!
108
+
109
+ Create a dummy app in your application (if not present):
110
+
111
+ ```bash
112
+ bin/rails decidim:generate_external_test_app
113
+ cd spec/decidim_dummy_app/
114
+ bundle exec rails decidim_file_authorization_handler:install:migrations
115
+ RAILS_ENV=test bundle exec rails db:migrate
116
+ ```
117
+
118
+ And run tests:
119
+
120
+ ```bash
121
+ bundle exec rspec spec
122
+ ```
123
+
124
+ ## Troubleshooting
125
+
126
+ If you find the following error after you have installed the engine:
127
+
128
+ ```
129
+ undefined method 'decidim_file_authorization_handler_admin_path'
130
+ for module#<Module:0x00007fa2aa4e2a10>
131
+ ```
132
+
133
+ review if you have mounted the Engine routes into your application routes.
134
+
135
+ ## License
136
+
137
+ AGPLv3 (same as Decidim)
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "decidim/dev/common_rake"
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module FileAuthorizationHandler
5
+ module Admin
6
+ class CensusesController < Decidim::Admin::ApplicationController
7
+ def show
8
+ enforce_permission_to :show, :authorization
9
+ @status = Status.new(current_organization)
10
+ end
11
+
12
+ def create
13
+ enforce_permission_to :create, :authorization
14
+ if params[:file]
15
+ data = CsvData.new(params[:file].path)
16
+ # rubocop: disable Rails/SkipsModelValidations
17
+ CensusDatum.insert_all(current_organization, data.values, data.headers[2..])
18
+ # rubocop: enable Rails/SkipsModelValidations
19
+ RemoveDuplicatesJob.perform_later(current_organization)
20
+ flash[:notice] = t(".success", count: data.values.count,
21
+ errors: data.errors.count)
22
+ end
23
+ redirect_to censuses_path
24
+ end
25
+
26
+ def destroy
27
+ enforce_permission_to :destroy, :authorization, organization: current_organization
28
+ CensusDatum.clear(current_organization)
29
+ redirect_to censuses_path, notice: t(".success")
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module FileAuthorizationHandler
5
+ class ApplicationJob < ActiveJob::Base
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module FileAuthorizationHandler
5
+ class RemoveDuplicatesJob < ApplicationJob
6
+ queue_as :default
7
+
8
+ # rubocop:disable Style/HashSyntax
9
+ def perform(organization)
10
+ duplicated_census(organization).pluck(:id_document).each do |id_document|
11
+ CensusDatum.inside(organization)
12
+ .where(id_document: id_document)
13
+ .order(id: :desc)
14
+ .all[1..]
15
+ .each(&:delete)
16
+ end
17
+ end
18
+ # rubocop:enable Style/HashSyntax
19
+
20
+ private
21
+
22
+ def duplicated_census(organization)
23
+ CensusDatum.inside(organization)
24
+ .select(:id_document)
25
+ .group(:id_document)
26
+ .having("count(id_document)>1")
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module FileAuthorizationHandler
5
+ class ApplicationRecord < ActiveRecord::Base
6
+ self.abstract_class = true
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module FileAuthorizationHandler
5
+ class CensusDatum < ApplicationRecord
6
+ belongs_to :organization, foreign_key: :decidim_organization_id,
7
+ class_name: "Decidim::Organization"
8
+ # An organzation scope
9
+ def self.inside(organization)
10
+ where(decidim_organization_id: organization.id)
11
+ end
12
+
13
+ # Search for a specific document id inside a organization
14
+ def self.search_id_document(organization, id_document)
15
+ CensusDatum.inside(organization)
16
+ .where(id_document: normalize_and_encode_id_document(id_document))
17
+ .order(created_at: :desc, id: :desc)
18
+ .first
19
+ end
20
+
21
+ # Normalizes a id document string (remove invalid characters) and encode it
22
+ # to conform with Decidim privacy guidelines.
23
+ def self.normalize_and_encode_id_document(id_document)
24
+ return "" unless id_document
25
+
26
+ id_document = id_document.gsub(/[^A-z0-9]/, "").upcase
27
+ return "" if id_document.blank?
28
+
29
+ Digest::SHA256.hexdigest(
30
+ "#{id_document}-#{Rails.application.secrets.secret_key_base}"
31
+ )
32
+ end
33
+
34
+ # Convert a date from string to a Date object
35
+ def self.parse_date(string)
36
+ Date.strptime((string || "").strip, "%d/%m/%Y")
37
+ rescue StandardError
38
+ nil
39
+ end
40
+
41
+ # Insert a collection of values
42
+ def self.insert_all(organization, values, extra_headers = nil)
43
+ return if values.empty?
44
+
45
+ table_name = CensusDatum.table_name
46
+ columns = %w(id_document birthdate decidim_organization_id created_at).join(",")
47
+ columns = "#{columns},extras" if extra_headers.present?
48
+ now = Time.current
49
+ values = values.map do |row|
50
+ vals = "('#{row[0]}', '#{row[1]}', '#{organization.id}', '#{now}'"
51
+ if extra_headers.present?
52
+ extras = {}
53
+ extra_headers.present? && extra_headers.each_with_index do |header, idx|
54
+ extras[header.downcase] = row[2 + idx]
55
+ end
56
+ vals += ", '#{extras.to_json}'"
57
+ end
58
+ "#{vals})"
59
+ end
60
+ sql = "INSERT INTO #{table_name} (#{columns}) VALUES #{values.join(",")}"
61
+ ActiveRecord::Base.connection.execute(sql)
62
+ end
63
+
64
+ # Clear all census data for a given organization
65
+ def self.clear(organization)
66
+ CensusDatum.inside(organization).delete_all
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "csv"
4
+
5
+ module Decidim
6
+ module FileAuthorizationHandler
7
+ class CsvData
8
+ @col_sep = ","
9
+ class << self; attr_accessor :col_sep end
10
+
11
+ attr_reader :errors, :values, :headers
12
+
13
+ def initialize(file)
14
+ @file = file
15
+ @errors = []
16
+ @values = []
17
+
18
+ Rails.logger.info "CsvData.col_sep: #{CsvData.col_sep}"
19
+ CSV.foreach(@file, headers: true, col_sep: CsvData.col_sep) do |row|
20
+ @headers = row.headers
21
+ process_row(row)
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def process_row(row)
28
+ id_document = CensusDatum.normalize_and_encode_id_document(row[0])
29
+ date = CensusDatum.parse_date(row[1])
30
+
31
+ if id_document.present? && !date.nil?
32
+ data = [id_document, date] + row[2..]
33
+ values << data
34
+ else
35
+ errors << row
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module FileAuthorizationHandler
5
+ # Provides information about the current status of the census data
6
+ # for a given organization
7
+ class Status
8
+ def initialize(organization)
9
+ @organization = organization
10
+ end
11
+
12
+ # Returns the date of the last import
13
+ def last_import_at
14
+ @last ||= CensusDatum.inside(@organization)
15
+ .order(created_at: :desc).first
16
+ @last ? @last.created_at : nil
17
+ end
18
+
19
+ # Returns the number of unique census
20
+ def count
21
+ @count ||= CensusDatum.inside(@organization)
22
+ .distinct.count(:id_document)
23
+ @count
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module FileAuthorizationHandler
5
+ module Admin
6
+ # Defines the abilities related to surveys for a logged in admin user.
7
+ class Permissions < Decidim::DefaultPermissions
8
+ def permissions
9
+ return permission_action if permission_action.scope != :admin
10
+
11
+ if user.organization.available_authorizations.include?("file_authorization_handler") &&
12
+ permission_action_in?(:show, :create, :destroy) &&
13
+ permission_action.subject == Decidim::FileAuthorizationHandler::CensusDatum
14
+ allow!
15
+ end
16
+ permission_action
17
+ end
18
+
19
+ private
20
+
21
+ def permission_action_in?(*actions)
22
+ actions.any? { |action| permission_action.action == action }
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ # An AuthorizationHandler that uses information uploaded from a CSV file
4
+ # to authorize against the age of the user
5
+ class FileAuthorizationHandler < Decidim::AuthorizationHandler
6
+ # This is the input (from the user) to validate against
7
+ attribute :id_document, String
8
+ attribute :birthdate, Decidim::Attributes::LocalizedDate
9
+
10
+ # This is the validation to perform
11
+ # If passed, an authorization is created
12
+ validates :id_document, presence: true
13
+ validates :birthdate, presence: true
14
+ validate :censed
15
+
16
+ def metadata
17
+ @metadata ||= begin
18
+ meta = { birthdate: census_for_user&.birthdate&.strftime("%Y/%m/%d") }
19
+ census_for_user&.extras&.each_pair do |key, value|
20
+ meta[key.to_sym] = value
21
+ end
22
+ meta
23
+ end
24
+ end
25
+
26
+ # This is required in new 0.8.4 version of decicim
27
+ # however, there's a bug and this doesn't work
28
+ def handler_name
29
+ +"file_authorization_handler"
30
+ end
31
+
32
+ # Checks if the id_document belongs to the census
33
+ def censed
34
+ return if census_for_user&.birthdate == birthdate
35
+
36
+ errors.add(:id_document, I18n.t("decidim.file_authorization_handler.errors.messages.not_censed"))
37
+ end
38
+
39
+ def authorized?
40
+ return true if census_for_user
41
+ end
42
+
43
+ def unique_id
44
+ return nil unless organization
45
+
46
+ Digest::SHA256.hexdigest("#{census_for_user&.id_document}-#{organization.id}-#{Rails.application.secrets.secret_key_base}")
47
+ end
48
+
49
+ def census_for_user
50
+ return unless organization
51
+
52
+ @census_for_user ||= Decidim::FileAuthorizationHandler::CensusDatum
53
+ .search_id_document(organization, id_document)
54
+ end
55
+
56
+ def organization
57
+ current_organization || user&.organization
58
+ end
59
+ end
@@ -0,0 +1,39 @@
1
+
2
+ <div class="card">
3
+ <div class="card-divider">
4
+ <h2 class="card-title">
5
+ <%= t('admin.show.title', scope: 'decidim.file_authorization_handler') %>
6
+ </h2>
7
+ </div>
8
+ <div class="card-section">
9
+ <% if @status.count > 0 %>
10
+ <p><%= t('decidim.file_authorization_handler.admin.show.data', count: @status.count,
11
+ due_date: l(@status.last_import_at, format: :long)) %>
12
+ </p>
13
+ <%= link_to t('decidim.file_authorization_handler.admin.destroy.title'),
14
+ censuses_path,
15
+ method: :delete,
16
+ class: 'button alert',
17
+ data: { confirm: t('decidim.file_authorization_handler.admin.destroy.confirm') } %>
18
+ <% else %>
19
+ <p><%= t('admin.show.empty', scope: 'decidim.file_authorization_handler') %></p>
20
+ <% end %>
21
+ </div>
22
+ </div>
23
+
24
+
25
+ <div class="card">
26
+ <div class="card-divider">
27
+ <h2 class="card-title">
28
+ <%= t('admin.new.title', scope: 'decidim.file_authorization_handler') %>
29
+ </h2>
30
+ </div>
31
+ <div class="card-section">
32
+ <p><%= t('decidim.file_authorization_handler.admin.new.info') %></p>
33
+ <%= form_tag censuses_path, multipart: true, class: 'form' do %>
34
+ <%= label_tag :name, t('admin.new.file', scope: 'decidim.file_authorization_handler') %>
35
+ <%= file_field_tag :file %>
36
+ <%= submit_tag t('admin.new.submit', scope: 'decidim.file_authorization_handler'), class: 'button' %>
37
+ <% end %>
38
+ </div>
39
+ </div>
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Census</title>
5
+ <%= stylesheet_link_tag "census/application", media: "all" %>
6
+ <%= javascript_include_tag "census/application" %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body>
10
+
11
+ <%= yield %>
12
+
13
+ </body>
14
+ </html>
@@ -0,0 +1,50 @@
1
+ ca:
2
+ activemodel:
3
+ attributes:
4
+ file_authorization_handler:
5
+ id_document: Document d'identitat (DNI, NIF, Passaport o Targeta de Residència)
6
+ birthdate: Data de naixement
7
+ census_authorization:
8
+ form:
9
+ date_select:
10
+ day: Dia
11
+ month: Mes
12
+ year: Any
13
+ decidim:
14
+ authorization_handlers:
15
+ file_authorization_handler:
16
+ name: Cens Organització
17
+ explanation: Autoritza el teu compte d'usuari contra el cens de la Organització
18
+ type: CSV
19
+ fields:
20
+ birthdate: Data de naixement
21
+ file_authorization_handler:
22
+ errors:
23
+ messages:
24
+ not_censed: No hem pogut trobar el teu document d'identitat amb aquesta data de naixement al padró municipal. Si les dades són correctes i el problema persisteix, siusplau, posa't en contacte amb un administrador.
25
+ younger_than_minimum_age: Hauries de ser major de %{age} anys
26
+ admin:
27
+ destroy:
28
+ title: Esborrar totes les dades del cens
29
+ confirm: Aquesta acció no es pot desfer. Estàs segur/a que voleu continuar?
30
+ censuses:
31
+ create:
32
+ success: S'han importat amb èxit %{count} elements (%{errors} errors)
33
+ destroy:
34
+ success: S'han esborrat totes les dades censals
35
+ menu:
36
+ census: Pujar cens
37
+ show:
38
+ title: Dades del cens carregat
39
+ data: Hi ha un total de %{count} registres carregats. La última càrrega va ser el dia %{due_date}
40
+ empty: Encara no hi ha dades censals carregades. Utilitza el següent formulari per importar-lo utilitzant un fitxer CSV.
41
+ new:
42
+ info: "Ha de ser un fitxer generat en excel i exportat en CSV amb dues columnes: document d'identitat i data de naixement"
43
+ title: Pujar un nou cens
44
+ file: Arxiu excel .csv amb les dades del cens
45
+ submit: Carrega
46
+ verifications:
47
+ authorizations:
48
+ first_login:
49
+ actions:
50
+ file_authorization_handler: Verifica't amb el cens de l'organització
@@ -0,0 +1,50 @@
1
+ en:
2
+ activemodel:
3
+ attributes:
4
+ file_authorization_handler:
5
+ id_document: Identification document (DNI, NIF, Password or Residence Card)
6
+ birthdate: Date of birth
7
+ census_authorization:
8
+ form:
9
+ date_select:
10
+ day: Day
11
+ month: Month
12
+ year: Year
13
+ decidim:
14
+ authorization_handlers:
15
+ file_authorization_handler:
16
+ name: Organization's Census
17
+ explanation: Authorize your user account against Organization's Census
18
+ type: CSV
19
+ fields:
20
+ birthdate: Birthdate
21
+ file_authorization_handler:
22
+ errors:
23
+ messages:
24
+ not_censed: We could not find your document ID matching with this birthdate in our Census. If the data entered is correct and the problem persists, please, contact an administrator.
25
+ younger_than_minimum_age: You should be older than %{age} years
26
+ admin:
27
+ destroy:
28
+ title: Delete all census data
29
+ confirm: Delete all the census can not be undone. Are you sure you want to continue?
30
+ censuses:
31
+ create:
32
+ success: Successfully imported %{count} items (%{errors} errors)
33
+ destroy:
34
+ success: All census data have been deleted
35
+ menu:
36
+ census: Upload census
37
+ show:
38
+ title: Current census data
39
+ data: There are %{count} records loaded in total. Last upload date was on %{due_date}
40
+ empty: There are no census data. Use the form below to import it using a CSV file.
41
+ new:
42
+ info: 'Must be a file generated by excel and exported with CSV format with two columns: identity document and date of birth'
43
+ title: Upload a new census
44
+ file: Excel .csv file with census data
45
+ submit: Upload file
46
+ verifications:
47
+ authorizations:
48
+ first_login:
49
+ actions:
50
+ file_authorization_handler: Get verified by organization's census
@@ -0,0 +1,50 @@
1
+ es:
2
+ activemodel:
3
+ attributes:
4
+ file_authorization_handler:
5
+ id_document: Documento de identidad (DNI, NIF, Pasaporte o Targeta de Residencia)
6
+ birthdate: Fecha de nacimiento
7
+ census_authorization:
8
+ form:
9
+ date_select:
10
+ day: Día
11
+ month: Mes
12
+ year: Año
13
+ decidim:
14
+ authorization_handlers:
15
+ file_authorization_handler:
16
+ name: Censo de la Organización
17
+ explanation: Autoriza tu cuenta de usuario contra el Censo de la Organización
18
+ type: CSV
19
+ fields:
20
+ birthdate: Fecha de nacimiento
21
+ file_authorization_handler:
22
+ errors:
23
+ messages:
24
+ not_censed: No hemos podido encontrar tu documento de identidad con esta fecha de nacimiento en el padrón municipal. Si tus datos son correctos y el problema persiste, por favor, ponte en contacto con un administrador
25
+ younger_than_minimum_age: Deberías ser mayor de %{age} años
26
+ admin:
27
+ destroy:
28
+ title: Borrar todos los datos de censo
29
+ confirm: Borrar el censo no se puede deshacer. ¿Estás seguro/a que deseas continuar?
30
+ censuses:
31
+ create:
32
+ success: Se han importado con éxito %{count} elementos (%{errors} errores)
33
+ destroy:
34
+ success: Se han borrado todos los datos censales
35
+ menu:
36
+ census: Subir censo
37
+ show:
38
+ title: Datos de censo actuales
39
+ data: Hay un total de %{count} registros cargados. La última carga fue el día %{due_date}
40
+ empty: No hay datos censales. Usa el formulario a continuación para importar usando un fichero CSV.
41
+ new:
42
+ info: 'Debe ser un fichero generado por excel y exportado en formato CSV con dos columnas: documento de identidad y fecha de nacimiento'
43
+ title: Subir un nuevo censo
44
+ file: Archivo excel .csv con los datos del censo
45
+ submit: Subir archivo
46
+ verifications:
47
+ authorizations:
48
+ first_login:
49
+ actions:
50
+ file_authorization_handler: Verifícate con el censo de la organización
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateDecidimFileAuthorizationHandlerCensusDatum < ActiveRecord::Migration[5.1]
4
+ def change
5
+ create_table :decidim_file_authorization_handler_census_data do |t|
6
+ t.references :decidim_organization, index: { name: "decidim_census_data_org_id_index" }
7
+ t.string :id_document
8
+ t.date :birthdate
9
+
10
+ # The rows in this table are immutable (insert or delete, not update)
11
+ # To explicitly reflect this fact there is no `updated_at` column
12
+ t.datetime "created_at", null: false
13
+ end
14
+ end
15
+ end