decidim-verify_wo_registration 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE-MIT.txt +7 -0
  3. data/README.md +63 -0
  4. data/Rakefile +9 -0
  5. data/app/commands/decidim/verify_wo_registration/do_verify_wo_registration.rb +126 -0
  6. data/app/controllers/decidim/verify_wo_registration/admin/application_controller.rb +15 -0
  7. data/app/controllers/decidim/verify_wo_registration/application_controller.rb +13 -0
  8. data/app/controllers/decidim/verify_wo_registration/verifications_controller.rb +69 -0
  9. data/app/forms/decidim/verify_wo_registration/verify_wo_registration_form.rb +83 -0
  10. data/app/helpers/decidim/verify_wo_registration/application_helper.rb +29 -0
  11. data/app/models/decidim/verify_wo_registration/application_record.rb +10 -0
  12. data/app/packs/images/decidim/verify_wo_registration/icon.svg +1 -0
  13. data/app/views/decidim/shared/_login_modal.html.erb +50 -0
  14. data/app/views/decidim/shared/_verify_wo_registration_login_modal.html.erb +23 -0
  15. data/app/views/decidim/shared/_verify_wo_registration_login_modal_col1.html.erb +10 -0
  16. data/app/views/decidim/shared/_verify_wo_registration_login_modal_col2.html.erb +31 -0
  17. data/app/views/decidim/verify_wo_registration/verifications/_form.html.erb +15 -0
  18. data/app/views/decidim/verify_wo_registration/verifications/_handler_form.html.erb +7 -0
  19. data/app/views/decidim/verify_wo_registration/verifications/new.html.erb +27 -0
  20. data/config/i18n-tasks.yml +10 -0
  21. data/config/locales/ca.yml +26 -0
  22. data/config/locales/en.yml +26 -0
  23. data/config/locales/es.yml +26 -0
  24. data/lib/decidim/verify_wo_registration/admin.rb +10 -0
  25. data/lib/decidim/verify_wo_registration/admin_engine.rb +27 -0
  26. data/lib/decidim/verify_wo_registration/config/assets.rb +40 -0
  27. data/lib/decidim/verify_wo_registration/engine.rb +29 -0
  28. data/lib/decidim/verify_wo_registration/extend_components.rb +15 -0
  29. data/lib/decidim/verify_wo_registration/test/factories.rb +13 -0
  30. data/lib/decidim/verify_wo_registration/version.rb +17 -0
  31. data/lib/decidim/verify_wo_registration.rb +13 -0
  32. metadata +160 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5591c6786a6b868acab83dda9fb1617ce216abb8e38eeec9e6a69e0780feb44a
4
+ data.tar.gz: 0bc507423086d5f268420349b8b5f29ed7ce0c38dc87feb182c0438490fa4d3a
5
+ SHA512:
6
+ metadata.gz: 6c22ded2aa0c47e74f5ef3ae33c8429c1d646e05bee45870e4d45a08e1bab5e53d7bb51bb48ef7bc38d1af5cc007cf1b643b033f02a506ecec87ca317d177751
7
+ data.tar.gz: a303a1d45f444395ce17ff9d880e5436da0961fccaf1b0edbcbdfc4cbb81da27ce5f9fa4b1d73883c8845dd0ec6cdb53d2e40e6c04571b7989d5b0c0dc6eda51
data/LICENSE-MIT.txt ADDED
@@ -0,0 +1,7 @@
1
+ Copyright 2020 CodiTramuntana SL
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # Decidim::VerifyWoRegistration
2
+
3
+ Adds the hability for proposals and budgets components to allow users to give support without being registered. Enabling this feature the user is requested for verification and then, on success, logged in into a 30min session.
4
+
5
+ The current behavior is as follows. When the logged out user arrives to an action that requires verifiaction the popup offers a new option to allow the user to open a temporal session without the need to signup to the platform. Once selected the form for the first direct verifier found is rendered to the user to fill it.
6
+ On submit, first checks if there's already an authorization for the first direct verifier. If an authorization exists, redirects back and tells the user to use the already verified account, if not, then tries to verify the user with the current data in the form.
7
+ A special case are impersonated (managed) users that are re-authenticated every time.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'decidim-verify_wo_registration'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ ```bash
20
+ bundle install
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ This module allows admins to enable participants to open sessions from Proposals and Budgets components (login in) without being registered.
26
+
27
+ For this feature to be enabled admins should do two things:
28
+
29
+ - navigate to the corresponding component, select the "Enable supports without registration (user only verifies)" ("Poder donar suports sense registre (només verificant-se)") check and save.
30
+ - navigate to this component's permissions, and select a direct verifier for some of its actions. Note that multi-step verifiers are not supported.
31
+
32
+ This will enable the feature in the public views.
33
+
34
+ Once enabled, non registered (thus not logged in) participants will have to navigate to the given component (a proposal or a budget) and click in the support/vote/select project action. The login modal now will have a new "I have no user and I do not want to" button that takes the participant to a verification screen. Once the user is correctly verified, a 30min session starts for her to participate.
35
+
36
+ Note that although the only way for participants to open a session is by clicking the "Support" button, once verified, she will be able to perform all the actions that require the authentications she has verified for.
37
+
38
+ ### Warning
39
+
40
+ Platform administrators should take care not to reset authorizations while in the middle of a process.
41
+ Reseting verifications will remove `Authorization`s from existing impersonated users. This will allow participants to vote again in the same process with the same credentials via this module or being "manually" impersonated.
42
+
43
+ ## Run tests
44
+
45
+ Create a dummy app in your application (if not present):
46
+
47
+ ```bash
48
+ bin/rails decidim:generate_external_test_app
49
+ ```
50
+
51
+ And run tests:
52
+
53
+ ```bash
54
+ bundle exec rspec spec
55
+ ```
56
+
57
+ ## Contributing
58
+
59
+ See [Decidim](https://github.com/decidim/decidim).
60
+
61
+ ## License
62
+
63
+ This engine is distributed under the GNU AFFERO GENERAL PUBLIC LICENSE.
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'decidim/dev/common_rake'
4
+
5
+ desc 'Generates a dummy app for testing'
6
+ task test_app: 'decidim:generate_external_test_app'
7
+
8
+ desc 'Generates a development app.'
9
+ task development_app: 'decidim:generate_external_development_app'
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module VerifyWoRegistration
5
+ # A command with all the business logic to verify and impersonate (managed user).
6
+ class DoVerifyWoRegistration < Decidim::Command
7
+ # Public: Initializes the command.
8
+ #
9
+ # form - The form with the authorization info
10
+ def initialize(form)
11
+ @form = form
12
+ end
13
+
14
+ # Executes the command. Broadcasts this events:
15
+ #
16
+ # - :ok when everything is valid.
17
+ # - :invalid if the form is not valid.
18
+ #
19
+ # Returns nothing.
20
+ def call
21
+ if authorizations_exists?
22
+ if existing_registered_user?
23
+ # ignore form data, make the participant use the already existing user
24
+ broadcast(:use_registered_user)
25
+ elsif existing_impersonated_user?
26
+ # we can not reuse existing authorization because it will raise "A participant is already authorized with the same data." on @form.valid?
27
+ # as it is an impersonated user, we can safely destroy it and perform the verification process again
28
+ transaction do
29
+ @user = @authorization.user
30
+ user.skip_confirmation!
31
+ destroy_authorization
32
+ if @form.valid?
33
+ authorize_user
34
+ broadcast(:ok, user)
35
+ else
36
+ broadcast(:invalid)
37
+ end
38
+ end
39
+ else
40
+ Rails.logger.warn('This should never happen :(')
41
+ broadcast(:invalid)
42
+ end
43
+ elsif @form.valid?
44
+ transaction do
45
+ create_user
46
+ authorize_user
47
+ end
48
+ broadcast(:ok, user)
49
+ else
50
+ broadcast(:invalid)
51
+ end
52
+ end
53
+
54
+ #----------------------------------------------------------------------
55
+ private
56
+ #----------------------------------------------------------------------
57
+
58
+ attr_reader :user, :form
59
+
60
+ # Searches for a registered (not managed) user associated with the given form authorizations.
61
+ def existing_registered_user?
62
+ @user = @authorization.user unless @authorization.user.managed?
63
+ end
64
+
65
+ def existing_impersonated_user?
66
+ @authorization.user.managed?
67
+ end
68
+
69
+ # Some authentication already exists?
70
+ # Sets the first found authorization to +@authorization+ attribute.
71
+ def authorizations_exists?
72
+ @form.authorization_handlers.any? do |handler|
73
+ @authorization = Authorization.joins(:user).where('decidim_users.decidim_organization_id = ?', form.current_organization).where(
74
+ name: handler.handler_name,
75
+ unique_id: handler.unique_id
76
+ ).first
77
+ end
78
+ end
79
+
80
+ def destroy_authorization
81
+ @authorization.destroy
82
+ end
83
+
84
+ def authorize_user
85
+ transaction do
86
+ create_or_update_authorization
87
+ update_user_extended_data
88
+ end
89
+ end
90
+
91
+ def create_user
92
+ @user = @form.authorization_handlers.first.user
93
+ user.save!
94
+ end
95
+
96
+ def create_or_update_authorization
97
+ handler= @form.verified_handler
98
+ handler.user = user
99
+ Authorization.create_or_update_from(handler)
100
+ end
101
+
102
+ def user_authorizations
103
+ ::Decidim::Verifications::Authorizations.new(
104
+ organization: form.current_organization,
105
+ user: user,
106
+ granted: true
107
+ ).query
108
+ end
109
+
110
+ def update_user_extended_data
111
+ user.update(
112
+ extended_data: {
113
+ component_id: @form.component_id,
114
+ authorizations: user_authorizations.as_json(only: %i[name granted_at metadata unique_id]),
115
+ unique_id: unique_id,
116
+ session_expired_at: 30.minutes.from_now
117
+ }
118
+ )
119
+ end
120
+
121
+ def unique_id
122
+ user_authorizations.pluck(:unique_id).sort.join('-')
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module VerifyWoRegistration
5
+ module Admin
6
+ # This controller is the abstract class from which all other controllers of
7
+ # this engine inherit.
8
+ #
9
+ # Note that it inherits from `Decidim::Admin::Components::BaseController`, which
10
+ # override its layout and provide all kinds of useful methods.
11
+ class ApplicationController < Decidim::Admin::Components::BaseController
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module VerifyWoRegistration
5
+ # This controller is the abstract class from which all other controllers of
6
+ # this engine inherit.
7
+ #
8
+ # Note that it inherits from `Decidim::Components::BaseController`, which
9
+ # override its layout and provide all kinds of useful methods.
10
+ class ApplicationController < Decidim::Components::BaseController
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module VerifyWoRegistration
5
+ class VerificationsController < Decidim::ApplicationController
6
+ include ::Devise::Controllers::Helpers
7
+ include ::Decidim::VerifyWoRegistration::ApplicationHelper
8
+ include FormFactory
9
+
10
+ before_action :validate_verification_workflow_manifests!
11
+
12
+ helper Decidim::AuthorizationFormHelper
13
+
14
+ def new
15
+ @form = form(VerifyWoRegistrationForm).from_params(params)
16
+ end
17
+
18
+ def create
19
+ @form = form(VerifyWoRegistrationForm).from_params(form_params)
20
+
21
+ DoVerifyWoRegistration.call(@form) do
22
+ on(:ok) do |user|
23
+ flash[:notice] = I18n.t('verify_wo_registration.create.success', minutes: ::Decidim::ImpersonationLog::SESSION_TIME_IN_MINUTES)
24
+
25
+ sign_in(user)
26
+ redirect_to @form.redirect_url
27
+ end
28
+
29
+ on(:use_registered_user) do
30
+ flash.now[:alert] = I18n.t('verify_wo_registration.create.use_registered_user')
31
+ render :new
32
+ end
33
+
34
+ on(:invalid) do
35
+ flash.now[:alert] = I18n.t('impersonations.create.error', scope: 'decidim.admin')
36
+ render :new
37
+ end
38
+ end
39
+ end
40
+
41
+ # -------------------------------------------------------------
42
+ private
43
+ # -------------------------------------------------------------
44
+
45
+ def form_params
46
+ {
47
+ authorizations: verify_params[:authorizations],
48
+ component_id: component.id,
49
+ redirect_url: verify_params[:redirect_url]
50
+ }
51
+ end
52
+
53
+ def verify_params
54
+ params[:verify_wo_registration].permit!
55
+ end
56
+
57
+ def component
58
+ @component ||= Decidim::Component.find(params[:component_id] || verify_params[:component_id])
59
+ end
60
+
61
+ # Should we validate that only 'direct' verification handlers are enabled?
62
+ def validate_verification_workflow_manifests!
63
+ return if Decidim::VerifyWoRegistration::ApplicationHelper.verify_wo_registration_custom_modal?(component)
64
+
65
+ raise 'Invalid verifications, all verifications should be of type direct'
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module VerifyWoRegistration
5
+ # A form object used to wrap and validate params from the controller to the command.
6
+ #
7
+ class VerifyWoRegistrationForm < Form
8
+ attribute :authorizations, Hash
9
+ attribute :component_id, String
10
+ attribute :redirect_url, String
11
+
12
+ validates_presence_of :component_id, :redirect_url
13
+ validate :verify_against_enabled_authorization_handlers
14
+
15
+ # Returns authorization_handlers that were configured for the current component
16
+ def authorization_handlers
17
+ @authorization_handlers ||= begin
18
+ ::Decidim::VerifyWoRegistration::ApplicationHelper.workflow_manifests(component).map do |workflow_manifest|
19
+ Decidim::AuthorizationHandler.handler_for(workflow_manifest.name, handler_params(workflow_manifest.name))
20
+ end
21
+ end
22
+ end
23
+
24
+ # The authorizations from the params may be in the following format:
25
+ #
26
+ # ```
27
+ # {"0"=>{"handler_name"=>"dummy_authorization_handler", "document_number"=>"00000000X", "postal_code"=>"00000", "birthday"=>"23/06/6"}}
28
+ # ```
29
+ #
30
+ def handler_params(handler_name)
31
+ authorization_params = authorizations
32
+ return default_handler_params if authorization_params.nil?
33
+
34
+ authorization_params = authorization_params.values.find { |h| h.with_indifferent_access[:handler_name] == handler_name }
35
+ return default_handler_params if authorization_params.nil?
36
+
37
+ authorization_params.merge(default_handler_params)
38
+ end
39
+
40
+ def default_handler_params
41
+ { user: new_verified_user }
42
+ end
43
+
44
+ def new_verified_user
45
+ @new_verified_user ||= Decidim::User.new(
46
+ organization: current_organization,
47
+ admin: false,
48
+ managed: true,
49
+ name: Time.current.utc.to_s(:number)
50
+ ) do |u|
51
+ u.nickname = UserBaseEntity.nicknamize(u.name, organization: current_organization)
52
+ u.tos_agreement = true
53
+ u.skip_confirmation!
54
+ end
55
+ end
56
+
57
+ def component
58
+ @component ||= begin
59
+ c = Decidim::Component.find(component_id)
60
+ raise ArgumentError unless c.participatory_space.organization.id == current_organization.id
61
+
62
+ c
63
+ end
64
+ end
65
+
66
+ # Provides the handler that verified the user data to the command
67
+ def verified_handler
68
+ @verified_handler
69
+ end
70
+
71
+ # ----------------------------------------------------------------------
72
+ private
73
+ # ----------------------------------------------------------------------
74
+
75
+ # Check if the data introduced by the user verifies against any handler enabled for the current component.
76
+ def verify_against_enabled_authorization_handlers
77
+ @verified_handler= authorization_handlers.find {|handler| handler.valid? }
78
+
79
+ errors.add(:authorizations, :invalid) unless @verified_handler
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module VerifyWoRegistration
5
+ # Custom helpers, scoped to the verify_wo_registration engine.
6
+ #
7
+ module ApplicationHelper
8
+ def self.verify_wo_registration_custom_modal?(component)
9
+ component.settings.try(:supports_without_registration) && all_verifications_of_type_direct?(component)
10
+ end
11
+
12
+ def self.workflow_manifests(component)
13
+ return [] if component.permissions&.blank? || component.permissions.try(:fetch, "vote").blank?
14
+
15
+ Decidim::Verifications::Adapter.from_collection(
16
+ # component.permissions returns a structure of the form:
17
+ # {"vote"=>{"authorization_handlers"=>{"dummy_authorization_handler"=>{"options"=>{"postal_code"=>"08001"}}}}}
18
+ component.permissions['vote']['authorization_handlers'].keys
19
+ )
20
+ end
21
+
22
+ # Checks whether all workflow manifests for the givevn +component+ are of type "direct".
23
+ def self.all_verifications_of_type_direct?(component)
24
+ manifests = workflow_manifests(component)
25
+ manifests.any? && manifests.all? { |manifest| manifest.type == 'direct' }
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module VerifyWoRegistration
5
+ # Abstract class from which all models in this engine inherit.
6
+ class ApplicationRecord < ActiveRecord::Base
7
+ self.abstract_class = true
8
+ end
9
+ end
10
+ end
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 35 35"><path d="M17.5 35A17.5 17.5 0 1 1 35 17.5 17.52 17.52 0 0 1 17.5 35zm0-33.06A15.56 15.56 0 1 0 33.06 17.5 15.57 15.57 0 0 0 17.5 1.94zm9.5 13.7H8a1 1 0 0 1 0-1.94h19a1 1 0 0 1 0 1.94zm0 3.68H8a1 1 0 0 1 0-1.94h19a1 1 0 0 1 0 1.94zM22.26 23H8a1 1 0 0 1 0-1.94h14.26a1 1 0 0 1 0 1.94z"/></svg>
@@ -0,0 +1,50 @@
1
+ <% if respond_to?(:current_component) && Decidim::VerifyWoRegistration::ApplicationHelper.verify_wo_registration_custom_modal?(current_component) %>
2
+ <%= render 'decidim/shared/verify_wo_registration_login_modal' %>
3
+ <% else %>
4
+ <div class="reveal" id="loginModal" data-reveal>
5
+ <div class="reveal__header">
6
+ <h3 class="reveal__title"><%= t(".please_sign_in") %></h3>
7
+ <button class="close-button" data-close aria-label="Close modal"
8
+ type="button">
9
+ <span aria-hidden="true">&times;</span>
10
+ </button>
11
+ </div>
12
+ <% if current_organization.sign_in_enabled? %>
13
+ <div class="row">
14
+ <div class="columns medium-8 medium-centered">
15
+ <%= decidim_form_for(Decidim::User.new, as: :user, url: session_path(:user), html: { class: "register-form new_user" }) do |f| %>
16
+ <div>
17
+ <div class="field">
18
+ <%= f.email_field :email, autofocus: true %>
19
+ </div>
20
+ <div class="field">
21
+ <%= f.password_field :password, autocomplete: "off" %>
22
+ </div>
23
+ </div>
24
+ <div class="actions">
25
+ <%= f.submit t("devise.sessions.new.sign_in"), class: "button expanded" %>
26
+ </div>
27
+ <% end %>
28
+ <% if current_organization.sign_up_enabled? %>
29
+ <p class="text-center">
30
+ <%= link_to t(".sign_up"), decidim.new_user_registration_path, class: "sign-up-link" %>
31
+ </p>
32
+ <% end %>
33
+ <p class="text-center">
34
+ <%= link_to t("devise.shared.links.forgot_your_password"), new_password_path(:user) %>
35
+ </p>
36
+ </div>
37
+ </div>
38
+ <%= render "decidim/devise/shared/omniauth_buttons_mini" %>
39
+ <% else %>
40
+ <div class="row">
41
+ <div class="columns medium-8 medium-centered">
42
+ <p>
43
+ <%= t("sign_in_disabled", scope: "decidim.devise.sessions.new") %>
44
+ </p>
45
+ </div>
46
+ </div>
47
+ <%= render "decidim/devise/shared/omniauth_buttons" %>
48
+ <% end %>
49
+ </div>
50
+ <% end %>
@@ -0,0 +1,23 @@
1
+ <div class="reveal two_columns" id="loginModal" data-reveal>
2
+ <div class="reveal__header">
3
+ <h3 class="reveal__title"><%= t("verify_wo_registration.login_modal.title") %></h3>
4
+ <button class="close-button" data-close aria-label="Close modal"
5
+ type="button">
6
+ <span aria-hidden="true">&times;</span>
7
+ </button>
8
+ </div>
9
+ <div class="row">
10
+ <div class="columns medium-6">
11
+ <div class="columns medium-centered">
12
+ <h5><%= t("verify_wo_registration.login_modal.col1_title") %></h5>
13
+ <%= render "decidim/shared/verify_wo_registration_login_modal_col1" %>
14
+ </div>
15
+ </div>
16
+ <div class="columns medium-6">
17
+ <div class="columns medium-centered">
18
+ <h5><%= t("verify_wo_registration.login_modal.col2_title") %></h5>
19
+ <%= render "decidim/shared/verify_wo_registration_login_modal_col2" %>
20
+ </div>
21
+ </div>
22
+ </div>
23
+ </div>
@@ -0,0 +1,10 @@
1
+ <div class="columns medium-centered">
2
+ <div class="text-center">
3
+ <%= link_to(t("verify_wo_registration.login_modal.col1_only_verify_btn"),
4
+ Decidim::VerifyWoRegistration::Engine.routes.url_helpers.new_verification_path({
5
+ component_id: current_component.id,
6
+ redirect_url: URI(request.original_fullpath).path,
7
+ votable_gid: "gid"
8
+ }), class: "button expanded") %>
9
+ </div>
10
+ </div>
@@ -0,0 +1,31 @@
1
+ <% if current_organization.sign_in_enabled? %>
2
+ <%= decidim_form_for(Decidim::User.new, as: :user, url: session_path(:user), html: { class: "register-form new_user" }) do |f| %>
3
+ <div>
4
+ <div class="field">
5
+ <%= f.email_field :email, autofocus: true %>
6
+ </div>
7
+ <div class="field">
8
+ <%= f.password_field :password, autocomplete: "off" %>
9
+ </div>
10
+ </div>
11
+ <div class="actions">
12
+ <%= f.submit t("devise.sessions.new.sign_in"), class: "button expanded" %>
13
+ </div>
14
+ <% end %>
15
+ <% if current_organization.sign_up_enabled? %>
16
+ <p class="text-center">
17
+ <%= link_to t("decidim.shared.login_modal.sign_up"), decidim.new_user_registration_path, class: "sign-up-link" %>
18
+ </p>
19
+ <% end %>
20
+ <p class="text-center">
21
+ <%= link_to t("devise.shared.links.forgot_your_password"), new_password_path(:user) %>
22
+ </p>
23
+ <div style="box-sizing: unset">
24
+ <%= render "decidim/devise/shared/omniauth_buttons_mini" %>
25
+ </div>
26
+ <% else %>
27
+ <p style="box-sizing: unset">
28
+ <%= t("sign_in_disabled", scope: "decidim.devise.sessions.new") %>
29
+ </p>
30
+ <%= render "decidim/devise/shared/omniauth_buttons" %>
31
+ <% end %>
@@ -0,0 +1,15 @@
1
+ <% form.object.authorization_handlers.each_with_index do |handler, handler_idx| %>
2
+ <div class="card-section">
3
+ <div class="card__header collapse">
4
+ <h5 class="card__title">
5
+ <%= t("authorize_with", authorizer: t("#{handler.handler_name}.name", scope: "decidim.authorization_handlers"), scope: "decidim.verifications.authorizations.new") %>
6
+ </h5>
7
+ </div>
8
+
9
+ <%= form.fields_for "authorizations[#{handler_idx}]", handler, builder: Decidim::AuthorizationFormBuilder do |handler_form| %>
10
+ <div id="authorization-handler-<%= handler_form.object.handler_name %>" class="authorization-handler">
11
+ <%= render "handler_form", handler_form: handler_form %>
12
+ </div>
13
+ <% end %>
14
+ </div>
15
+ <% end %>
@@ -0,0 +1,7 @@
1
+ <% if lookup_context.exists?(handler_form.object.to_partial_path, [], true) %>
2
+ <%= render partial: handler_form.object.to_partial_path, locals: { handler: handler_form.object, form: handler_form } %>
3
+ <% else %>
4
+ <%= handler_form.all_fields %>
5
+ <% end %>
6
+
7
+ <%= handler_form.error_for(:base) %>
@@ -0,0 +1,27 @@
1
+ <div class="wrapper">
2
+ <div class="row">
3
+ <div class="columns large-6 medium-centered">
4
+ <h2 class="heading2"><%= t("verify_wo_registration.form.title") %></h2>
5
+ <p><%= t("verify_wo_registration.form.description") %></p>
6
+ <%= cell("decidim/announcement", { announcement: t("verify_wo_registration.form.announcement", minutes: ::Decidim::ImpersonationLog::SESSION_TIME_IN_MINUTES), callout_class: "warning" }) %>
7
+ </div>
8
+ </div>
9
+
10
+ <div class="row">
11
+ <div class="columns large-6 medium-centered">
12
+ <%= decidim_form_for(@form, url: verifications_path, html: { class: "form" }) do |form| %>
13
+ <div class="card">
14
+ <div class="card__content">
15
+ <%= render partial: "form", object: form %>
16
+ <%= form.hidden_field :component_id %>
17
+ <%= form.hidden_field :redirect_url %>
18
+ </div>
19
+ </div>
20
+
21
+ <div class="button--double form-general-submit">
22
+ <%= form.submit(t("verify_wo_registration.form.submit_btn")) %>
23
+ </div>
24
+ <% end %>
25
+ </div>
26
+ </div>
27
+ </div>
@@ -0,0 +1,10 @@
1
+ ---
2
+
3
+ base_locale: en
4
+ locales: [en]
5
+
6
+ ignore_unused:
7
+ - "decidim.components.verify_wo_registration.name"
8
+
9
+ ignore_missing:
10
+ - decidim.participatory_processes.scopes.global
@@ -0,0 +1,26 @@
1
+ ---
2
+ ca:
3
+ decidim:
4
+ components:
5
+ budgets:
6
+ settings:
7
+ global:
8
+ supports_without_registration: Poder donar suports sense registre (només verificant-se)
9
+ proposals:
10
+ settings:
11
+ global:
12
+ supports_without_registration: Poder donar suports sense registre (només verificant-se)
13
+ verify_wo_registration:
14
+ login_modal:
15
+ title: Per tal de poder participar cal que et verifiquis. Com et vols verificar?
16
+ col1_only_verify_btn: Verifica't sense registre
17
+ col2_title: Ja tinc un compte. Inicia la sessió i verifica't
18
+ col1_title: No tinc compte i no em vull registar
19
+ form:
20
+ announcement: La sessió expirarà en %{minutes} minuts
21
+ description: Per tal de poder participal cal que verifiquis les teves credencials a través del següent formulari
22
+ submit_btn: Verifica
23
+ title: Verificació del/la participant
24
+ create:
25
+ success: T'has verificat correctament. Ara tens %{minutes}min per participar.
26
+ use_registered_user: Ja existeix un usuari verficat amb les mateixes dades. Cal que utilitzis l'usuari ja existent per participar.
@@ -0,0 +1,26 @@
1
+ ---
2
+ en:
3
+ decidim:
4
+ components:
5
+ budgets:
6
+ settings:
7
+ global:
8
+ supports_without_registration: Enable supports without registration (user only verifies)
9
+ proposals:
10
+ settings:
11
+ global:
12
+ supports_without_registration: Enable supports without registration (user only verifies)
13
+ verify_wo_registration:
14
+ login_modal:
15
+ title: To participate you must be verified. How do you want to verify?
16
+ col1_only_verify_btn: Verify without signup
17
+ col2_title: I already have an account. Login to verify yourself
18
+ col1_title: I don't have account and I don't want to signup
19
+ form:
20
+ announcement: The session will expire in %{minutes} minutes
21
+ description: You must verify your credentials through the following form in order to be able to participate
22
+ submit_btn: Verify
23
+ title: Participant verification
24
+ create:
25
+ success: You have been successfully verified. You have %{minutes}min to participate.
26
+ use_registered_user: There's already an existing user with your provided verification. You must use the existing user to participate.
@@ -0,0 +1,26 @@
1
+ ---
2
+ es:
3
+ decidim:
4
+ components:
5
+ budgets:
6
+ settings:
7
+ global:
8
+ supports_without_registration: Poder dar soportes sin registrarse (sólo verificandose)
9
+ proposals:
10
+ settings:
11
+ global:
12
+ supports_without_registration: Poder dar soportes sin registrarse (sólo verificandose)
13
+ verify_wo_registration:
14
+ login_modal:
15
+ title: Por tal de poder participar hace falta que te verifiques. ¿Cómo te quieres verificar?
16
+ col1_only_verify_btn: Verifícate sin registro
17
+ col2_title: Ya tengo una cuenta. Inicia la sesión y verifícate
18
+ col1_title: No tengo cuenta y no me quiero registrar
19
+ form:
20
+ announcement: La sessióm expirará en %{minutes} minutos
21
+ description: Por tal de poder participal hace falta que verifiques tus credenciales a través del siguiente formulario
22
+ submit_btn: Verificate
23
+ title: Verificación del/la participante
24
+ create:
25
+ success: Te has verificado correctamente. Tienes %{minutes}min para participar.
26
+ use_registered_user: Ya existe un usuario verficado con los mismos datos. Utiliza el usuario ya existente para participar.
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module VerifyWoRegistration
5
+ # This module contains all the domain logic associated to Decidim's VerifyWoRegistration
6
+ # component admin panel.
7
+ module Admin
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module VerifyWoRegistration
5
+ # This is the engine that runs on the public interface of `VerifyWoRegistration`.
6
+ class AdminEngine < ::Rails::Engine
7
+ isolate_namespace Decidim::VerifyWoRegistration::Admin
8
+
9
+ paths['db/migrate'] = nil
10
+ paths['lib/tasks'] = nil
11
+
12
+ routes do
13
+ # Add admin engine routes here
14
+ # resources :verify_wo_registration do
15
+ # collection do
16
+ # resources :exports, only: [:create]
17
+ # end
18
+ # end
19
+ # root to: "verify_wo_registration#index"
20
+ end
21
+
22
+ def load_seed
23
+ nil
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+ # This file is located at `config/assets.rb` of your module.
3
+
4
+ # Define the base path of your module. Please note that `Rails.root` may not be
5
+ # used because we are not inside the Rails environment when this file is loaded.
6
+ base_path = File.expand_path("..", __dir__)
7
+
8
+ # Register an additional load path for webpack. All the assets within these
9
+ # directories will be available for inclusion within the Decidim assets. For
10
+ # example, if you have `app/packs/src/decidim/foo.js`, you can include that file
11
+ # in your JavaScript entrypoints (or other JavaScript files within Decidim)
12
+ # using `import "src/decidim/foo"` after you have registered the additional path
13
+ # as follows.
14
+ Decidim::Webpacker.register_path("#{base_path}/app/packs")
15
+
16
+ # Register the entrypoints for your module. These entrypoints can be included
17
+ # within your application using `javascript_pack_tag` and if you include any
18
+ # SCSS files within the entrypoints, they become available for inclusion using
19
+ # `stylesheet_pack_tag`.
20
+ #Decidim::Webpacker.register_entrypoints(
21
+ # decidim_foo: "#{base_path}/app/packs/entrypoints/decidim_foo.js",
22
+ # decidim_foo_admin: "#{base_path}/app/packs/entrypoints/decidim_foo_admin.js"
23
+ #)
24
+
25
+ # If you want to import some extra SCSS files in the Decidim main SCSS file
26
+ # without adding any extra stylesheet inclusion tags, you can use the following
27
+ # method to register the stylesheet import for the main application.
28
+ #Decidim::Webpacker.register_stylesheet_import("stylesheets/decidim/verify_wo_registration/engine")
29
+
30
+ # If you want to do the same but include the SCSS file for the admin panel's
31
+ # main SCSS file, you can use the following method.
32
+ #Decidim::Webpacker.register_stylesheet_import("stylesheets/decidim/verify_wo_registration/admin_engine", group: :admin)
33
+
34
+ # If you want to override some SCSS variables/settings for Foundation from the
35
+ # module, you can add the following registered import.
36
+ #Decidim::Webpacker.register_stylesheet_import("stylesheets/decidim/foo/settings", type: :settings)
37
+
38
+ # If you want to do the same but override the SCSS variables of the admin
39
+ # panel's styles, you can use the following method.
40
+ #Decidim::Webpacker.register_stylesheet_import("stylesheets/decidim/foo/admin_settings", type: :settings, group: :admin)
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails'
4
+ require 'decidim/core'
5
+
6
+ module Decidim
7
+ module VerifyWoRegistration
8
+ # This is the engine that runs on the public interface of verify_wo_registration.
9
+ class Engine < ::Rails::Engine
10
+ isolate_namespace Decidim::VerifyWoRegistration
11
+
12
+ routes do
13
+ # Add engine routes here
14
+ resources :verifications, only: %i[new create]
15
+ # root to: "verify_wo_registration#index"
16
+ end
17
+
18
+ initializer 'verify_wo_registration.mount_routes' do |_app|
19
+ Decidim::Core::Engine.routes do
20
+ mount Decidim::VerifyWoRegistration::Engine => '/verify_wo_registration'
21
+ end
22
+ end
23
+
24
+ initializer "decidim_verify_wo_registration.webpacker.assets_path" do
25
+ Decidim.register_assets_path File.expand_path("app/packs", root)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Extends
4
+ # - the Decidim::Proposals component.
5
+ # - the Decidim::Budgets component.
6
+
7
+ def add_attribute_to_global_settings(component, attr_name, type, default = false)
8
+ component.settings(:global).attribute(attr_name.to_sym, type: type, default: default)
9
+ end
10
+
11
+ component = Decidim.find_component_manifest :proposals
12
+ add_attribute_to_global_settings(component, :supports_without_registration, :boolean, false)
13
+
14
+ component = Decidim.find_component_manifest :budgets
15
+ add_attribute_to_global_settings(component, :supports_without_registration, :boolean, false)
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'decidim/core/test/factories'
4
+
5
+ FactoryBot.define do
6
+ factory :verify_wo_registration_component, parent: :component do
7
+ name { Decidim::Components::Namer.new(participatory_space.organization.available_locales, :verify_wo_registration).i18n_name }
8
+ manifest_name { :verify_wo_registration }
9
+ participatory_space { create(:participatory_process, :with_steps) }
10
+ end
11
+
12
+ # Add engine factories here
13
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ # This holds the decidim-meetings version.
5
+ module VerifyWoRegistration
6
+ VERSION = '0.1.0'
7
+ DECIDIM_VER = '>= 0.27'
8
+
9
+ def self.version
10
+ VERSION
11
+ end
12
+
13
+ def self.decidim_version
14
+ DECIDIM_VER
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'decidim/verify_wo_registration/admin'
4
+ require 'decidim/verify_wo_registration/engine'
5
+ require 'decidim/verify_wo_registration/admin_engine'
6
+ require 'decidim/verify_wo_registration/extend_components'
7
+
8
+ module Decidim
9
+ # This namespace holds the logic of the `VerifyWoRegistration` component. This component
10
+ # allows users to create verify_wo_registration in a participatory space.
11
+ module VerifyWoRegistration
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,160 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: decidim-verify_wo_registration
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Oliver Valls
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-06-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: decidim-budgets
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0.27'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0.27'
27
+ - !ruby/object:Gem::Dependency
28
+ name: decidim-core
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0.27'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0.27'
41
+ - !ruby/object:Gem::Dependency
42
+ name: decidim-proposals
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0.27'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0.27'
55
+ - !ruby/object:Gem::Dependency
56
+ name: decidim
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0.27'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0.27'
69
+ - !ruby/object:Gem::Dependency
70
+ name: decidim-dev
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0.27'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0.27'
83
+ - !ruby/object:Gem::Dependency
84
+ name: decidim-participatory_processes
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0.27'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0.27'
97
+ description: Adds the hability for proposals and budgets components to allow users
98
+ to give support without being registered. Enabling this feature the user is requested
99
+ for verification and then, on success, logged in in a 30min session..
100
+ email:
101
+ - oliver.vh@coditramuntana.com
102
+ executables: []
103
+ extensions: []
104
+ extra_rdoc_files: []
105
+ files:
106
+ - LICENSE-MIT.txt
107
+ - README.md
108
+ - Rakefile
109
+ - app/commands/decidim/verify_wo_registration/do_verify_wo_registration.rb
110
+ - app/controllers/decidim/verify_wo_registration/admin/application_controller.rb
111
+ - app/controllers/decidim/verify_wo_registration/application_controller.rb
112
+ - app/controllers/decidim/verify_wo_registration/verifications_controller.rb
113
+ - app/forms/decidim/verify_wo_registration/verify_wo_registration_form.rb
114
+ - app/helpers/decidim/verify_wo_registration/application_helper.rb
115
+ - app/models/decidim/verify_wo_registration/application_record.rb
116
+ - app/packs/images/decidim/verify_wo_registration/icon.svg
117
+ - app/views/decidim/shared/_login_modal.html.erb
118
+ - app/views/decidim/shared/_verify_wo_registration_login_modal.html.erb
119
+ - app/views/decidim/shared/_verify_wo_registration_login_modal_col1.html.erb
120
+ - app/views/decidim/shared/_verify_wo_registration_login_modal_col2.html.erb
121
+ - app/views/decidim/verify_wo_registration/verifications/_form.html.erb
122
+ - app/views/decidim/verify_wo_registration/verifications/_handler_form.html.erb
123
+ - app/views/decidim/verify_wo_registration/verifications/new.html.erb
124
+ - config/i18n-tasks.yml
125
+ - config/locales/ca.yml
126
+ - config/locales/en.yml
127
+ - config/locales/es.yml
128
+ - lib/decidim/verify_wo_registration.rb
129
+ - lib/decidim/verify_wo_registration/admin.rb
130
+ - lib/decidim/verify_wo_registration/admin_engine.rb
131
+ - lib/decidim/verify_wo_registration/config/assets.rb
132
+ - lib/decidim/verify_wo_registration/engine.rb
133
+ - lib/decidim/verify_wo_registration/extend_components.rb
134
+ - lib/decidim/verify_wo_registration/test/factories.rb
135
+ - lib/decidim/verify_wo_registration/version.rb
136
+ homepage: https://github.com/CodiTramuntana/decidim-verify_wo_registration
137
+ licenses:
138
+ - MIT
139
+ metadata: {}
140
+ post_install_message:
141
+ rdoc_options: []
142
+ require_paths:
143
+ - lib
144
+ required_ruby_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ version: 3.0.2
149
+ required_rubygems_version: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ requirements: []
155
+ rubygems_version: 3.2.22
156
+ signing_key:
157
+ specification_version: 4
158
+ summary: Adds the hability for proposals and budgets components to allow users to
159
+ give support without being registered.
160
+ test_files: []