decidim-direct_verifications 0.17.5 → 0.21

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cc27718faef5834d2778ee506cdd695f855acc08e35578f6d3a9c0b2ff6844f6
4
- data.tar.gz: 441b66ef0ea0b5d45d689339ffab82120115f33f82e4f2f966c83b46859d972b
3
+ metadata.gz: cbf6bc3adf56db3268520dc976ecf5e24791667d27d41e43f43be7a1de122b15
4
+ data.tar.gz: 63bc2221b993503c21037f62195021967eed48f3d0d35ce1f25ceb2bd27e899a
5
5
  SHA512:
6
- metadata.gz: aeb8062cc3043a0cf46eadcdcdb39ac3d259d2af2405948d6dead388f6686492ca2c16edf103f9c8da797d24843e873aa371f12d59fe758f58dfb2d43870a258
7
- data.tar.gz: b1a9655776ca5495cc608bce587c881e28aded3ce54d640145c6edb3fb7d80227b77222319b0ffbcdf18ffccd0140a1569d105e35f4297f6e4cf0b23d5ddf006
6
+ metadata.gz: c90a4d69fd3640640efb62102de8a218ba2f57e01725bb89f81a6c7adc384c0e937ded80f8049b2448cc2b60eedfa37c71f24bdf74288c9d4efe63c69a5dccb1
7
+ data.tar.gz: fee38887199f7a345e64a62f7389262785435d6686aef02ee39a75359314dbc9b9d43465689d122c3b539811c2fde2abce0917e08584a73be4077e33c6cdfd22
data/README.md CHANGED
@@ -1,19 +1,21 @@
1
1
  # Decidim::DirectVerifications
2
2
 
3
- [![Build Status](https://travis-ci.org/Platoniq/decidim-verifications-direct_verifications.svg?branch=master)](https://travis-ci.org/Platoniq/decidim-verifications-direct_verifications)
3
+ ![[CI] Test](https://github.com/Platoniq/decidim-verifications-direct_verifications/workflows/%5BCI%5D%20Test/badge.svg)
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/master/graph/badge.svg?token=FR1zkV71S2)](https://codecov.io/gh/Platoniq/decidim-verifications-direct_verifications)
4
6
 
5
7
  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.
6
8
 
7
9
  This plugin allows to verify users against the `Direct verification` method by default, but it is not limited to it, it can be used to directly verify users against any other method registered for the organization.
8
10
 
9
- You can use this plugin in combination with the great [AccessRequests](https://github.com/mainio/decidim-module-access_requests) plugin from Maino Tech to provide and manage several levels of permissions to users in the platform Decidim.
10
-
11
- **Other features include:**
11
+ **Features:**
12
12
 
13
13
  1. Allows to massively register users directly in the platform prior (or independently) to verify them by sending them invite emails.
14
14
  > **IMPORTANT:**<br>
15
15
  > You must only use this feature if you have explicit consent from your users, otherwise you might be violating the [GDPR](https://eugdpr.org/) regulation in EU.
16
- 2. Can massively revoke authorizations given to any user with any verification method available.
16
+ 2. Massive authroizations of users using any verification method registered for the organization **if configured**.
17
+ 3. It can massively revoke authorizations given to any user with any verification method available.
18
+ 4. Shows user's statuses per verification method in a simple stats table.
17
19
 
18
20
  ## Screenshot
19
21
 
@@ -48,6 +50,66 @@ And then execute:
48
50
  bundle
49
51
  ```
50
52
 
53
+ ## Using additional verification methods
54
+
55
+ 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.
56
+ For instance, you can use this same engine to have 2 levels of permissions in the platform.
57
+
58
+ Create a file like `config/initializers/decidim_verifications.rb` with content as:
59
+
60
+ **`config/initializers/decidim_verifications.rb`:**
61
+
62
+ ```ruby
63
+ # frozen_string_literal: true
64
+
65
+ # We are using the same DirectVerifications engine without the admin part to
66
+ # create a custom verification method called "direct_verifications_managers"
67
+ Decidim::Verifications.register_workflow(:direct_verifications_managers) do |workflow|
68
+ workflow.engine = Decidim::DirectVerifications::Verification::Engine
69
+ end
70
+
71
+ # We need to tell the plugin to handle this method in addition to the default "Direct verification". Any registered workflow is valid.
72
+ Decidim::DirectVerifications.configure do |config|
73
+ config.manage_workflows = %w(direct_verifications_managers)
74
+ end
75
+
76
+ ```
77
+
78
+ You will need the locales entries corresponding to your custom workflow, create as many files as languages you have in your application in `config/locales`:
79
+
80
+ **`config/locales/en.yml`:**
81
+
82
+ ```yaml
83
+ en:
84
+ decidim:
85
+ authorization_handlers:
86
+ direct_verifications_managers:
87
+ name: Organization managers
88
+ explanation: Direct Verifications Subgroup explanation
89
+ verifications:
90
+ authorizations:
91
+ first_login:
92
+ actions:
93
+ direct_verifications_managers: Organization managers
94
+ ```
95
+
96
+ Similarly, you can also overwrite the default title "Direct verification" by creating the key again in your locales:
97
+
98
+ ```yaml
99
+ en:
100
+ decidim:
101
+ authorization_handlers:
102
+ direct_verifications:
103
+ name: Generic organization members
104
+ explanation: Direct Verifications Subgroup explanation
105
+ verifications:
106
+ authorizations:
107
+ first_login:
108
+ actions:
109
+ direct_verifications: Generic organization members
110
+ ```
111
+
112
+
51
113
  ## Contributing
52
114
 
53
115
  See [Decidim](https://github.com/decidim/decidim).
@@ -0,0 +1 @@
1
+ //= link decidim/direct_verifications/verification/admin/direct_verifications_admin.js
@@ -0,0 +1,7 @@
1
+ // = require_self
2
+
3
+ $(() => {
4
+ $('[type="checkbox"]#register').change(function () {
5
+ $(this).closest('label').find('.callout').toggleClass('hide', !$(this).prop('checked'))
6
+ })
7
+ })
@@ -6,71 +6,106 @@ module Decidim
6
6
  module Admin
7
7
  class DirectVerificationsController < Decidim::Admin::ApplicationController
8
8
  include NeedsPermission
9
+ helper_method :workflows, :current_authorization_handler
9
10
 
10
11
  layout "decidim/admin/users"
11
12
 
12
13
  def index
13
- enforce_permission_to :index, UserProcessor
14
+ enforce_permission_to :index, :authorization
14
15
  end
15
16
 
16
17
  def create
17
- enforce_permission_to :create, UserProcessor
18
-
19
- @userlist = params[:userlist]
20
- processor = UserProcessor.new(current_organization, current_user)
21
- processor.emails = extract_emails_to_hash @userlist
22
- processor.authorization_handler = params[:authorization_handler] if params[:authorization_handler]
23
- if params[:register]
24
- processor.register_users
25
- flash[:warning] = t(".registered", count: processor.emails.count,
26
- registered: processor.processed[:registered].count,
27
- errors: processor.errors[:registered].count)
28
- end
29
- if params[:authorize] == "in"
30
- processor.authorize_users
31
- flash[:notice] = t(".authorized", handler: t("#{processor.authorization_handler}.name", scope: "decidim.authorization_handlers"),
32
- count: processor.emails.count,
33
- authorized: processor.processed[:authorized].count,
34
- errors: processor.errors[:authorized].count)
35
- elsif params[:authorize] == "out"
36
- processor.revoke_users
37
- flash[:notice] = t(".revoked", handler: t("#{processor.authorization_handler}.name", scope: "decidim.authorization_handlers"),
38
- count: processor.emails.count,
39
- revoked: processor.processed[:revoked].count,
40
- errors: processor.errors[:revoked].count)
41
- else
42
- flash[:info] = t(".info", handler: t("#{processor.authorization_handler}.name", scope: "decidim.authorization_handlers"),
43
- count: processor.emails.count,
44
- authorized: processor.total(:authorized),
45
- unconfirmed: processor.total(:unconfirmed),
46
- registered: processor.total(:registered))
47
- render(action: :index) && return
48
- end
18
+ enforce_permission_to :create, :authorization
19
+
20
+ @userslist = params[:userlist]
21
+ @processor = UserProcessor.new(current_organization, current_user)
22
+ @processor.emails = extract_emails_to_hash @userslist
23
+ @processor.authorization_handler = current_authorization_handler
24
+ @stats = UserStats.new(current_organization)
25
+ @stats.authorization_handler = @processor.authorization_handler
26
+ register_users
27
+ authorize_users
28
+ revoke_users
29
+
30
+ render(action: :index) && return if show_users_info
31
+
49
32
  redirect_to direct_verifications_path
50
33
  end
51
34
 
52
- def permission_class_chain
53
- [
54
- Decidim::DirectVerifications::Verification::Admin::Permissions,
55
- Decidim::Admin::Permissions,
56
- Decidim::Permissions
57
- ]
35
+ private
36
+
37
+ def register_users
38
+ return unless params[:register]
39
+
40
+ @processor.register_users
41
+ flash[:warning] = t(".registered", count: @processor.emails.count,
42
+ registered: @processor.processed[:registered].count,
43
+ errors: @processor.errors[:registered].count)
58
44
  end
59
45
 
60
- def permission_scope
61
- :admin
46
+ def authorize_users
47
+ return unless params[:authorize] == "in"
48
+
49
+ @processor.authorize_users
50
+ flash[:notice] = t(".authorized", handler: t("#{@processor.authorization_handler}.name", scope: "decidim.authorization_handlers"),
51
+ count: @processor.emails.count,
52
+ authorized: @processor.processed[:authorized].count,
53
+ errors: @processor.errors[:authorized].count)
62
54
  end
63
55
 
64
- private
56
+ def revoke_users
57
+ return unless params[:authorize] == "out"
58
+
59
+ @processor.revoke_users
60
+ flash[:notice] = t(".revoked", handler: t("#{@processor.authorization_handler}.name", scope: "decidim.authorization_handlers"),
61
+ count: @processor.emails.count,
62
+ revoked: @processor.processed[:revoked].count,
63
+ errors: @processor.errors[:revoked].count)
64
+ end
65
+
66
+ def show_users_info
67
+ return if params[:authorize]
68
+
69
+ @stats.emails = @processor.emails.keys
70
+ flash.now[:info] = t(".info", handler: t("#{@processor.authorization_handler}.name", scope: "decidim.authorization_handlers"),
71
+ count: @processor.emails.count,
72
+ authorized: @stats.authorized,
73
+ unconfirmed: @stats.unconfirmed,
74
+ registered: @stats.registered)
75
+ true
76
+ end
65
77
 
66
78
  def extract_emails_to_hash(txt)
67
- reg = /([^@\r\n]*)\b([A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,})\b/i
68
- txt.scan(reg).map do |m|
69
- [
70
- m[1].delete("<>").strip,
71
- m[0].gsub(/[^[:print:]]|[\"\$\<\>\|\\]/, "").strip
72
- ]
73
- end .to_h
79
+ reg = /([A-Z0-9+._-]+@[A-Z0-9._-]+\.[A-Z0-9_-]+)\b/i
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
+ end
89
+
90
+ def authorization_handler(authorization_handler)
91
+ @authorization_handler = authorization_handler.presence || :direct_verifications
92
+ end
93
+
94
+ def current_authorization_handler
95
+ authorization_handler(params[:authorization_handler])
96
+ end
97
+
98
+ def configured_workflows
99
+ return Decidim::DirectVerifications.config.manage_workflows if Decidim::DirectVerifications.config
100
+
101
+ ["direct_verifications"]
102
+ end
103
+
104
+ def workflows
105
+ workflows = configured_workflows & current_organization.available_authorizations.map.to_a
106
+ workflows.map do |a|
107
+ [t("#{a}.name", scope: "decidim.authorization_handlers"), a]
108
+ end
74
109
  end
75
110
  end
76
111
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DirectVerifications
5
+ module Verification
6
+ module Admin
7
+ class StatsController < Decidim::Admin::ApplicationController
8
+ include NeedsPermission
9
+
10
+ layout "decidim/admin/users"
11
+
12
+ def index
13
+ enforce_permission_to :index, :authorization
14
+ stats = UserStats.new(current_organization)
15
+ @stats = {
16
+ t(".global") => stats_hash(stats)
17
+ }
18
+ current_organization.available_authorizations.map do |a|
19
+ stats.authorization_handler = a
20
+ @stats[t("#{a}.name", scope: "decidim.authorization_handlers")] = stats_hash(stats)
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def stats_hash(stats)
27
+ {
28
+ registered: stats.registered,
29
+ authorized: stats.authorized,
30
+ unconfirmed: stats.unconfirmed,
31
+ authorized_unconfirmed: stats.authorized_unconfirmed
32
+ }
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,40 +1,44 @@
1
-
2
1
  <div class="card">
3
2
  <div class="card-divider">
4
3
  <h2 class="card-title">
5
- <%= t('admin.index.title', scope: 'decidim.direct_verifications.verification') %>
4
+ <%= t("admin.index.title", scope: "decidim.direct_verifications.verification") %>
5
+ <%= link_to t("admin.index.stats", scope: "decidim.direct_verifications.verification"), stats_path, class: "button tiny button--title" %>
6
6
  </h2>
7
7
  </div>
8
8
  <div class="card-section">
9
- <p><%= t('decidim.direct_verifications.verification.admin.new.info') %></p>
10
- <%= form_tag direct_verifications_path, multipart: true, class: 'form' do %>
11
- <%= label_tag :userlist, t('admin.new.textarea', scope: 'decidim.direct_verifications.verification') %>
12
- <%= text_area_tag :userlist, @userlist, rows: 10 %>
9
+ <p><%= t("decidim.direct_verifications.verification.admin.new.info") %></p>
10
+ <%= form_tag direct_verifications_path, multipart: true, class: "form" do %>
11
+ <%= label_tag :userlist, t("admin.new.textarea", scope: "decidim.direct_verifications.verification") %>
12
+ <%= text_area_tag :userlist, @userslist, rows: 10 %>
13
13
  <label>
14
14
  <%= check_box_tag :register %>
15
- <%= t('admin.new.register', scope: 'decidim.direct_verifications.verification') %>
15
+ <%= t("admin.new.register", scope: "decidim.direct_verifications.verification") %>
16
+ <div data-alert class="callout alert hide">
17
+ <%= t("admin.direct_verifications.gdpr_disclaimer", scope: "decidim.direct_verifications.verification") %>
18
+ </div>
16
19
  </label>
17
20
  <label>
18
- <%= radio_button_tag :authorize, 'in' %>
19
- <%= t('admin.new.authorize', scope: 'decidim.direct_verifications.verification') %>
21
+ <%= radio_button_tag :authorize, "in" %>
22
+ <%= t("admin.new.authorize", scope: "decidim.direct_verifications.verification") %>
20
23
  </label>
21
24
  <label>
22
- <%= radio_button_tag :authorize, 'out' %>
23
- <%= t('admin.new.revoke', scope: 'decidim.direct_verifications.verification') %>
25
+ <%= radio_button_tag :authorize, "out" %>
26
+ <%= t("admin.new.revoke", scope: "decidim.direct_verifications.verification") %>
24
27
  </label>
25
28
  <label>
26
- <%= radio_button_tag :authorize, 'check', true %>
27
- <%= t('admin.new.check', scope: 'decidim.direct_verifications.verification') %>
29
+ <%= radio_button_tag :authorize, "check", true %>
30
+ <%= t("admin.new.check", scope: "decidim.direct_verifications.verification") %>
28
31
  </label>
29
32
 
30
- <%= label_tag :userlist, t('admin.new.authorization_handler', scope: 'decidim.direct_verifications.verification') %>
31
- <%= select_tag :authorization_handler, options_for_select(current_organization.available_authorizations.map { |a|
32
- [t("#{a}.name", scope: "decidim.authorization_handlers"), a]
33
- }, :direct_verifications) %>
33
+ <%= label_tag :authorization_handler, t("admin.new.authorization_handler", scope: "decidim.direct_verifications.verification") %>
34
+
35
+ <%= select_tag :authorization_handler, options_for_select(workflows, current_authorization_handler) %>
34
36
 
35
- <%= submit_tag t('admin.new.submit', scope: 'decidim.direct_verifications.verification'), class: 'button' %>
37
+ <%= submit_tag t("admin.new.submit", scope: "decidim.direct_verifications.verification"), class: "button" %>
36
38
 
37
39
  <% end %>
38
40
 
39
41
  </div>
40
42
  </div>
43
+
44
+ <%= javascript_include_tag "decidim/direct_verifications/verification/admin/direct_verifications_admin" %>
@@ -0,0 +1,35 @@
1
+ <div class="card">
2
+ <div class="card-divider">
3
+ <h2 class="card-title">
4
+ <%= t("admin.index.stats", scope: "decidim.direct_verifications.verification") %>
5
+ <%= link_to t("admin.index.title", scope: "decidim.direct_verifications.verification"), direct_verifications_path, class: "button tiny button--title" %>
6
+ </h2>
7
+ </div>
8
+ <div class="card-section">
9
+ <table class="table-list">
10
+ <thead>
11
+ <tr>
12
+ <th><%= t("admin.new.authorization_handler", scope: "decidim.direct_verifications.verification") %></th>
13
+ <th><%= t(".registered") %></th>
14
+ <th><%= t(".authorized") %></th>
15
+ <th><%= t(".unconfirmed") %></th>
16
+ <th><%= t(".authorized_unconfirmed") %></th>
17
+ <th></th>
18
+ </tr>
19
+ </thead>
20
+ <tbody>
21
+ <% @stats.each do |a, s| %>
22
+ <tr>
23
+ <td>
24
+ <%= a %>
25
+ </td>
26
+ <td><%= s[:registered] %></td>
27
+ <td><%= s[:authorized] %></td>
28
+ <td><%= s[:unconfirmed] %></td>
29
+ <td><%= s[:authorized_unconfirmed] %></td>
30
+ </tr>
31
+ <% end %>
32
+ </tbody>
33
+ </table>
34
+ </div>
35
+ </div>
@@ -26,15 +26,21 @@ ca:
26
26
  authorized: S'han verificat correctament %{authorized} usuaris utilitzant
27
27
  [%{handler}] (%{count} detectats, %{errors} errors)
28
28
  info: S'han detectat %{count} usuaris, dels quals %{registered} estan
29
- registrats, %{authorized} autoritzats utilitzant [%{handler}] (%{unconfirmed} sense confirmar)
29
+ registrats, %{authorized} autoritzats utilitzant [%{handler}] (%{unconfirmed}
30
+ sense confirmar)
30
31
  registered: S'han registrat correctament %{registered} usuaris (%{count}
31
32
  detectats, %{errors} errors)
32
33
  revoked: S'ha revocat correctament la verificació de %{revoked} usuaris
33
34
  utilitzant [%{handler}] (%{count} detectats, %{errors} errors)
35
+ gdpr_disclaimer: Feu-ho sota la vostra responsabilitat. Recordeu que heu
36
+ de tenir el consentiment explícit dels vostres usuaris per registrar-los.
37
+ En cas contrari, estareu infringint la regulació GDPR als països de
38
+ la UE.
34
39
  index:
40
+ stats: Estadístiques d'usuaris
35
41
  title: Inscriu i autoritza usuaris
36
42
  new:
37
- authorization_handler: 'Mètode de verificació:'
43
+ authorization_handler: Mètode de verificació
38
44
  authorize: Autoritza els usuaris
39
45
  check: Comprova l'estat dels usuaris
40
46
  info: Introdueix aquí els emails, un per línia. Si els emails estan precedits
@@ -42,7 +48,23 @@ ca:
42
48
  register: Registra els usuaris a la plataforma (si existeixen s'ignoraran)
43
49
  revoke: Revoca l'autorització dels usuaris
44
50
  submit: Envia i processa el llistat
45
- textarea: 'Llista d''emails:'
51
+ textarea: Llista d''emails
52
+ stats:
53
+ index:
54
+ authorized: Verificats
55
+ authorized_unconfirmed: Verificats però no confirmats
56
+ global: "- Qualsevol mètode de verificació -"
57
+ registered: Registrats
58
+ unconfirmed: No confirmats
46
59
  authorizations:
47
60
  new:
48
61
  no_action: Aquest mètode requereix que un administrador us verifiqui
62
+ verifications:
63
+ authorizations:
64
+ first_login:
65
+ actions:
66
+ direct_verifications: Verificació directa
67
+ devise:
68
+ mailer:
69
+ direct_invite:
70
+ subject: Instruccions d'invitació
@@ -26,15 +26,19 @@ en:
26
26
  authorized: "%{authorized} users have been successfully verified using
27
27
  [%{handler}] (%{count} detected, %{errors} errors)"
28
28
  info: "%{count} users detected, of which %{registered} are registered,
29
- %{authorized} authorized using [%{handler}] (%{unconfirmed} unconfirmed)"
29
+ %{authorized} authorized using [%{handler}] (%{unconfirmed} unconfirmed)"
30
30
  registered: "%{registered} users have been successfully registered (%{count}
31
31
  detected, %{errors} errors) "
32
32
  revoked: Verification from %{revoked} users have been revoked using
33
33
  [%{handler}] (%{count} detected, %{errors} errors)
34
+ gdpr_disclaimer: Do this under your responsibility. Remember that you
35
+ need to have explicit consent from your users in order to register them.
36
+ Otherwise you will be infringing the GDPR regulation in EU countries.
34
37
  index:
38
+ stats: User stats
35
39
  title: Register and authorize users
36
40
  new:
37
- authorization_handler: 'Verification method:'
41
+ authorization_handler: Verification method
38
42
  authorize: Authorize users
39
43
  check: Check users status
40
44
  info: Enter the emails here, one per line. If the emails are preceded
@@ -42,7 +46,23 @@ en:
42
46
  register: Register users in the platform (if they exist they will be ignored)
43
47
  revoke: Revoke authorization from users
44
48
  submit: Send and process the list
45
- textarea: 'Emails list:'
49
+ textarea: Emails list
50
+ stats:
51
+ index:
52
+ authorized: Authorized
53
+ authorized_unconfirmed: Authorized but unconfirmed
54
+ global: "- Any verification method -"
55
+ registered: Registered
56
+ unconfirmed: Unconfirmed
46
57
  authorizations:
47
58
  new:
48
59
  no_action: This method requires an administrator that verifies you
60
+ verifications:
61
+ authorizations:
62
+ first_login:
63
+ actions:
64
+ direct_verifications: Direct verification
65
+ devise:
66
+ mailer:
67
+ direct_invite:
68
+ subject: Invitation instructions
@@ -26,15 +26,21 @@ es:
26
26
  authorized: Se han verificado correctamente %{authorized} usuarios usando
27
27
  [%{handler}] (%{count} detectados, %{errors} errores)
28
28
  info: Se han detectado %{count} usuarios, de los cuales %{registered}
29
- están registrados, %{authorized} autorizados usando [%{handler}] (%{unconfirmed} sin confirmar)
29
+ están registrados, %{authorized} autorizados usando [%{handler}] (%{unconfirmed}
30
+ sin confirmar)
30
31
  registered: Se han registrado correctamente %{registered} usuarios (%{count}
31
32
  detectados, %{errors} errores)
32
33
  revoked: Se ha revocado correctament la verificación de %{revoked} usuarios
33
34
  usando [%{handler}] (%{count} detectados, %{errors} errores)
35
+ gdpr_disclaimer: Haga esto bajo su responsabilidad. Recuerde que debe
36
+ contar con el consentimiento explícito de sus usuarios para poder registrarlos.
37
+ De lo contrario, estará infringiendo la regulación GDPR en los países
38
+ de la UE.
34
39
  index:
40
+ stats: Estadísticas de usuarios
35
41
  title: Inscribe y autoriza usuarios
36
42
  new:
37
- authorization_handler: 'Método de verificación:'
43
+ authorization_handler: Método de verificación
38
44
  authorize: Autoriza los usuarios
39
45
  check: Comprueba el estado de los usuarios
40
46
  info: Introduce aquí los emails, uno por linea. Si los emails están precedidos
@@ -42,7 +48,23 @@ es:
42
48
  register: Registra los usuarios a la plataforma (si existen se ignorarán)
43
49
  revoke: Revoca la autorización de los usuarios
44
50
  submit: Envía y procesa el listado
45
- textarea: 'Lista de emails:'
51
+ textarea: Lista de emails
52
+ stats:
53
+ index:
54
+ authorized: Verificados
55
+ authorized_unconfirmed: Verificados pero sin confirmar
56
+ global: "- Cualquier método de verificación -"
57
+ registered: Registrados
58
+ unconfirmed: Sin confirmar
46
59
  authorizations:
47
60
  new:
48
61
  no_action: Este método requiere que un administrador os verifique
62
+ verifications:
63
+ authorizations:
64
+ first_login:
65
+ actions:
66
+ direct_verifications: Verificación directa
67
+ devise:
68
+ mailer:
69
+ direct_invite:
70
+ subject: Instrucciones de invitación
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "direct_verifications/version"
4
+ require_relative "direct_verifications/config"
4
5
  require_relative "direct_verifications/user_processor"
6
+ require_relative "direct_verifications/user_stats"
5
7
  require_relative "direct_verifications/verification"
6
8
 
7
9
  module Decidim
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DirectVerifications
5
+ class << self
6
+ attr_accessor :config
7
+ def configure
8
+ yield self.config ||= Config.new
9
+ end
10
+ end
11
+
12
+ class Config
13
+ attr_reader :manage_workflows
14
+ def manage_workflows=(manage_workflows)
15
+ @manage_workflows.concat(manage_workflows).uniq!
16
+ end
17
+
18
+ def initialize
19
+ @manage_workflows = ["direct_verifications"]
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ shared_examples_for "checking users" do |params|
4
+ context "when check without mails" do
5
+ it "renders the index with info message" do
6
+ params[:userlist] = ""
7
+ perform_enqueued_jobs do
8
+ post :create, params: params
9
+ expect(flash[:info]).not_to be_empty
10
+ expect(flash[:info]).to include("0 users detected")
11
+ expect(subject).to render_template("decidim/direct_verifications/verification/admin/direct_verifications/index")
12
+ end
13
+ end
14
+ end
15
+
16
+ context "when check with mails" do
17
+ it "renders the index with info message" do
18
+ params[:userlist] = "mail@example.com"
19
+ perform_enqueued_jobs do
20
+ post :create, params: params
21
+ expect(flash[:info]).not_to be_empty
22
+ expect(flash[:info]).to include("1 users detected")
23
+ expect(subject).to render_template("decidim/direct_verifications/verification/admin/direct_verifications/index")
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ shared_examples_for "registering users" do |params|
30
+ context "when there are valid emails" do
31
+ it "creates warning message" do
32
+ perform_enqueued_jobs do
33
+ post :create, params: params
34
+ expect(flash[:warning]).not_to be_empty
35
+ expect(flash[:warning]).to include("1 detected")
36
+ expect(flash[:warning]).to include("0 errors")
37
+ expect(flash[:warning]).to include("1 users")
38
+ expect(flash[:warning]).to include("registered")
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ shared_examples_for "authorizing users" do |params|
45
+ context "when there are valid emails" do
46
+ it "creates notice message" do
47
+ perform_enqueued_jobs do
48
+ post :create, params: params
49
+ expect(flash[:notice]).not_to be_empty
50
+ expect(flash[:notice]).to include("1 detected")
51
+ expect(flash[:notice]).to include("0 errors")
52
+ expect(flash[:notice]).to include("1 users")
53
+ expect(flash[:notice]).to include("verified")
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ shared_examples_for "revoking users" do |params|
60
+ context "when there are valid emails" do
61
+ it "creates notice message" do
62
+ create(
63
+ :authorization,
64
+ :granted,
65
+ name: verification_type,
66
+ user: authorized_user
67
+ )
68
+ perform_enqueued_jobs do
69
+ post :create, params: params
70
+ expect(flash[:notice]).not_to be_empty
71
+ expect(flash[:notice]).to include("1 detected")
72
+ expect(flash[:notice]).to include("0 errors")
73
+ expect(flash[:notice]).to include("1 users")
74
+ expect(flash[:notice]).to include("revoked")
75
+ end
76
+ end
77
+ end
78
+ end
@@ -22,6 +22,7 @@ module Decidim
22
22
  def register_users
23
23
  @emails.each do |email, name|
24
24
  next if find_user(email)
25
+
25
26
  form = register_form(email, name)
26
27
  begin
27
28
  InviteUser.call(form) do
@@ -43,7 +44,8 @@ module Decidim
43
44
  @emails.each do |email, _name|
44
45
  if (u = find_user(email))
45
46
  auth = authorization(u)
46
- next if auth.granted?
47
+ next unless !auth.granted? || auth.expired?
48
+
47
49
  Verification::ConfirmUserAuthorization.call(auth, authorize_form(u)) do
48
50
  on(:ok) do
49
51
  add_processed :authorized, email
@@ -63,6 +65,7 @@ module Decidim
63
65
  if (u = find_user(email))
64
66
  auth = authorization(u)
65
67
  next unless auth.granted?
68
+
66
69
  Verification::DestroyUserAuthorization.call(auth) do
67
70
  on(:ok) do
68
71
  add_processed :revoked, email
@@ -77,24 +80,6 @@ module Decidim
77
80
  end
78
81
  end
79
82
 
80
- def total(type)
81
- if type == :registered
82
- return User.where(email: @emails.keys, decidim_organization_id: @organization.id)
83
- .count
84
- end
85
- if type == :unconfirmed
86
- return User.where(email: @emails.keys, decidim_organization_id: @organization.id)
87
- .where(confirmed_at: nil).count
88
- end
89
- if type == :authorized
90
- return Decidim::Authorization.joins(:user)
91
- .where(name: authorization_handler)
92
- .where("decidim_users.email IN (:emails) AND decidim_users.decidim_organization_id=:org",
93
- emails: @emails.keys, org: @organization.id).count
94
- end
95
- 0
96
- end
97
-
98
83
  private
99
84
 
100
85
  def find_user(email)
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DirectVerifications
5
+ class UserStats
6
+ def initialize(organization)
7
+ @organization = organization
8
+ @authorization_handler = ""
9
+ @emails = []
10
+ end
11
+
12
+ attr_reader :organization, :authorization_handler
13
+ attr_accessor :emails
14
+
15
+ def authorization_handler=(name)
16
+ @workflow_manifest = nil
17
+ @authorization_handler = name
18
+ end
19
+
20
+ def registered
21
+ registered_users.count
22
+ end
23
+
24
+ def unconfirmed
25
+ registered_users.where("decidim_users.confirmed_at IS NULL").count
26
+ end
27
+
28
+ def authorized
29
+ authorized_users.count
30
+ end
31
+
32
+ def authorized_unconfirmed
33
+ authorized_users.where("decidim_users.confirmed_at IS NULL").count
34
+ end
35
+
36
+ private
37
+
38
+ def registered_users
39
+ if authorization_handler.empty?
40
+ filter = { decidim_organization_id: organization.id }
41
+ filter[:email] = emails unless emails.empty?
42
+ return User.where(filter).where.not(email: "")
43
+ end
44
+ authorized_users(false)
45
+ end
46
+
47
+ def authorized_users(strict = true)
48
+ q = Decidim::Authorization.joins(:user)
49
+ unless authorization_handler.empty?
50
+ q = q.where(name: authorization_handler)
51
+ if strict
52
+ q = q.where.not(granted_at: nil)
53
+ q = q.where("decidim_authorizations.granted_at >= :date", date: Time.current - expires_in) if expires_in
54
+ end
55
+ end
56
+ q = q.where("decidim_users.decidim_organization_id=:org and decidim_users.email!=''", org: organization.id)
57
+ return q if emails.empty?
58
+
59
+ q.where("decidim_users.email IN (:emails)", emails: emails)
60
+ end
61
+
62
+ def expires_in
63
+ return unless workflow_manifest
64
+ return if workflow_manifest.expires_in.zero?
65
+
66
+ workflow_manifest.expires_in
67
+ end
68
+
69
+ def workflow_manifest
70
+ return if authorization_handler.empty?
71
+
72
+ @workflow_manifest ||= Decidim::Verifications.find_workflow_manifest(authorization_handler)
73
+ end
74
+ end
75
+ end
76
+ end
@@ -8,10 +8,15 @@ module Decidim
8
8
  paths["db/migrate"] = nil
9
9
 
10
10
  routes do
11
- resources :direct_verifications, only: [:index, :create]
11
+ resources :direct_verifications, only: [:index, :create, :stats]
12
+ resources :stats, only: [:index]
12
13
 
13
14
  root to: "direct_verifications#index"
14
15
  end
16
+
17
+ initializer "decidim_direct_verifications.admin_assets" do |app|
18
+ app.config.assets.precompile += %w(direct_verifications_admin_manifest.js)
19
+ end
15
20
  end
16
21
  end
17
22
  end
@@ -3,7 +3,8 @@
3
3
  module Decidim
4
4
  # This holds the decidim-direct_verifications version.
5
5
  module DirectVerifications
6
- VERSION = "0.17.5"
7
- DECIDIM_VERSION = ">= 0.17.0"
6
+ VERSION = "0.21"
7
+ DECIDIM_VERSION = "0.21"
8
+ MIN_DECIDIM_VERSION = "~> 0.21.0"
8
9
  end
9
10
  end
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: decidim-direct_verifications
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.17.5
4
+ version: '0.21'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivan Vergés
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-04-04 00:00:00.000000000 Z
11
+ date: 2020-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: decidim-admin
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.17.0
19
+ version: 0.21.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.17.0
26
+ version: 0.21.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: decidim-core
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.17.0
33
+ version: 0.21.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.17.0
40
+ version: 0.21.0
41
41
  description: Provides a verification method that also registers users directly in
42
42
  the platform. Can be used to mass verificate user with other verification handlers
43
43
  email:
@@ -49,20 +49,26 @@ files:
49
49
  - LICENSE-AGPLv3.txt
50
50
  - README.md
51
51
  - Rakefile
52
+ - app/assets/config/direct_verifications_admin_manifest.js
53
+ - app/assets/javascripts/decidim/direct_verifications/verification/admin/direct_verifications_admin.js.es6
52
54
  - app/commands/decidim/direct_verifications/verification/confirm_user_authorization.rb
53
55
  - app/commands/decidim/direct_verifications/verification/destroy_user_authorization.rb
54
56
  - app/controllers/decidim/direct_verifications/verification/admin/direct_verifications_controller.rb
57
+ - app/controllers/decidim/direct_verifications/verification/admin/stats_controller.rb
55
58
  - app/controllers/decidim/direct_verifications/verification/authorizations_controller.rb
56
59
  - app/forms/decidim/direct_verifications/verification/direct_verifications_form.rb
57
- - app/permissions/decidim/direct_verifications/verification/admin/permissions.rb
58
60
  - app/views/decidim/direct_verifications/verification/admin/direct_verifications/index.html.erb
61
+ - app/views/decidim/direct_verifications/verification/admin/stats/index.html.erb
59
62
  - app/views/devise/mailer/direct_invite.html.erb
60
63
  - app/views/devise/mailer/direct_invite.text.erb
61
64
  - config/locales/ca.yml
62
65
  - config/locales/en.yml
63
66
  - config/locales/es.yml
64
67
  - lib/decidim/direct_verifications.rb
68
+ - lib/decidim/direct_verifications/config.rb
69
+ - lib/decidim/direct_verifications/tests/verification_controller_examples.rb
65
70
  - lib/decidim/direct_verifications/user_processor.rb
71
+ - lib/decidim/direct_verifications/user_stats.rb
66
72
  - lib/decidim/direct_verifications/verification.rb
67
73
  - lib/decidim/direct_verifications/verification/admin.rb
68
74
  - lib/decidim/direct_verifications/verification/admin_engine.rb
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Decidim
4
- module DirectVerifications
5
- module Verification
6
- module Admin
7
- # Defines the abilities related to direct_verifications for a logged in admin user.
8
- class Permissions < Decidim::DefaultPermissions
9
- def permissions
10
- return permission_action if permission_action.scope != :admin
11
- if user.organization.available_authorizations.include?("direct_verifications")
12
- allow! if permission_action.subject == Decidim::DirectVerifications::UserProcessor
13
- permission_action
14
- end
15
- end
16
- end
17
- end
18
- end
19
- end
20
- end