decidim-verifications 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +101 -0
  3. data/Rakefile +3 -0
  4. data/app/commands/decidim/verifications/authorize_user.rb +61 -0
  5. data/app/commands/decidim/verifications/confirm_user_authorization.rb +49 -0
  6. data/app/commands/decidim/verifications/perform_authorization_step.rb +48 -0
  7. data/app/controllers/decidim/verifications/authorizations_controller.rb +91 -0
  8. data/app/controllers/decidim/verifications/id_documents/admin/confirmations_controller.rb +48 -0
  9. data/app/controllers/decidim/verifications/id_documents/admin/pending_authorizations_controller.rb +28 -0
  10. data/app/controllers/decidim/verifications/id_documents/admin/rejections_controller.rb +37 -0
  11. data/app/controllers/decidim/verifications/id_documents/authorizations_controller.rb +82 -0
  12. data/app/controllers/decidim/verifications/postal_letter/admin/pending_authorizations_controller.rb +27 -0
  13. data/app/controllers/decidim/verifications/postal_letter/admin/postages_controller.rb +41 -0
  14. data/app/controllers/decidim/verifications/postal_letter/authorizations_controller.rb +74 -0
  15. data/app/forms/decidim/verifications/id_documents/information_form.rb +50 -0
  16. data/app/forms/decidim/verifications/id_documents/information_rejection_form.rb +15 -0
  17. data/app/forms/decidim/verifications/id_documents/upload_form.rb +20 -0
  18. data/app/forms/decidim/verifications/postal_letter/address_form.rb +28 -0
  19. data/app/forms/decidim/verifications/postal_letter/confirmation_form.rb +19 -0
  20. data/app/forms/decidim/verifications/postal_letter/postage_form.rb +34 -0
  21. data/app/presenters/decidim/verifications/id_documents/authorization_presenter.rb +20 -0
  22. data/app/presenters/decidim/verifications/postal_letter/authorization_presenter.rb +59 -0
  23. data/app/queries/decidim/verifications/authorizations.rb +41 -0
  24. data/app/services/decidim/authorization_handler.rb +112 -0
  25. data/app/services/decidim/dummy_authorization_handler.rb +27 -0
  26. data/app/uploaders/decidim/verifications/attachment_uploader.rb +16 -0
  27. data/app/views/decidim/verifications/authorizations/first_login.html.erb +22 -0
  28. data/app/views/decidim/verifications/authorizations/index.html.erb +78 -0
  29. data/app/views/decidim/verifications/authorizations/new.html.erb +33 -0
  30. data/app/views/decidim/verifications/id_documents/admin/confirmations/new.html.erb +26 -0
  31. data/app/views/decidim/verifications/id_documents/admin/pending_authorizations/index.html.erb +32 -0
  32. data/app/views/decidim/verifications/id_documents/authorizations/edit.html.erb +53 -0
  33. data/app/views/decidim/verifications/id_documents/authorizations/new.html.erb +35 -0
  34. data/app/views/decidim/verifications/postal_letter/admin/pending_authorizations/index.html.erb +50 -0
  35. data/app/views/decidim/verifications/postal_letter/authorizations/edit.html.erb +37 -0
  36. data/app/views/decidim/verifications/postal_letter/authorizations/new.html.erb +27 -0
  37. data/config/locales/ca.yml +126 -0
  38. data/config/locales/en.yml +126 -0
  39. data/config/locales/es.yml +126 -0
  40. data/config/locales/eu.yml +125 -0
  41. data/config/locales/fi.yml +125 -0
  42. data/config/locales/fr.yml +125 -0
  43. data/config/locales/it.yml +125 -0
  44. data/config/locales/nl.yml +125 -0
  45. data/config/locales/pl.yml +125 -0
  46. data/config/locales/pt.yml +125 -0
  47. data/config/locales/ru.yml +5 -0
  48. data/config/locales/uk.yml +41 -0
  49. data/db/migrate/20171030133426_move_authorizations_to_new_api.rb +66 -0
  50. data/lib/decidim/verifications.rb +26 -0
  51. data/lib/decidim/verifications/adapter.rb +88 -0
  52. data/lib/decidim/verifications/dummy.rb +5 -0
  53. data/lib/decidim/verifications/engine.rb +24 -0
  54. data/lib/decidim/verifications/id_documents.rb +6 -0
  55. data/lib/decidim/verifications/id_documents/admin.rb +12 -0
  56. data/lib/decidim/verifications/id_documents/admin_engine.rb +21 -0
  57. data/lib/decidim/verifications/id_documents/engine.rb +18 -0
  58. data/lib/decidim/verifications/id_documents/workflow.rb +6 -0
  59. data/lib/decidim/verifications/postal_letter.rb +6 -0
  60. data/lib/decidim/verifications/postal_letter/admin.rb +12 -0
  61. data/lib/decidim/verifications/postal_letter/admin_engine.rb +21 -0
  62. data/lib/decidim/verifications/postal_letter/engine.rb +18 -0
  63. data/lib/decidim/verifications/postal_letter/workflow.rb +6 -0
  64. data/lib/decidim/verifications/registry.rb +39 -0
  65. data/lib/decidim/verifications/version.rb +10 -0
  66. data/lib/decidim/verifications/workflow_manifest.rb +56 -0
  67. data/lib/decidim/verifications/workflows.rb +58 -0
  68. metadata +152 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0bcafbf13f475478c5f7f53c1c4c5493926dc09f
4
+ data.tar.gz: 86d57eecdd80590628847fcfe9d56139cc9114ad
5
+ SHA512:
6
+ metadata.gz: 19c99dd7f94b58209f0c2f7bf0a31449c739c2f555992237f9226c2bdf17703c5b58a59c1982c40237b564483b37396cb587bbee453b64e0fb99e7bef5cfce4e
7
+ data.tar.gz: f799da0090c4168632ef49a25ef6c29abf2efe6c7101895c1f4320a5ebbe00a49a41fa387ac7361d98dac4782d455cd6f851fbb0a17edd791a629cba412f9a8d
data/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # Decidim::Verifications
2
+
3
+ Decidim offers several methods for allowing participants to get authorization to
4
+ perform certain privileged actions. This gem implements several of those methods
5
+ and also offers a way for installation to implement their custom verification
6
+ methods.
7
+
8
+ ## Introduction
9
+
10
+ Each decidim instance is in full control of its authorizations, and can customize:
11
+
12
+ * The different methods to be used by users to get verified. For example,
13
+ through a census, by uploading their identity documents, or by receiving a
14
+ verification home at their address.
15
+
16
+ * The different actions in decidim that require authorization, and which
17
+ authorization method they require. For example, a decidim instance might
18
+ choose to require census authorization to create proposals, but a fully
19
+ verified address via a verification code sent by postal mail for voting on
20
+ proposals.
21
+
22
+ ## Types of authorization methods
23
+
24
+ Decidim implements two type of authorization methods:
25
+
26
+ * _Form authorizations_.
27
+
28
+ When your verification method is simple enough, you can use a `Rectify::Form`
29
+ to implement it. "Simple" here means that the authorization can be granted
30
+ with the submission of a single form. For example, to validate a user against
31
+ a census API you will need a form with some fields that your users will use to
32
+ authenticate against a census (for example, an ID and a Postal Code). You'll
33
+ implement this with a form class. See the documentation for the [parent
34
+ class][authorization handler base class] or have a look at a
35
+ [live example][live authorization handler example] in decidim-barcelona.
36
+
37
+ To register your handler, use
38
+
39
+ ```ruby
40
+ # config/initializers/decidim.rb
41
+
42
+ Decidim::Verifications.register_workflow(:census) do |workflow|
43
+ workflow.form = "<myAuthorizationHandlerClass"
44
+ end
45
+ ```
46
+
47
+ * _Workflow authorizations_.
48
+
49
+ For more complex scenarios requiring several steps or admin intervention, you
50
+ can register a verification flow.
51
+
52
+ For example:
53
+
54
+ ```ruby
55
+ # config/initializers/decidim.rb
56
+
57
+ Decidim::Verifications.register_workflow(:sms_verification) do |workflow|
58
+ workflow.engine = Decidim::Verifications::SmsVerification::Engine
59
+ workflow.admin_engine = Decidim::Verifications::SmsVerification::AdminEngine
60
+ end
61
+ ```
62
+
63
+ Inside these engines, you can implement any steps required for the
64
+ authorization to succeed, via one or more custom controllers and views. You
65
+ can create partial `Authorization` records (with the `verified_at` column set
66
+ to `nil`) and hold partial verification data in the `verification_metadata`
67
+ column, or even a partial verification attachment in the
68
+ `verification_attachment` column.
69
+
70
+ Decidim currently requires that your main engine defines two routes:
71
+
72
+ * `new_authorization_path`: This is the entry point to start the authorization
73
+ process.
74
+
75
+ * `edit_authorization_path`: This is the entry point to resume an existing
76
+ authorization process.
77
+
78
+ ## Installation
79
+
80
+ Add this line to your application's Gemfile:
81
+
82
+ ```ruby
83
+ gem 'decidim-verifications'
84
+ ```
85
+
86
+ And then execute:
87
+
88
+ ```bash
89
+ bundle
90
+ ```
91
+
92
+ ## Contributing
93
+
94
+ See [Decidim](https://github.com/decidim/decidim).
95
+
96
+ ## License
97
+
98
+ See [Decidim](https://github.com/decidim/decidim).
99
+
100
+ [authorization handler base class]: https://github.com/decidim/decidim/blob/master/decidim-core/app/services/decidim/authorization_handler.rb
101
+ [real authorization handler]: https://github.com/decidim/decidim-barcelona/blob/master/app/services/census_authorization_handler.rb
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "decidim/dev/common_rake"
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Verifications
5
+ # A command to authorize a user with an authorization handler.
6
+ class AuthorizeUser < Rectify::Command
7
+ # Public: Initializes the command.
8
+ #
9
+ # handler - An AuthorizationHandler object.
10
+ def initialize(handler)
11
+ @handler = handler
12
+ end
13
+
14
+ # Executes the command. Broadcasts these events:
15
+ #
16
+ # - :ok when everything is valid.
17
+ # - :invalid if the handler wasn't valid and we couldn't proceed.
18
+ #
19
+ # Returns nothing.
20
+ def call
21
+ return broadcast(:invalid) unless handler.valid? && unique?
22
+
23
+ create_authorization
24
+ broadcast(:ok)
25
+ end
26
+
27
+ private
28
+
29
+ attr_reader :handler
30
+
31
+ def create_authorization
32
+ authorization = Authorization.find_or_initialize_by(
33
+ user: handler.user,
34
+ name: handler.handler_name
35
+ )
36
+
37
+ authorization.attributes = {
38
+ unique_id: handler.unique_id,
39
+ metadata: handler.metadata
40
+ }
41
+
42
+ authorization.grant!
43
+ end
44
+
45
+ def unique?
46
+ return true if handler.unique_id.nil?
47
+
48
+ duplicates = Authorization.where(
49
+ user: User.where.not(id: handler.user.id).where(organization: handler.user.organization.id),
50
+ name: handler.handler_name,
51
+ unique_id: handler.unique_id
52
+ )
53
+
54
+ return true unless duplicates.any?
55
+
56
+ handler.errors.add(:base, I18n.t("decidim.authorization_handlers.errors.duplicate_authorization"))
57
+ false
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Verifications
5
+ # A command to confirm a previous partial authorization.
6
+ class ConfirmUserAuthorization < Rectify::Command
7
+ # Public: Initializes the command.
8
+ #
9
+ # authorization - An Authorization to be confirmed.
10
+ # form - A form object with the verification data to confirm it.
11
+ def initialize(authorization, form)
12
+ @authorization = authorization
13
+ @form = form
14
+ end
15
+
16
+ # Executes the command. Broadcasts these events:
17
+ #
18
+ # - :ok when everything is valid.
19
+ # - :invalid if the handler wasn't valid and we couldn't proceed.
20
+ #
21
+ # Returns nothing.
22
+ def call
23
+ return broadcast(:already_confirmed) if authorization.granted?
24
+
25
+ return broadcast(:invalid) unless form.valid?
26
+
27
+ if confirmation_successful?
28
+ authorization.grant!
29
+
30
+ broadcast(:ok)
31
+ else
32
+ broadcast(:invalid)
33
+ end
34
+ end
35
+
36
+ protected
37
+
38
+ def confirmation_successful?
39
+ form.verification_metadata.all? do |key, value|
40
+ authorization.verification_metadata[key] == value
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ attr_reader :authorization, :form
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Verifications
5
+ # A command to create a partial authorization for a user.
6
+ class PerformAuthorizationStep < Rectify::Command
7
+ # Public: Initializes the command.
8
+ #
9
+ # authorization - An Authorization object.
10
+ # handler - An AuthorizationHandler object.
11
+ def initialize(authorization, handler)
12
+ @authorization = authorization
13
+ @handler = handler
14
+ end
15
+
16
+ # Executes the command. Broadcasts these events:
17
+ #
18
+ # - :ok when everything is valid.
19
+ # - :invalid if the handler wasn't valid and we couldn't proceed.
20
+ #
21
+ # Returns nothing.
22
+ def call
23
+ return broadcast(:invalid) unless handler.valid?
24
+
25
+ update_verification_data
26
+
27
+ broadcast(:ok)
28
+ end
29
+
30
+ protected
31
+
32
+ def update_verification_data
33
+ authorization.attributes = {
34
+ unique_id: handler.unique_id,
35
+ metadata: handler.metadata,
36
+ verification_metadata: handler.verification_metadata,
37
+ verification_attachment: handler.verification_attachment
38
+ }
39
+
40
+ authorization.save!
41
+ end
42
+
43
+ private
44
+
45
+ attr_reader :authorization, :handler
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Verifications
5
+ # This controller allows users to create and destroy their authorizations. It
6
+ # shouldn't be necessary to expand it to add new authorization schemes.
7
+ class AuthorizationsController < Decidim::ApplicationController
8
+ helper_method :handler, :unauthorized_methods
9
+ before_action :valid_handler, only: [:new, :create]
10
+
11
+ include Decidim::UserProfile
12
+ helper Decidim::DecidimFormHelper
13
+ helper Decidim::CtaButtonHelper
14
+ helper Decidim::AuthorizationFormHelper
15
+
16
+ layout "layouts/decidim/user_profile", only: [:index]
17
+
18
+ def new; end
19
+
20
+ def index
21
+ @granted_authorizations = granted_authorizations
22
+ @pending_authorizations = pending_authorizations
23
+ end
24
+
25
+ def first_login
26
+ if unauthorized_methods.length == 1
27
+ redirect_to(
28
+ action: :new,
29
+ handler: unauthorized_methods.first.name,
30
+ redirect_url: decidim.account_path
31
+ )
32
+ end
33
+ end
34
+
35
+ def create
36
+ AuthorizeUser.call(handler) do
37
+ on(:ok) do
38
+ flash[:notice] = t("authorizations.create.success", scope: "decidim.verifications")
39
+ redirect_to params[:redirect_url] || authorizations_path
40
+ end
41
+
42
+ on(:invalid) do
43
+ flash[:alert] = t("authorizations.create.error", scope: "decidim.verifications")
44
+ render action: :new
45
+ end
46
+ end
47
+ end
48
+
49
+ protected
50
+
51
+ def handler
52
+ @handler ||= Decidim::AuthorizationHandler.handler_for(handler_name, handler_params)
53
+ end
54
+
55
+ def handler_params
56
+ (params[:authorization_handler] || {}).merge(user: current_user)
57
+ end
58
+
59
+ def handler_name
60
+ params[:handler] || params.dig(:authorization_handler, :handler_name)
61
+ end
62
+
63
+ def valid_handler
64
+ return true if handler
65
+
66
+ logger.warn "Invalid authorization handler given: #{handler_name} doesn't"\
67
+ "exist or you haven't added it to `Decidim.authorization_handlers`"
68
+
69
+ redirect_to(authorizations_path) && (return false)
70
+ end
71
+
72
+ def unauthorized_methods
73
+ @unauthorized_methods ||= available_verification_workflows.reject do |handler|
74
+ active_authorization_methods.include?(handler.key)
75
+ end
76
+ end
77
+
78
+ def active_authorization_methods
79
+ Authorizations.new(user: current_user).pluck(:name)
80
+ end
81
+
82
+ def granted_authorizations
83
+ Authorizations.new(user: current_user, granted: true)
84
+ end
85
+
86
+ def pending_authorizations
87
+ Authorizations.new(user: current_user, granted: false)
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Verifications
5
+ module IdDocuments
6
+ module Admin
7
+ #
8
+ # Handles confirmations for verification by identity document upload.
9
+ #
10
+ class ConfirmationsController < Decidim::Admin::ApplicationController
11
+ layout "decidim/admin/users"
12
+
13
+ before_action :load_pending_authorization
14
+
15
+ def new
16
+ authorize! :update, @pending_authorization
17
+
18
+ @form = InformationForm.new
19
+ end
20
+
21
+ def create
22
+ authorize! :update, @pending_authorization
23
+
24
+ @form = InformationForm.from_params(params)
25
+
26
+ ConfirmUserAuthorization.call(@pending_authorization, @form) do
27
+ on(:ok) do
28
+ flash[:notice] = t("confirmations.create.success", scope: "decidim.verifications.id_documents.admin")
29
+ redirect_to pending_authorizations_path
30
+ end
31
+
32
+ on(:invalid) do
33
+ flash.now[:alert] = t("confirmations.create.error", scope: "decidim.verifications.id_documents.admin")
34
+ render action: :new
35
+ end
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def load_pending_authorization
42
+ @pending_authorization = Authorization.find(params[:pending_authorization_id])
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Verifications
5
+ module IdDocuments
6
+ module Admin
7
+ class PendingAuthorizationsController < Decidim::Admin::ApplicationController
8
+ layout "decidim/admin/users"
9
+
10
+ def index
11
+ authorize! :index, Authorization
12
+
13
+ @pending_authorizations = pending_authorizations
14
+ end
15
+
16
+ private
17
+
18
+ def pending_authorizations
19
+ Authorizations
20
+ .new(name: "id_documents", granted: false)
21
+ .query
22
+ .where("verification_metadata->'rejected' IS NULL")
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end