decidim-access_requests 0.15.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.
- checksums.yaml +7 -0
- data/LICENSE-AGPLv3.txt +661 -0
- data/README.md +105 -0
- data/Rakefile +17 -0
- data/app/assets/config/decidim_access_requests_manifest.css +3 -0
- data/app/assets/stylesheets/decidim/access_requests/verification.scss +4 -0
- data/app/assets/stylesheets/decidim/access_requests/verification/_step-bullets.scss +30 -0
- data/app/assets/stylesheets/decidim/access_requests/verification/_variables.scss +2 -0
- data/app/commands/decidim/access_requests/verification/admin/confirm_user_access_request.rb +67 -0
- data/app/commands/decidim/access_requests/verification/admin/destroy_authorization.rb +40 -0
- data/app/controllers/concerns/decidim/access_requests/verification/detectable_verification_manifest.rb +23 -0
- data/app/controllers/decidim/access_requests/verification/admin/granted_authorizations_controller.rb +117 -0
- data/app/controllers/decidim/access_requests/verification/admin/pending_authorizations_controller.rb +76 -0
- data/app/controllers/decidim/access_requests/verification/authorizations_controller.rb +68 -0
- data/app/events/decidim/access_requests/access_request_confirmed_event.rb +31 -0
- data/app/forms/decidim/access_requests/verification/request_form.rb +25 -0
- data/app/presenters/decidim/access_requests/verification/authorization_presenter.rb +16 -0
- data/app/views/decidim/access_requests/verification/admin/granted_authorizations/index.html.erb +44 -0
- data/app/views/decidim/access_requests/verification/admin/granted_authorizations/new.html.erb +52 -0
- data/app/views/decidim/access_requests/verification/admin/pending_authorizations/index.html.erb +48 -0
- data/app/views/decidim/access_requests/verification/authorizations/_steps.html.erb +40 -0
- data/app/views/decidim/access_requests/verification/authorizations/edit.html.erb +13 -0
- data/app/views/decidim/access_requests/verification/authorizations/new.html.erb +25 -0
- data/config/locales/en.yml +70 -0
- data/config/locales/fi.yml +68 -0
- data/config/locales/sv.yml +70 -0
- data/lib/decidim/access_requests.rb +9 -0
- data/lib/decidim/access_requests/verification.rb +5 -0
- data/lib/decidim/access_requests/verification/admin.rb +12 -0
- data/lib/decidim/access_requests/verification/admin_engine.rb +21 -0
- data/lib/decidim/access_requests/verification/engine.rb +24 -0
- data/lib/decidim/access_requests/version.rb +8 -0
- 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
|
data/app/views/decidim/access_requests/verification/admin/granted_authorizations/index.html.erb
ADDED
@@ -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>
|
data/app/views/decidim/access_requests/verification/admin/pending_authorizations/index.html.erb
ADDED
@@ -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}.
|