decidim-direct_verifications 0.17.6 → 0.22

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: baa520a6dc6b5d727bc233c5076a6dd0d042cfcd3fdd0ff4cdde46f7f1837cec
4
- data.tar.gz: 94f879f2b21bfaf542d1820c4d65c84e6769f6e32b9e06ba8930f979dcebc02a
3
+ metadata.gz: 8a3a36032cc453d0d386579125ace610fbc73e85a975196b56ae84c3f10a2296
4
+ data.tar.gz: d20c11a81153e2c9fe79b0663d5b9cd7f077133714d8cf25a872ee1f70ca6741
5
5
  SHA512:
6
- metadata.gz: f2aaa64f6b10b225353285a58f70c44d91c6ab0ac50051f6a82bf5dd63ed73a12f8c5df4e09230a3a5d5d535c5a6303af5c1f64d2c4908a7d37adbbe32632575
7
- data.tar.gz: 9248e063925c40870f2ada644dd55b6a3efd8f5034d4c870945ef0f017277f1cbc256d88911559cd03c1bf1f43a250aeb385a75b4003e6e59191b6eaf428fa76
6
+ metadata.gz: b3201103a89ca52e19fbd493018e45727d81d3b7d626eca0a5735253bc4ee21b5fc3260038cca70c405aed30f4556c807ae35b3b1ec00bc6157acc3f0c16cc33
7
+ data.tar.gz: 170a4e48d8ecadd8abc262626669ed9b8820d85804a0a48350c1ea2a2dc7f2de4a87f6833f71ff23fe1b880ba817b81f8f4823059824bfcce9703d9b45720631
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, session)
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>
@@ -32,10 +32,15 @@ ca:
32
32
  detectats, %{errors} errors)
33
33
  revoked: S'ha revocat correctament la verificació de %{revoked} usuaris
34
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.
35
39
  index:
40
+ stats: Estadístiques d'usuaris
36
41
  title: Inscriu i autoritza usuaris
37
42
  new:
38
- authorization_handler: 'Mètode de verificació:'
43
+ authorization_handler: Mètode de verificació
39
44
  authorize: Autoritza els usuaris
40
45
  check: Comprova l'estat dels usuaris
41
46
  info: Introdueix aquí els emails, un per línia. Si els emails estan precedits
@@ -43,10 +48,22 @@ ca:
43
48
  register: Registra els usuaris a la plataforma (si existeixen s'ignoraran)
44
49
  revoke: Revoca l'autorització dels usuaris
45
50
  submit: Envia i processa el llistat
46
- 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
47
59
  authorizations:
48
60
  new:
49
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
50
67
  devise:
51
68
  mailer:
52
69
  direct_invite:
@@ -31,10 +31,14 @@ en:
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,10 +46,22 @@ 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
49
65
  devise:
50
66
  mailer:
51
67
  direct_invite:
@@ -32,10 +32,15 @@ es:
32
32
  detectados, %{errors} errores)
33
33
  revoked: Se ha revocado correctament la verificación de %{revoked} usuarios
34
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.
35
39
  index:
40
+ stats: Estadísticas de usuarios
36
41
  title: Inscribe y autoriza usuarios
37
42
  new:
38
- authorization_handler: 'Método de verificación:'
43
+ authorization_handler: Método de verificación
39
44
  authorize: Autoriza los usuarios
40
45
  check: Comprueba el estado de los usuarios
41
46
  info: Introduce aquí los emails, uno por linea. Si los emails están precedidos
@@ -43,10 +48,22 @@ es:
43
48
  register: Registra los usuarios a la plataforma (si existen se ignorarán)
44
49
  revoke: Revoca la autorización de los usuarios
45
50
  submit: Envía y procesa el listado
46
- 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
47
59
  authorizations:
48
60
  new:
49
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
50
67
  devise:
51
68
  mailer:
52
69
  direct_invite:
@@ -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
@@ -3,16 +3,17 @@
3
3
  module Decidim
4
4
  module DirectVerifications
5
5
  class UserProcessor
6
- def initialize(organization, current_user)
6
+ def initialize(organization, current_user, session)
7
7
  @organization = organization
8
8
  @current_user = current_user
9
9
  @authorization_handler = :direct_verifications
10
10
  @errors = { registered: [], authorized: [], revoked: [] }
11
11
  @processed = { registered: [], authorized: [], revoked: [] }
12
12
  @emails = {}
13
+ @session = session
13
14
  end
14
15
 
15
- attr_reader :organization, :current_user, :errors, :processed, :emails
16
+ attr_reader :organization, :current_user, :session, :errors, :processed, :emails
16
17
  attr_accessor :authorization_handler
17
18
 
18
19
  def emails=(email_list)
@@ -22,6 +23,7 @@ module Decidim
22
23
  def register_users
23
24
  @emails.each do |email, name|
24
25
  next if find_user(email)
26
+
25
27
  form = register_form(email, name)
26
28
  begin
27
29
  InviteUser.call(form) do
@@ -43,8 +45,9 @@ module Decidim
43
45
  @emails.each do |email, _name|
44
46
  if (u = find_user(email))
45
47
  auth = authorization(u)
46
- next if auth.granted?
47
- Verification::ConfirmUserAuthorization.call(auth, authorize_form(u)) do
48
+ next unless !auth.granted? || auth.expired?
49
+
50
+ Verification::ConfirmUserAuthorization.call(auth, authorize_form(u), session) do
48
51
  on(:ok) do
49
52
  add_processed :authorized, email
50
53
  end
@@ -63,6 +66,7 @@ module Decidim
63
66
  if (u = find_user(email))
64
67
  auth = authorization(u)
65
68
  next unless auth.granted?
69
+
66
70
  Verification::DestroyUserAuthorization.call(auth) do
67
71
  on(:ok) do
68
72
  add_processed :revoked, email
@@ -77,24 +81,6 @@ module Decidim
77
81
  end
78
82
  end
79
83
 
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
84
  private
99
85
 
100
86
  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.6"
7
- DECIDIM_VERSION = ">= 0.17.0"
6
+ VERSION = "0.22"
7
+ DECIDIM_VERSION = "0.22"
8
+ MIN_DECIDIM_VERSION = ">= 0.22.0"
8
9
  end
9
10
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: decidim-direct_verifications
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.17.6
4
+ version: '0.22'
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
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.17.0
19
+ version: 0.22.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.22.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.22.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.22.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