decidim-direct_verifications 0.22.1 → 1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +32 -3
- data/app/assets/config/direct_verifications_admin_manifest.css +3 -0
- data/app/assets/stylesheets/decidim/direct_verifications/authorizations.scss +17 -0
- data/app/commands/decidim/direct_verifications/verification/create_import.rb +50 -0
- data/app/controllers/decidim/direct_verifications/verification/admin/authorizations_controller.rb +40 -0
- data/app/controllers/decidim/direct_verifications/verification/admin/direct_verifications_controller.rb +20 -18
- data/app/controllers/decidim/direct_verifications/verification/admin/imports_controller.rb +55 -0
- data/app/forms/decidim/direct_verifications/registration_form.rb +8 -0
- data/app/forms/decidim/direct_verifications/verification/create_import_form.rb +43 -0
- data/app/jobs/decidim/direct_verifications/authorize_users_job.rb +34 -0
- data/app/jobs/decidim/direct_verifications/base_import_job.rb +38 -0
- data/app/jobs/decidim/direct_verifications/register_users_job.rb +19 -0
- data/app/jobs/decidim/direct_verifications/revoke_users_job.rb +17 -0
- data/app/mailers/decidim/direct_verifications/import_mailer.rb +27 -0
- data/app/mailers/decidim/direct_verifications/stats.rb +23 -0
- data/app/views/decidim/direct_verifications/import_mailer/finished_processing.html.erb +7 -0
- data/app/views/decidim/direct_verifications/import_mailer/finished_processing.text.erb +7 -0
- data/app/views/decidim/direct_verifications/verification/admin/authorizations/index.html.erb +42 -0
- data/app/views/decidim/direct_verifications/verification/admin/direct_verifications/index.html.erb +2 -1
- data/app/views/decidim/direct_verifications/verification/admin/imports/new.html.erb +50 -0
- data/config/initializers/mail_previews.rb +5 -0
- data/config/locales/ca.yml +20 -20
- data/config/locales/cs.yml +69 -0
- data/config/locales/en.yml +29 -2
- data/config/locales/es.yml +20 -20
- data/config/locales/fr.yml +69 -0
- data/lib/decidim/direct_verifications.rb +24 -1
- data/lib/decidim/direct_verifications/authorize_user.rb +64 -0
- data/lib/decidim/direct_verifications/instrumenter.rb +58 -0
- data/lib/decidim/direct_verifications/parsers.rb +11 -0
- data/lib/decidim/direct_verifications/parsers/base_parser.rb +37 -0
- data/lib/decidim/direct_verifications/parsers/metadata_parser.rb +54 -0
- data/lib/decidim/direct_verifications/parsers/name_parser.rb +40 -0
- data/lib/decidim/direct_verifications/register_user.rb +54 -0
- data/lib/decidim/direct_verifications/revoke_user.rb +45 -0
- data/lib/decidim/direct_verifications/tests/factories.rb +11 -0
- data/lib/decidim/direct_verifications/tests/verification_controller_examples.rb +8 -3
- data/lib/decidim/direct_verifications/user_processor.rb +17 -101
- data/lib/decidim/direct_verifications/user_stats.rb +5 -5
- data/lib/decidim/direct_verifications/verification/admin_engine.rb +6 -1
- data/lib/decidim/direct_verifications/version.rb +3 -3
- metadata +37 -9
- data/lib/decidim/direct_verifications/config.rb +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46d0f12ed4661879a4cdec82f1482875823fe9c5f4fba39c129e2a020d3c7f19
|
4
|
+
data.tar.gz: 5cf039fb0a1b3474082dbf7acc28013d8d0034c6d959c7c7ad589aca85c1fdf8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f960edacf1528f9801d6cfd82aa6898a5bffbf9233a2386a57cdb0c55c0a3d5ef45ddf501d1775db1ab325dbcd61925b012dcc3ab8bf83bedbd4630abbf3b03
|
7
|
+
data.tar.gz: 909e8c8be3368861bc6fe75c1290f820a4d697e20bf4ded85d9e91ec9a5b7a27d3aa65953d749460d3fe0efbfe132fd8aa586ac27e032782127463be98476a61
|
data/README.md
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
# Decidim::DirectVerifications
|
2
2
|
|
3
|
-
![Test](https://github.com/Platoniq/decidim-verifications-direct_verifications/workflows/
|
3
|
+
[![Test](https://github.com/Platoniq/decidim-verifications-direct_verifications/actions/workflows/test.yml/badge.svg)](https://github.com/Platoniq/decidim-verifications-direct_verifications/actions/workflows/test.yml)
|
4
4
|
[![Maintainability](https://api.codeclimate.com/v1/badges/2195deb4de6c6354a6bc/maintainability)](https://codeclimate.com/github/Platoniq/decidim-verifications-direct_verifications/maintainability)
|
5
|
-
[![codecov](https://codecov.io/gh/Platoniq/decidim-verifications-direct_verifications/branch/
|
5
|
+
[![codecov](https://codecov.io/gh/Platoniq/decidim-verifications-direct_verifications/branch/main/graph/badge.svg?token=FR1zkV71S2)](https://codecov.io/gh/Platoniq/decidim-verifications-direct_verifications)
|
6
|
+
|
7
|
+
|
6
8
|
|
7
9
|
A [Decidim](https://github.com/decidim/decidim) that provides a verification method called `Direct verification`. Works only on the admin side, final users do not intervene in the verification process.
|
8
10
|
|
@@ -36,6 +38,23 @@ With the detected list of emails admin have different options available:
|
|
36
38
|
3. Revoke the authorization for the list of users using any verification method available.
|
37
39
|
4. Check the status of the users in order to know if they are verified or registered.
|
38
40
|
|
41
|
+
### Metadata mode
|
42
|
+
|
43
|
+
This mode provides extra capabilities over the default processing:
|
44
|
+
|
45
|
+
* Reads CSV format with header (copy and paste it from your spreadsheet)
|
46
|
+
* Stores all columns except the email as authorization metadata
|
47
|
+
|
48
|
+
This enables querying the authorization metadata however fits you best.
|
49
|
+
|
50
|
+
To enable it create a new initializer, for instance `config/initializers/decidim_direct_verifications.rb` with the following contents
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
Decidim::DirectVerifications.configure do |config|
|
54
|
+
config.input_parser = :metadata_parser
|
55
|
+
end
|
56
|
+
```
|
57
|
+
|
39
58
|
## Installation
|
40
59
|
|
41
60
|
Add this line to your application's Gemfile:
|
@@ -50,6 +69,13 @@ And then execute:
|
|
50
69
|
bundle
|
51
70
|
```
|
52
71
|
|
72
|
+
Depending on your Decidim version, you might want to specify the version to ensure compatibility:
|
73
|
+
|
74
|
+
| Direct Verifications version | Compatible Decidim versions |
|
75
|
+
|---|---|
|
76
|
+
| 1.0 | >= 0.23.x |
|
77
|
+
| 0.22.x | 0.22.x |
|
78
|
+
|
53
79
|
## Using additional verification methods
|
54
80
|
|
55
81
|
You can manage other verification methods (or workflow) a part from `Direct verification`. You need to configure it in a new file in the `config/initializers` folder.
|
@@ -70,7 +96,10 @@ end
|
|
70
96
|
|
71
97
|
# We need to tell the plugin to handle this method in addition to the default "Direct verification". Any registered workflow is valid.
|
72
98
|
Decidim::DirectVerifications.configure do |config|
|
73
|
-
config.manage_workflows = %w(direct_verifications_managers)
|
99
|
+
config.manage_workflows = %w(direct_verifications direct_verifications_managers)
|
100
|
+
|
101
|
+
# change the to the metadata_parser if you want it
|
102
|
+
# config.input_parser = :metadata_parser
|
74
103
|
end
|
75
104
|
|
76
105
|
```
|
@@ -0,0 +1,17 @@
|
|
1
|
+
@import "decidim/admin/utils/settings";
|
2
|
+
|
3
|
+
$code-color: $black;
|
4
|
+
$code-font-family: $font-family-monospace;
|
5
|
+
$code-font-weight: $global-weight-normal;
|
6
|
+
$code-background: $light-gray;
|
7
|
+
$code-border: 1px solid $medium-gray;
|
8
|
+
$code-padding: rem-calc(2 5 1);
|
9
|
+
|
10
|
+
.code {
|
11
|
+
background: $code-background;
|
12
|
+
color: $code-color;
|
13
|
+
font-family: $code-font-family;
|
14
|
+
font-weight: $code-font-weight;
|
15
|
+
border: $code-border;
|
16
|
+
padding: $code-padding;
|
17
|
+
}
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module DirectVerifications
|
5
|
+
module Verification
|
6
|
+
class CreateImport < Rectify::Command
|
7
|
+
def initialize(form)
|
8
|
+
@form = form
|
9
|
+
@file = form.file
|
10
|
+
@organization = form.organization
|
11
|
+
@user = form.user
|
12
|
+
@action = form.action
|
13
|
+
end
|
14
|
+
|
15
|
+
def call
|
16
|
+
return broadcast(:invalid) unless form.valid?
|
17
|
+
|
18
|
+
case action
|
19
|
+
when :register
|
20
|
+
register_users_async
|
21
|
+
when :register_and_authorize
|
22
|
+
register_users_async
|
23
|
+
file.rewind
|
24
|
+
authorize_users_async
|
25
|
+
when :revoke
|
26
|
+
revoke_users_async
|
27
|
+
end
|
28
|
+
|
29
|
+
broadcast(:ok)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
attr_reader :form, :file, :organization, :user, :action
|
35
|
+
|
36
|
+
def register_users_async
|
37
|
+
RegisterUsersJob.perform_later(file.read, organization, user, form.authorization_handler)
|
38
|
+
end
|
39
|
+
|
40
|
+
def revoke_users_async
|
41
|
+
RevokeUsersJob.perform_later(file.read, organization, user, form.authorization_handler)
|
42
|
+
end
|
43
|
+
|
44
|
+
def authorize_users_async
|
45
|
+
AuthorizeUsersJob.perform_later(file.read, organization, user, form.authorization_handler)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/app/controllers/decidim/direct_verifications/verification/admin/authorizations_controller.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module DirectVerifications
|
5
|
+
module Verification
|
6
|
+
module Admin
|
7
|
+
class AuthorizationsController < Decidim::Admin::ApplicationController
|
8
|
+
layout "decidim/admin/users"
|
9
|
+
|
10
|
+
def index
|
11
|
+
enforce_permission_to :index, :authorization
|
12
|
+
@authorizations = collection.includes(:user)
|
13
|
+
end
|
14
|
+
|
15
|
+
def destroy
|
16
|
+
if authorization.destroy
|
17
|
+
flash[:notice] = "successfully"
|
18
|
+
redirect_to authorizations_path
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def collection
|
25
|
+
# Decidim::Verifications::Authorizations Query
|
26
|
+
Decidim::Verifications::Authorizations.new(
|
27
|
+
organization: current_organization,
|
28
|
+
name: "direct_verifications",
|
29
|
+
granted: true
|
30
|
+
).query
|
31
|
+
end
|
32
|
+
|
33
|
+
def authorization
|
34
|
+
@authorization ||= collection.find_by(id: params[:id])
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -18,29 +18,39 @@ module Decidim
|
|
18
18
|
enforce_permission_to :create, :authorization
|
19
19
|
|
20
20
|
@userslist = params[:userslist]
|
21
|
-
|
22
|
-
@processor
|
21
|
+
|
22
|
+
@processor = UserProcessor.new(current_organization, current_user, session, instrumenter)
|
23
|
+
@processor.emails = parser_class.new(@userslist).to_h
|
23
24
|
@processor.authorization_handler = current_authorization_handler
|
25
|
+
|
24
26
|
@stats = UserStats.new(current_organization)
|
25
27
|
@stats.authorization_handler = @processor.authorization_handler
|
28
|
+
|
26
29
|
register_users
|
27
30
|
authorize_users
|
28
31
|
revoke_users
|
29
32
|
|
30
33
|
render(action: :index) && return if show_users_info
|
31
34
|
|
35
|
+
redirect_to direct_verifications_path
|
36
|
+
rescue InputParserError => e
|
37
|
+
flash[:error] = e.message
|
32
38
|
redirect_to direct_verifications_path
|
33
39
|
end
|
34
40
|
|
35
41
|
private
|
36
42
|
|
43
|
+
def instrumenter
|
44
|
+
@instrumenter ||= Instrumenter.new(current_user)
|
45
|
+
end
|
46
|
+
|
37
47
|
def register_users
|
38
48
|
return unless params[:register]
|
39
49
|
|
40
50
|
@processor.register_users
|
41
51
|
flash[:warning] = t(".registered", count: @processor.emails.count,
|
42
|
-
registered:
|
43
|
-
errors:
|
52
|
+
registered: instrumenter.processed_count(:registered),
|
53
|
+
errors: instrumenter.errors_count(:registered))
|
44
54
|
end
|
45
55
|
|
46
56
|
def authorize_users
|
@@ -49,8 +59,8 @@ module Decidim
|
|
49
59
|
@processor.authorize_users
|
50
60
|
flash[:notice] = t(".authorized", handler: t("#{@processor.authorization_handler}.name", scope: "decidim.authorization_handlers"),
|
51
61
|
count: @processor.emails.count,
|
52
|
-
authorized:
|
53
|
-
errors:
|
62
|
+
authorized: instrumenter.processed_count(:authorized),
|
63
|
+
errors: instrumenter.errors_count(:authorized))
|
54
64
|
end
|
55
65
|
|
56
66
|
def revoke_users
|
@@ -59,8 +69,8 @@ module Decidim
|
|
59
69
|
@processor.revoke_users
|
60
70
|
flash[:notice] = t(".revoked", handler: t("#{@processor.authorization_handler}.name", scope: "decidim.authorization_handlers"),
|
61
71
|
count: @processor.emails.count,
|
62
|
-
revoked:
|
63
|
-
errors:
|
72
|
+
revoked: instrumenter.processed_count(:revoked),
|
73
|
+
errors: instrumenter.errors_count(:revoked))
|
64
74
|
end
|
65
75
|
|
66
76
|
def show_users_info
|
@@ -75,16 +85,8 @@ module Decidim
|
|
75
85
|
true
|
76
86
|
end
|
77
87
|
|
78
|
-
def
|
79
|
-
|
80
|
-
emails = {}
|
81
|
-
txt.split(/[\r\n;,]/).each do |line|
|
82
|
-
reg.match line do |m|
|
83
|
-
n = line.split(m[0]).first
|
84
|
-
emails[m[0]] = (n.presence || "").gsub(/[^[:print:]]|[\"\$\<\>\|\\]/, "").strip
|
85
|
-
end
|
86
|
-
end
|
87
|
-
emails
|
88
|
+
def parser_class
|
89
|
+
Decidim::DirectVerifications.find_parser_class(Decidim::DirectVerifications.input_parser)
|
88
90
|
end
|
89
91
|
|
90
92
|
def authorization_handler(authorization_handler)
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module DirectVerifications
|
5
|
+
module Verification
|
6
|
+
module Admin
|
7
|
+
class ImportsController < Decidim::Admin::ApplicationController
|
8
|
+
layout "decidim/admin/users"
|
9
|
+
helper_method :workflows, :current_authorization_handler
|
10
|
+
|
11
|
+
def new
|
12
|
+
enforce_permission_to :create, :authorization
|
13
|
+
@form = form(CreateImportForm).instance
|
14
|
+
end
|
15
|
+
|
16
|
+
def create
|
17
|
+
enforce_permission_to :create, :authorization
|
18
|
+
|
19
|
+
defaults = { organization: current_organization, user: current_user }
|
20
|
+
form = form(CreateImportForm).from_params(params.merge(defaults))
|
21
|
+
|
22
|
+
CreateImport.call(form) do
|
23
|
+
on(:ok) do
|
24
|
+
flash[:notice] = t(".success")
|
25
|
+
end
|
26
|
+
|
27
|
+
on(:invalid) do
|
28
|
+
flash[:alert] = t(".error")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
redirect_to new_import_path
|
33
|
+
end
|
34
|
+
|
35
|
+
def workflows
|
36
|
+
workflows = configured_workflows & current_organization.available_authorizations.map.to_a
|
37
|
+
workflows.map do |workflow|
|
38
|
+
[t("#{workflow}.name", scope: "decidim.authorization_handlers"), workflow]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def configured_workflows
|
43
|
+
return Decidim::DirectVerifications.config.manage_workflows if Decidim::DirectVerifications.config
|
44
|
+
|
45
|
+
["direct_verifications"]
|
46
|
+
end
|
47
|
+
|
48
|
+
def current_authorization_handler
|
49
|
+
params[:authorization_handler]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module DirectVerifications
|
5
|
+
module Verification
|
6
|
+
class CreateImportForm < Form
|
7
|
+
ACTIONS = {
|
8
|
+
"in" => :authorize,
|
9
|
+
"out" => :revoke,
|
10
|
+
"check" => :check
|
11
|
+
}.freeze
|
12
|
+
|
13
|
+
attribute :file
|
14
|
+
attribute :organization, Decidim::Organization
|
15
|
+
attribute :user, Decidim::User
|
16
|
+
attribute :authorize, String
|
17
|
+
attribute :register, Boolean
|
18
|
+
attribute :authorization_handler, String
|
19
|
+
|
20
|
+
validates :file, :organization, :user, :authorize, :authorization_handler, presence: true
|
21
|
+
validates :authorize, inclusion: { in: ACTIONS.keys }
|
22
|
+
|
23
|
+
validate :available_authorization_handler
|
24
|
+
|
25
|
+
def available_authorization_handler
|
26
|
+
return if authorization_handler.in?(organization.available_authorizations)
|
27
|
+
|
28
|
+
errors.add(:authorization_handler, :inclusion)
|
29
|
+
end
|
30
|
+
|
31
|
+
def action
|
32
|
+
if register && authorize == "in"
|
33
|
+
:register_and_authorize
|
34
|
+
elsif register
|
35
|
+
:register
|
36
|
+
else
|
37
|
+
ACTIONS[authorize]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "decidim/direct_verifications/instrumenter"
|
4
|
+
|
5
|
+
module Decidim
|
6
|
+
module DirectVerifications
|
7
|
+
class AuthorizeUsersJob < BaseImportJob
|
8
|
+
class NullSession; end
|
9
|
+
|
10
|
+
def process_users
|
11
|
+
emails.each do |email, data|
|
12
|
+
AuthorizeUser.new(
|
13
|
+
email,
|
14
|
+
data,
|
15
|
+
session,
|
16
|
+
organization,
|
17
|
+
instrumenter,
|
18
|
+
authorization_handler
|
19
|
+
).call
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def type
|
24
|
+
:authorized
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def session
|
30
|
+
NullSession.new
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "decidim/direct_verifications/instrumenter"
|
4
|
+
|
5
|
+
module Decidim
|
6
|
+
module DirectVerifications
|
7
|
+
# This class implements the logic to import the user entries and sending an email notification
|
8
|
+
# with the result. The specifics to process the entries are meant to be implemented by
|
9
|
+
# subclasses which must implement the `#process_users` and `#type` methods.
|
10
|
+
class BaseImportJob < ApplicationJob
|
11
|
+
queue_as :default
|
12
|
+
|
13
|
+
def perform(userslist, organization, current_user, authorization_handler)
|
14
|
+
@emails = Parsers::MetadataParser.new(userslist).to_h
|
15
|
+
@organization = organization
|
16
|
+
@current_user = current_user
|
17
|
+
@instrumenter = Instrumenter.new(current_user)
|
18
|
+
@authorization_handler = authorization_handler
|
19
|
+
|
20
|
+
process_users
|
21
|
+
send_email_notification
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
attr_reader :emails, :organization, :current_user, :instrumenter, :authorization_handler
|
27
|
+
|
28
|
+
def send_email_notification
|
29
|
+
ImportMailer.finished_processing(
|
30
|
+
current_user,
|
31
|
+
instrumenter,
|
32
|
+
type,
|
33
|
+
authorization_handler
|
34
|
+
).deliver_now
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|