decidim-access_requests 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE-AGPLv3.txt +661 -0
  3. data/README.md +105 -0
  4. data/Rakefile +17 -0
  5. data/app/assets/config/decidim_access_requests_manifest.css +3 -0
  6. data/app/assets/stylesheets/decidim/access_requests/verification.scss +4 -0
  7. data/app/assets/stylesheets/decidim/access_requests/verification/_step-bullets.scss +30 -0
  8. data/app/assets/stylesheets/decidim/access_requests/verification/_variables.scss +2 -0
  9. data/app/commands/decidim/access_requests/verification/admin/confirm_user_access_request.rb +67 -0
  10. data/app/commands/decidim/access_requests/verification/admin/destroy_authorization.rb +40 -0
  11. data/app/controllers/concerns/decidim/access_requests/verification/detectable_verification_manifest.rb +23 -0
  12. data/app/controllers/decidim/access_requests/verification/admin/granted_authorizations_controller.rb +117 -0
  13. data/app/controllers/decidim/access_requests/verification/admin/pending_authorizations_controller.rb +76 -0
  14. data/app/controllers/decidim/access_requests/verification/authorizations_controller.rb +68 -0
  15. data/app/events/decidim/access_requests/access_request_confirmed_event.rb +31 -0
  16. data/app/forms/decidim/access_requests/verification/request_form.rb +25 -0
  17. data/app/presenters/decidim/access_requests/verification/authorization_presenter.rb +16 -0
  18. data/app/views/decidim/access_requests/verification/admin/granted_authorizations/index.html.erb +44 -0
  19. data/app/views/decidim/access_requests/verification/admin/granted_authorizations/new.html.erb +52 -0
  20. data/app/views/decidim/access_requests/verification/admin/pending_authorizations/index.html.erb +48 -0
  21. data/app/views/decidim/access_requests/verification/authorizations/_steps.html.erb +40 -0
  22. data/app/views/decidim/access_requests/verification/authorizations/edit.html.erb +13 -0
  23. data/app/views/decidim/access_requests/verification/authorizations/new.html.erb +25 -0
  24. data/config/locales/en.yml +70 -0
  25. data/config/locales/fi.yml +68 -0
  26. data/config/locales/sv.yml +70 -0
  27. data/lib/decidim/access_requests.rb +9 -0
  28. data/lib/decidim/access_requests/verification.rb +5 -0
  29. data/lib/decidim/access_requests/verification/admin.rb +12 -0
  30. data/lib/decidim/access_requests/verification/admin_engine.rb +21 -0
  31. data/lib/decidim/access_requests/verification/engine.rb +24 -0
  32. data/lib/decidim/access_requests/version.rb +8 -0
  33. metadata +132 -0
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module AccessRequests
5
+ module Verification
6
+ class AuthorizationsController < Decidim::ApplicationController
7
+ helper_method :authorization
8
+
9
+ before_action :load_authorization
10
+
11
+ def new
12
+ enforce_permission_to :create, :authorization, authorization: @authorization
13
+
14
+ @form = RequestForm.new(handler_handle: authorization_handle)
15
+ end
16
+
17
+ def create
18
+ enforce_permission_to :create, :authorization, authorization: @authorization
19
+
20
+ @form = RequestForm.from_params(
21
+ params.merge(user: current_user)
22
+ ).with_context(current_organization: current_organization)
23
+
24
+ Decidim::Verifications::PerformAuthorizationStep.call(@authorization, @form) do
25
+ on(:ok) do
26
+ flash[:notice] = t("authorizations.create.success", scope: "decidim.access_requests.verification")
27
+ redirect_to decidim_verifications.authorizations_path
28
+ end
29
+
30
+ on(:invalid) do
31
+ flash.now[:alert] = t("authorizations.create.error", scope: "decidim.access_requests.verification")
32
+ render :new
33
+ end
34
+ end
35
+ end
36
+
37
+ def edit
38
+ enforce_permission_to :create, :authorization, authorization: @authorization
39
+ end
40
+
41
+ private
42
+
43
+ # rubocop:disable Naming/MemoizedInstanceVariableName
44
+ def authorization
45
+ @authorization_presenter ||= AuthorizationPresenter.new(@authorization)
46
+ end
47
+ # rubocop:enable Naming/MemoizedInstanceVariableName
48
+
49
+ def load_authorization
50
+ @authorization = Decidim::Authorization.find_or_initialize_by(
51
+ user: current_user,
52
+ name: authorization_handle
53
+ )
54
+ end
55
+
56
+ def authorization_handle
57
+ # In case the form is posted, the authorization handle is not
58
+ # available from the request path.
59
+ tmpform = RequestForm.from_params(params)
60
+ return tmpform.handler_name unless tmpform.handler_name.nil?
61
+
62
+ # Determine the handle from the request path
63
+ request.path.split("/").last
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,31 @@
1
+ # frozen-string_literal: true
2
+
3
+ module Decidim
4
+ module AccessRequests
5
+ class AccessRequestConfirmedEvent < Decidim::Events::SimpleEvent
6
+ delegate :url_helpers, to: "Decidim::Core::Engine.routes"
7
+
8
+ i18n_attributes :verification_name
9
+
10
+ def resource_url
11
+ url_helpers.profile_url(
12
+ user_nickname,
13
+ host: user.organization.host
14
+ )
15
+ end
16
+
17
+ def resource_path
18
+ url_helpers.profile_path(user_nickname)
19
+ end
20
+
21
+ def verification_name
22
+ handler_name = extra.dig("handler_name")
23
+ I18n.t("#{handler_name}.name", scope: "decidim.authorization_handlers")
24
+ end
25
+
26
+ def user_nickname
27
+ extra.dig("user_nickname")
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module AccessRequests
5
+ module Verification
6
+ # A form object to be used when public users want to get verified by
7
+ # access requests.
8
+ class RequestForm < AuthorizationHandler
9
+ attribute :handler_handle, String
10
+
11
+ validates :handler_handle,
12
+ presence: true,
13
+ inclusion: {
14
+ in: proc { |form|
15
+ form.current_organization.available_authorizations
16
+ }
17
+ }
18
+
19
+ def handler_name
20
+ handler_handle
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module AccessRequests
5
+ module Verification
6
+ #
7
+ # Decorator for access request authorizations.
8
+ #
9
+ class AuthorizationPresenter < SimpleDelegator
10
+ def self.for_collection(authorizations)
11
+ authorizations.map { |authorization| new(authorization) }
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,44 @@
1
+ <div class="card">
2
+ <div class="card-divider">
3
+ <h2 class="card-title">
4
+ <%= t(".title") %>
5
+ <%= link_to t(".pending_authorizations"), pending_authorizations_path, class: "button tiny button--title" %>
6
+ <%= link_to t(".new"), new_granted_authorization_path, class: "button tiny button--title" %>
7
+ </h2>
8
+ </div>
9
+ <div class="card-section">
10
+ <table class="table-list">
11
+ <thead>
12
+ <tr>
13
+ <th><%= t(".name") %></th>
14
+ <th><%= t(".nickname") %></th>
15
+ <th></th>
16
+ </tr>
17
+ </thead>
18
+ <tbody>
19
+ <% @granted_authorizations.each do |authorization| %>
20
+ <tr>
21
+ <td>
22
+ <%= authorization.user.name %>
23
+ </td>
24
+ <td>
25
+ <%= authorization.user.nickname %>
26
+ </td>
27
+ <td class="table-list__actions">
28
+ <%= icon_link_to "person",
29
+ decidim.profile_path(authorization.user.nickname),
30
+ t("layouts.decidim.user_profile.account"),
31
+ class:"action-icon--show",
32
+ target: "_blank" %>
33
+ <%= icon_link_to "circle-x",
34
+ granted_authorization_path(authorization.id),
35
+ t(".remove_access"),
36
+ method: :delete,
37
+ class: "action-icon--delete" %>
38
+ </td>
39
+ </tr>
40
+ <% end %>
41
+ </tbody>
42
+ </table>
43
+ </div>
44
+ </div>
@@ -0,0 +1,52 @@
1
+ <div class="filters row">
2
+ <div class="column medium-4">
3
+ <%= form_tag "", method: :get do %>
4
+ <div class="filters__search">
5
+ <div class="input-group">
6
+ <%= search_field_tag :q, @query,label: false, class: "input-group-field", placeholder: t(".search") %>
7
+ <%= hidden_field_tag :state, @state %>
8
+ <div class="input-group-button">
9
+ <button type="submit" class="button button--muted">
10
+ <%= icon "magnifying-glass", aria_label: t(".search") %>
11
+ </button>
12
+ </div>
13
+ </div>
14
+ </div>
15
+ <% end %>
16
+ </div>
17
+ </div>
18
+
19
+ <div class="card" id='user-groups'>
20
+ <div class="card-divider">
21
+ <h2 class="card-title"><%= t ".users" %></h2>
22
+ </div>
23
+ <div class="card-section">
24
+ <div class="table-scroll">
25
+ <table class="table-list">
26
+ <thead>
27
+ <tr>
28
+ <th><%= t(".name") %></th>
29
+ <th><%= t(".nickname") %></th>
30
+ <th><%= t(".created_at") %></th>
31
+ <th><%= t(".actions") %></th>
32
+ </tr>
33
+ </thead>
34
+ <tbody>
35
+ <% @users.each do |user| %>
36
+ <tr data-user-id="<%= user.id %>">
37
+ <td><%= link_to user.name, decidim.profile_path(user.nickname) %></td>
38
+ <td><%= link_to user.nickname, decidim.profile_path(user.nickname) %></td>
39
+ <td><%= l user.created_at, format: :short %></td>
40
+
41
+ <td class="table-list__actions">
42
+ <%= icon_link_to "envelope-closed", current_or_new_conversation_path_with(user), t("decidim.contact"), class:"action-icon--new" %>
43
+ <%= icon_link_to "circle-check", granted_authorizations_path(user_id: user.id), t(".grant_access"), class: "action-icon--verify", method: :post %>
44
+ </td>
45
+ </tr>
46
+ <% end %>
47
+ </tbody>
48
+ </table>
49
+ <%= paginate @users, theme: "decidim" %>
50
+ </div>
51
+ </div>
52
+ </div>
@@ -0,0 +1,48 @@
1
+ <div class="card">
2
+ <div class="card-divider">
3
+ <h2 class="card-title">
4
+ <%= t(".title") %>
5
+ <%= link_to t(".granted_authorizations"), granted_authorizations_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(".name") %></th>
13
+ <th><%= t(".nickname") %></th>
14
+ <th></th>
15
+ </tr>
16
+ </thead>
17
+ <tbody>
18
+ <% @pending_authorizations.each do |authorization| %>
19
+ <tr>
20
+ <td>
21
+ <%= authorization.user.name %>
22
+ </td>
23
+ <td>
24
+ <%= authorization.user.nickname %>
25
+ </td>
26
+ <td class="table-list__actions">
27
+ <%= icon_link_to "person",
28
+ decidim.profile_path(authorization.user.nickname),
29
+ t("layouts.decidim.user_profile.account"),
30
+ class:"action-icon--show",
31
+ target: "_blank" %>
32
+ <%= icon_link_to "circle-check",
33
+ pending_authorization_path(authorization.id),
34
+ t(".approve_request"),
35
+ method: :patch,
36
+ class: "action-icon--verify" %>
37
+ <%= icon_link_to "circle-x",
38
+ pending_authorization_path(authorization.id),
39
+ t(".reject_request"),
40
+ method: :delete,
41
+ class: "action-icon--reject" %>
42
+ </td>
43
+ </tr>
44
+ <% end %>
45
+ </tbody>
46
+ </table>
47
+ </div>
48
+ </div>
@@ -0,0 +1,40 @@
1
+ <%
2
+ active ||= []
3
+ steps = [
4
+ {
5
+ icon: "envelope-closed",
6
+ title: t(".step1.title"),
7
+ description: t(".step1.description")
8
+ },
9
+ {
10
+ icon: "check",
11
+ title: t(".step2.title"),
12
+ description: t(".step2.description")
13
+ },
14
+ {
15
+ icon: "bell",
16
+ title: t(".step3.title"),
17
+ description: t(".step3.description")
18
+ }
19
+ ]
20
+ %>
21
+
22
+ <div class="row small-up-1 medium-up-3 step-bullets">
23
+ <% steps.each_with_index do |step, i| %>
24
+ <%
25
+ cls = "step-bullet text-center"
26
+ cls << " completed" if active.include?(i)
27
+ %>
28
+ <div class="column">
29
+ <div class="<%= cls %>">
30
+ <div class="step-bullet__icon">
31
+ <%= icon step[:icon] %>
32
+ </div>
33
+ <div class="step-bullet__desc">
34
+ <h4 class="heading6"><%= step[:title] %></h4>
35
+ <p><%= step[:description] %></p>
36
+ </div>
37
+ </div>
38
+ </div>
39
+ <% end %>
40
+ </div>
@@ -0,0 +1,13 @@
1
+ <div class="wrapper">
2
+ <div class="row collapse">
3
+ <div class="row collapse">
4
+ <div class="columns large-8 large-centered text-center page-title">
5
+ <h1><%= t(".title") %></h1>
6
+ </div>
7
+ </div>
8
+
9
+ <%= render "steps", active: [0, 1] %>
10
+ </div>
11
+ </div>
12
+
13
+ <%= stylesheet_link_tag "decidim/access_requests/verification" %>
@@ -0,0 +1,25 @@
1
+ <div class="wrapper">
2
+ <div class="row collapse">
3
+ <div class="row collapse">
4
+ <div class="columns large-8 large-centered text-center page-title">
5
+ <h1><%= t(".title") %></h1>
6
+ </div>
7
+ </div>
8
+
9
+ <%= render "steps", active: [0] %>
10
+
11
+ <div class="row">
12
+ <div class="columns large-6 medium-centered">
13
+ <%= decidim_form_for(@form, url: authorization_path) do |form| %>
14
+ <%= form.hidden_field :handler_handle %>
15
+
16
+ <div class="actions">
17
+ <%= form.submit t(".send"), class: "button expanded", "data-disable-with" => "#{t('.send')}..." %>
18
+ </div>
19
+ <% end %>
20
+ </div>
21
+ </div>
22
+ </div>
23
+ </div>
24
+
25
+ <%= stylesheet_link_tag "decidim/access_requests/verification" %>
@@ -0,0 +1,70 @@
1
+ en:
2
+ activemodel:
3
+ models:
4
+ decidim/access_requests/access_request_confirmed_event: Access request confirmed
5
+ decidim:
6
+ access_requests:
7
+ verification:
8
+ admin:
9
+ granted_authorizations:
10
+ destroy:
11
+ error: There was an error deleting the verification.
12
+ success: Verification was deleted successfully.
13
+ index:
14
+ name: Name
15
+ new: New
16
+ nickname: Nickname
17
+ pending_authorizations: Pending requests
18
+ remove_access: Remove access
19
+ title: Granted requests
20
+ username: Username
21
+ new:
22
+ actions: Actions
23
+ created_at: Created at
24
+ grant_access: Grant access
25
+ name: Name
26
+ nickname: Nickname
27
+ search: Search
28
+ users: Users
29
+ pending_authorizations:
30
+ destroy:
31
+ error: There was an error rejecting the access request.
32
+ success: Access request was rejected successfully.
33
+ index:
34
+ approve_request: Grant access
35
+ granted_authorizations: Granted requests
36
+ name: Name
37
+ nickname: Nickname
38
+ reject_request: Reject access
39
+ title: Pending requests
40
+ update:
41
+ error: There was an error verifying access for the user.
42
+ success: Access successfully granted for the user.
43
+ authorizations:
44
+ create:
45
+ error: There was an error creating the access request.
46
+ success: Access request successfully created.
47
+ edit:
48
+ title: Your request is pending
49
+ new:
50
+ title: Request access
51
+ send: Send request
52
+ steps:
53
+ step1:
54
+ title: Step 1
55
+ description: Send access request.
56
+ step2:
57
+ title: Step 2
58
+ description: Wait for review of the request.
59
+ step3:
60
+ title: Step 3
61
+ description: >
62
+ You will get notified once the request review has been
63
+ completed.
64
+ events:
65
+ access_requests:
66
+ confirmed:
67
+ email_intro: Congratulations! You have been granted access to %{verification_name}.
68
+ email_outro: You have received this notification because your access request has been approved.
69
+ email_subject: You have been granted access to %{verification_name}!
70
+ notification_title: You have been granted access to %{verification_name}.