decidim-verifications 0.16.1 → 0.17.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/commands/decidim/verifications/csv_census/admin/create_census_data.rb +32 -0
- data/app/commands/decidim/verifications/csv_census/confirm_census_authorization.rb +20 -0
- data/app/controllers/decidim/verifications/csv_census/admin/census_controller.rb +68 -0
- data/app/controllers/decidim/verifications/csv_census/authorizations_controller.rb +39 -0
- data/app/controllers/decidim/verifications/sms/authorizations_controller.rb +16 -2
- data/app/forms/decidim/verifications/csv_census/admin/census_data_form.rb +20 -0
- data/app/forms/decidim/verifications/csv_census/census_form.rb +32 -0
- data/app/jobs/decidim/verifications/csv_census/application_job.rb +10 -0
- data/app/jobs/decidim/verifications/csv_census/remove_duplicates_job.rb +30 -0
- data/app/models/decidim/verifications/application_record.rb +9 -0
- data/app/models/decidim/verifications/csv_census/data.rb +41 -0
- data/app/models/decidim/verifications/csv_census/status.rb +24 -0
- data/app/models/decidim/verifications/csv_datum.rb +29 -0
- data/app/permissions/decidim/verifications/csv_census/admin/permissions.rb +19 -0
- data/app/views/decidim/verifications/authorizations/_granted_authorization.html.erb +1 -1
- data/app/views/decidim/verifications/authorizations/index.html.erb +1 -1
- data/app/views/decidim/verifications/csv_census/admin/census/index.html.erb +37 -0
- data/app/views/decidim/verifications/csv_census/admin/census/instructions.html.erb +10 -0
- data/app/views/decidim/verifications/sms/authorizations/edit.html.erb +10 -1
- data/app/views/decidim/verifications/sms/authorizations/new.html.erb +1 -1
- data/config/locales/ar-SA.yml +68 -5
- data/config/locales/ca.yml +54 -14
- data/config/locales/cs-CZ.yml +36 -0
- data/config/locales/cs.yml +230 -0
- data/config/locales/de.yml +41 -1
- data/config/locales/en.yml +65 -24
- data/config/locales/es-MX.yml +42 -2
- data/config/locales/es-PY.yml +42 -2
- data/config/locales/es.yml +56 -16
- data/config/locales/eu.yml +41 -1
- data/config/locales/fi-pl.yml +36 -0
- data/config/locales/fi-plain.yml +228 -0
- data/config/locales/fi.yml +50 -10
- data/config/locales/fr.yml +41 -1
- data/config/locales/gl.yml +41 -1
- data/config/locales/hu.yml +42 -2
- data/config/locales/id-ID.yml +41 -1
- data/config/locales/it.yml +41 -1
- data/config/locales/nl.yml +41 -1
- data/config/locales/pl.yml +41 -1
- data/config/locales/pt-BR.yml +41 -1
- data/config/locales/pt.yml +41 -1
- data/config/locales/ru.yml +0 -3
- data/config/locales/sv.yml +41 -1
- data/config/locales/tr-TR.yml +41 -1
- data/config/locales/uk.yml +0 -3
- data/db/migrate/20181227135423_create_decidim_verifications_csv_data.rb +12 -0
- data/lib/decidim/verifications.rb +1 -0
- data/lib/decidim/verifications/adapter.rb +13 -1
- data/lib/decidim/verifications/csv_census.rb +6 -0
- data/lib/decidim/verifications/csv_census/admin.rb +10 -0
- data/lib/decidim/verifications/csv_census/admin_engine.rb +23 -0
- data/lib/decidim/verifications/csv_census/engine.rb +19 -0
- data/lib/decidim/verifications/csv_census/workflow.rb +6 -0
- data/lib/decidim/verifications/default_action_authorizer.rb +11 -4
- data/lib/decidim/verifications/sms/engine.rb +1 -1
- data/lib/decidim/verifications/test/factories.rb +11 -0
- data/lib/decidim/verifications/version.rb +1 -1
- metadata +31 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 225bbee462860c9becc5c3d7dd53d16a0e0e94993359cff93d2c6bfc96d555e6
|
4
|
+
data.tar.gz: 495394b73a941ef63a06bfdf90905d7d5d6bcfabf1adf3db33a6bb9e1413cbda
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '0326694c4648f0f2b45a6bd9af49b747efe042e47f69d23f4ea17dd490416f8a51fb2da8f1866daaa7ff8861755d1f6e4bc68b66e74d21223a73100e36706e59'
|
7
|
+
data.tar.gz: 82cc23f42d19073afa7238316e02e1398bcc80560b6ee389a95453b62bcb7447202e980aa283f521660c532fd6f08c232ea88a2d6f8b21d74571beb5a8374eda
|
@@ -0,0 +1,32 @@
|
|
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 CreateCensusData < Rectify::Command
|
10
|
+
def initialize(form, organization)
|
11
|
+
@form = form
|
12
|
+
@organization = organization
|
13
|
+
end
|
14
|
+
|
15
|
+
# Executes the command. Broadcast this events:
|
16
|
+
# - :ok when everything is valid
|
17
|
+
# - :invalid when the form wasn't valid and couldn't proceed-
|
18
|
+
#
|
19
|
+
# Returns nothing.
|
20
|
+
def call
|
21
|
+
return broadcast(:invalid) unless @form.file
|
22
|
+
|
23
|
+
CsvDatum.insert_all(@organization, @form.data.values)
|
24
|
+
RemoveDuplicatesJob.perform_later(@organization)
|
25
|
+
|
26
|
+
broadcast(:ok)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Verifications
|
5
|
+
module CsvCensus
|
6
|
+
class ConfirmCensusAuthorization < ConfirmUserAuthorization
|
7
|
+
def call
|
8
|
+
return broadcast(:invalid) unless form.valid?
|
9
|
+
|
10
|
+
if confirmation_successful?
|
11
|
+
authorization.grant!
|
12
|
+
broadcast(:ok)
|
13
|
+
else
|
14
|
+
broadcast(:invalid)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Verifications
|
5
|
+
module CsvCensus
|
6
|
+
module Admin
|
7
|
+
class CensusController < Decidim::Admin::ApplicationController
|
8
|
+
include NeedsPermission
|
9
|
+
|
10
|
+
layout "decidim/admin/users"
|
11
|
+
|
12
|
+
before_action :show_instructions,
|
13
|
+
unless: :csv_census_active?
|
14
|
+
|
15
|
+
def index
|
16
|
+
enforce_permission_to :index, CsvDatum
|
17
|
+
@form = form(CensusDataForm).instance
|
18
|
+
@status = Status.new(current_organization)
|
19
|
+
end
|
20
|
+
|
21
|
+
def create
|
22
|
+
enforce_permission_to :create, CsvDatum
|
23
|
+
@form = form(CensusDataForm).from_params(params)
|
24
|
+
CreateCensusData.call(@form, current_organization) do
|
25
|
+
on(:ok) do
|
26
|
+
flash[:notice] = t(".success", count: @form.data.values.count, errors: @form.data.errors.count)
|
27
|
+
end
|
28
|
+
|
29
|
+
on(:invalid) do
|
30
|
+
flash[:alert] = t(".error")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
redirect_to census_path
|
34
|
+
end
|
35
|
+
|
36
|
+
def destroy_all
|
37
|
+
enforce_permission_to :destroy, CsvDatum
|
38
|
+
CsvDatum.clear(current_organization)
|
39
|
+
|
40
|
+
redirect_to census_path, notice: t(".success")
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def show_instructions
|
46
|
+
render :instructions
|
47
|
+
end
|
48
|
+
|
49
|
+
def csv_census_active?
|
50
|
+
current_organization.available_authorizations.include?("csv_census")
|
51
|
+
end
|
52
|
+
|
53
|
+
def permission_class_chain
|
54
|
+
[
|
55
|
+
Decidim::Verifications::CsvCensus::Admin::Permissions,
|
56
|
+
Decidim::Admin::Permissions,
|
57
|
+
Decidim::Permissions
|
58
|
+
]
|
59
|
+
end
|
60
|
+
|
61
|
+
def permission_scope
|
62
|
+
:admin
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Verifications
|
5
|
+
module CsvCensus
|
6
|
+
class AuthorizationsController < Decidim::ApplicationController
|
7
|
+
helper_method :authorization
|
8
|
+
|
9
|
+
before_action :load_authorization
|
10
|
+
|
11
|
+
def new
|
12
|
+
@form = CensusForm.from_params(user: current_user)
|
13
|
+
ConfirmCensusAuthorization.call(@authorization, @form) do
|
14
|
+
on(:ok) do
|
15
|
+
flash[:notice] = t("authorizations.new.success", scope: "decidim.verifications.csv_census")
|
16
|
+
end
|
17
|
+
on(:invalid) do
|
18
|
+
flash[:alert] = t("authorizations.new.error", scope: "decidim.verifications.csv_census")
|
19
|
+
end
|
20
|
+
redirect_to decidim_verifications.authorizations_path
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def authorization
|
27
|
+
@authorization ||= AuthorizationPresenter.new(@authorization)
|
28
|
+
end
|
29
|
+
|
30
|
+
def load_authorization
|
31
|
+
@authorization = Decidim::Authorization.find_or_initialize_by(
|
32
|
+
user: current_user,
|
33
|
+
name: "csv_census"
|
34
|
+
)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -21,7 +21,7 @@ module Decidim
|
|
21
21
|
on(:ok) do
|
22
22
|
flash[:notice] = t("authorizations.create.success", scope: "decidim.verifications.sms")
|
23
23
|
authorization_method = Decidim::Verifications::Adapter.from_element(authorization.name)
|
24
|
-
redirect_to authorization_method.resume_authorization_path
|
24
|
+
redirect_to authorization_method.resume_authorization_path(redirect_url: params[:redirect_url])
|
25
25
|
end
|
26
26
|
on(:invalid) do
|
27
27
|
flash.now[:alert] = t("authorizations.create.error", scope: "decidim.verifications.sms")
|
@@ -44,7 +44,12 @@ module Decidim
|
|
44
44
|
ConfirmUserAuthorization.call(authorization, @form) do
|
45
45
|
on(:ok) do
|
46
46
|
flash[:notice] = t("authorizations.update.success", scope: "decidim.verifications.sms")
|
47
|
-
|
47
|
+
|
48
|
+
if params[:redirect_url]
|
49
|
+
redirect_to params[:redirect_url]
|
50
|
+
else
|
51
|
+
redirect_to decidim_verifications.authorizations_path
|
52
|
+
end
|
48
53
|
end
|
49
54
|
|
50
55
|
on(:invalid) do
|
@@ -54,6 +59,15 @@ module Decidim
|
|
54
59
|
end
|
55
60
|
end
|
56
61
|
|
62
|
+
def destroy
|
63
|
+
enforce_permission_to :destroy, :authorization, authorization: authorization
|
64
|
+
|
65
|
+
authorization.destroy!
|
66
|
+
flash[:notice] = t("authorizations.destroy.success", scope: "decidim.verifications.sms")
|
67
|
+
|
68
|
+
redirect_to action: :new
|
69
|
+
end
|
70
|
+
|
57
71
|
private
|
58
72
|
|
59
73
|
def authorization
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Verifications
|
5
|
+
module CsvCensus
|
6
|
+
module Admin
|
7
|
+
# A form to temporaly upload csv census data
|
8
|
+
class CensusDataForm < Form
|
9
|
+
mimic :census_data
|
10
|
+
|
11
|
+
attribute :file
|
12
|
+
|
13
|
+
def data
|
14
|
+
CsvCensus::Data.new(file.path)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Verifications
|
5
|
+
module CsvCensus
|
6
|
+
class CensusForm < AuthorizationHandler
|
7
|
+
validate :censed
|
8
|
+
|
9
|
+
def authorized?
|
10
|
+
true if census_for_user
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def censed
|
16
|
+
return if census_for_user&.email == user.email
|
17
|
+
|
18
|
+
errors.add(:email, I18n.t("decidim.verifications.csv_census.authorizations.new.error"))
|
19
|
+
end
|
20
|
+
|
21
|
+
def organization
|
22
|
+
current_organization || user.organization
|
23
|
+
end
|
24
|
+
|
25
|
+
def census_for_user
|
26
|
+
@census_for_user ||= CsvDatum
|
27
|
+
.search_user_email(organization, user.email)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Verifications
|
5
|
+
module CsvCensus
|
6
|
+
class RemoveDuplicatesJob < ApplicationJob
|
7
|
+
queue_as :default
|
8
|
+
|
9
|
+
def perform(organization)
|
10
|
+
duplicated_census(organization).pluck(:email).each do |email|
|
11
|
+
CsvDatum.inside(organization)
|
12
|
+
.where(email: email)
|
13
|
+
.order(id: :desc)
|
14
|
+
.all(1..-1)
|
15
|
+
.each(&:delete)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def duplicated_census(organization)
|
22
|
+
CsvDatum.inside(organization)
|
23
|
+
.select(:email)
|
24
|
+
.group(:email)
|
25
|
+
.having("count(email)>1")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "csv"
|
4
|
+
|
5
|
+
module Decidim
|
6
|
+
module Verifications
|
7
|
+
module CsvCensus
|
8
|
+
# A data processor for get emails data form a csv file
|
9
|
+
#
|
10
|
+
# Enable this methods:
|
11
|
+
#
|
12
|
+
# - .error with an array of rows with errors in the csv file
|
13
|
+
# - .values an array with emails readed from the csv file
|
14
|
+
#
|
15
|
+
# Returns nothing
|
16
|
+
class Data
|
17
|
+
attr_reader :errors, :values
|
18
|
+
def initialize(file)
|
19
|
+
@file = file
|
20
|
+
@values = []
|
21
|
+
@errors = []
|
22
|
+
|
23
|
+
CSV.foreach(@file, headers: true) do |row|
|
24
|
+
process_row(row)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def process_row(row)
|
31
|
+
user_mail = row["email"]
|
32
|
+
if user_mail.present?
|
33
|
+
values << user_mail
|
34
|
+
else
|
35
|
+
errors << row
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Verifications
|
5
|
+
module CsvCensus
|
6
|
+
class Status
|
7
|
+
def initialize(organization)
|
8
|
+
@organization = organization
|
9
|
+
end
|
10
|
+
|
11
|
+
def last_import_at
|
12
|
+
@last ||= CsvDatum.inside(@organization)
|
13
|
+
.order(created_at: :desc).first
|
14
|
+
@last ? @last.created_at : nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def count
|
18
|
+
@count ||= CsvDatum.inside(@organization)
|
19
|
+
.distinct.count(:email)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Verifications
|
5
|
+
class CsvDatum < ApplicationRecord
|
6
|
+
belongs_to :organization, foreign_key: :decidim_organization_id,
|
7
|
+
class_name: "Decidim::Organization"
|
8
|
+
|
9
|
+
def self.inside(organization)
|
10
|
+
where(organization: organization)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.search_user_email(organization, email)
|
14
|
+
inside(organization)
|
15
|
+
.where(email: email)
|
16
|
+
.order(created_at: :desc, id: :desc)
|
17
|
+
.first
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.insert_all(organization, values)
|
21
|
+
values.each { |value| create(email: value, organization: organization) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.clear(organization)
|
25
|
+
inside(organization).delete_all
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Verifications
|
5
|
+
module CsvCensus
|
6
|
+
module Admin
|
7
|
+
class Permissions < Decidim::DefaultPermissions
|
8
|
+
def permissions
|
9
|
+
return permission_action if permission_action.scope != :admin
|
10
|
+
if user.organization.available_authorizations.include?("csv_census")
|
11
|
+
allow! if permission_action.subject == Decidim::Verifications::CsvDatum
|
12
|
+
permission_action
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<div class="card--list__item">
|
2
2
|
<div class="card--list__text">
|
3
|
-
<%= icon "lock-
|
3
|
+
<%= icon "lock-locked", class: "card--list__icon" %>
|
4
4
|
<div>
|
5
5
|
<h5 class="card--list__heading">
|
6
6
|
<%= t("#{authorization.name}.name", scope: "decidim.authorization_handlers") %>
|