As a customer, I’m not likely to visit the `Users` page to create a personal access token. Let’s make it easier to find by moving it to its own page and adding it to the sidebar.
193 lines
9 KiB
Text
193 lines
9 KiB
Text
<% if @token
|
|
page_header = "Token #{@token.ubid}"
|
|
ace_options = [
|
|
["aces[][action]", @action_options.to_h { |k, v| [k, k ? v.map { [_1.ubid, _1.name] }.sort_by! { _2 } : v] }],
|
|
["aces[][object]", @object_options.to_h { |k, v| [k, k ? v.map { [_1.ubid, _1.name] } : v] }]
|
|
]
|
|
form_action = "#{@project_data[:path]}/token/#{@token.ubid}/access-control"
|
|
table_headers = %w[Action Object]
|
|
edit_perm = true
|
|
|
|
unrestricted = @token.unrestricted_token_for_project?(@project.id)
|
|
restriction_title, restriction_path =
|
|
if unrestricted
|
|
["Restrict", "#{@project_data[:path]}/token/#{@token.ubid}/restrict-access"]
|
|
else
|
|
["Unrestrict", "#{@project_data[:path]}/token/#{@token.ubid}/unrestrict-access"]
|
|
end
|
|
else
|
|
page_header = "Access Control"
|
|
ace_options = [
|
|
["aces[][subject]", @subject_options.to_h { |k, v| [k, k ? v.map { [_1.ubid, _1.name] } : v] }],
|
|
["aces[][action]", @action_options.to_h { |k, v| [k, k ? v.map { [_1.ubid, _1.name] }.sort_by! { _2 } : v] }],
|
|
["aces[][object]", @object_options.to_h { |k, v| [k, k ? v.map { [_1.ubid, _1.name] } : v] }]
|
|
]
|
|
form_action = "#{@project_data[:path]}/user/access-control"
|
|
table_headers = %w[Subject Action Object]
|
|
edit_perm = has_project_permission("Project:editaccess")
|
|
end
|
|
@page_title = "#{@project_data[:name]} - #{page_header}" %>
|
|
|
|
<%== render("project/user-tabbar") unless @token %>
|
|
|
|
<div class="space-y-1">
|
|
<%== render(
|
|
"components/page_header",
|
|
locals: {
|
|
title: page_header,
|
|
breadcrumbs: [%w[Projects /project], [@project_data[:name], @project_data[:path]], [page_header, "#"]]
|
|
}
|
|
) %>
|
|
</div>
|
|
|
|
<div class="grid gap-6">
|
|
<% unless unrestricted %>
|
|
<% if @token.nil? && edit_perm %>
|
|
<div class="md:flex md:items-center md:justify-between">
|
|
<div class="min-w-0 flex-1">
|
|
Access is allowed if there is an access control entry allowing the subject to take the action on the object.
|
|
Subjects, actions, and objects can all be tags, which are used for grouping. The recommended way to handle
|
|
access control in Ubicloud is to create appropriate tags, add the subjects, actions, and objects to the tags,
|
|
and create the minimum number of access control entries you need to enforce the access you want. However, you
|
|
can create access control entries referencing specific subjects, actions, or objects.
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
|
|
<form id="access-control-form" action="<%= form_action %>" role="form" method="POST">
|
|
<%== csrf_tag(form_action) %>
|
|
<div class="overflow-hidden rounded-lg shadow ring-1 ring-black ring-opacity-5 bg-white divide-y divide-gray-200">
|
|
<table id="access-control-entries" class="min-w-full divide-y divide-gray-300 group">
|
|
<thead class="bg-gray-50 <% if @token %> hidden group-[&:has(tr:nth-child(n+3))]:table-header-group <% end %>">
|
|
<tr>
|
|
<% table_headers.each do |type| %>
|
|
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
|
<%= type %>
|
|
<% unless @token %>
|
|
<a
|
|
id="<%= type.downcase %>-tags-link"
|
|
href="<%= "#{@project_data[:path]}/user/access-control/tag/#{type.downcase}" %>"
|
|
class="text-orange-600 hover:text-orange-700 text-xs"
|
|
>
|
|
(Tags)
|
|
</a>
|
|
<% end %>
|
|
</th>
|
|
<% end %>
|
|
<% if edit_perm %>
|
|
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900"></th>
|
|
<% end %>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y divide-gray-200 bg-white">
|
|
<% @aces.append(["template", [], true]).each do |ubid, tags, editable| %>
|
|
<% editable &&= edit_perm %>
|
|
<tr id="ace-<%= ubid %>" class="<%= "existing-aces#{"-view" unless editable}" unless ubid == "template" %>">
|
|
<% if editable %>
|
|
<% ace_options.each_with_index do | (name, options), index| %>
|
|
<% attributes = (!@token && index == 0 && ubid != "template") ? { required: "required" } : {} %>
|
|
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
|
|
<%== render(
|
|
"components/form/select",
|
|
locals: {
|
|
id: "ace-#{ubid}-#{index}",
|
|
name:,
|
|
selected: tags[index]&.ubid,
|
|
options:,
|
|
classes: table_headers[index].downcase,
|
|
attributes:
|
|
}
|
|
) %>
|
|
</td>
|
|
<% end %>
|
|
<td class="py-4 px-3 text-right">
|
|
<%== render("components/form/hidden", locals: { name: "aces[][ubid]", value: ubid }) %>
|
|
<%== render(
|
|
"components/form/checkbox",
|
|
locals: {
|
|
id_prefix: "ace-#{ubid}-",
|
|
name: "aces[][deleted]",
|
|
options: [%w[true Delete]]
|
|
}
|
|
) %>
|
|
</td>
|
|
<% else %>
|
|
<% tags.each do |tag| %>
|
|
<td class="values whitespace-nowrap px-3 py-4 text-sm text-gray-500">
|
|
<%= ace_label(tag) %>
|
|
</td>
|
|
<% end %>
|
|
<% if edit_perm %>
|
|
<td class="py-4 px-3 text-right"></td>
|
|
<% end %>
|
|
<% end %>
|
|
</tr>
|
|
<% end %>
|
|
<% if @aces.count == 1 %>
|
|
<tr class="group-[&:has(tr:nth-child(n+3))]:hidden">
|
|
<td colspan="3" class="py-4 px-8">
|
|
<p class="mb-4">Currently, this token has no access to the project.</p>
|
|
<p>You should grant the token the access you think the token should have. Be aware that the token can
|
|
never have more access to the project than your account has. Each access control entry has a single
|
|
action and object. Access is allowed if there is an access control entry allowing the token to take
|
|
the action on the object. Actions and objects can be tags, which are used for grouping multiple
|
|
actions or multiple objects into a single entity.</p>
|
|
</td>
|
|
</tr>
|
|
<% end %>
|
|
</tbody>
|
|
</table>
|
|
<% if edit_perm %>
|
|
<div class="px-3 py-4 flex justify-between">
|
|
<%== render(
|
|
"components/button",
|
|
locals: {
|
|
icon: "hero-plus",
|
|
text: "New Access Control Entry",
|
|
attributes: {
|
|
id: "new-ace-btn"
|
|
}
|
|
}
|
|
) %>
|
|
<%== render("components/button", locals: { text: "Save All" }) %>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
</form>
|
|
<% end %>
|
|
<% if @token %>
|
|
<div class="overflow-hidden rounded-lg shadow ring-1 ring-black ring-opacity-5 bg-white divide-y divide-gray-200">
|
|
<div class="px-4 py-5 sm:p-6">
|
|
<form action="<%= restriction_path %>" role="form" method="POST">
|
|
<%== csrf_tag(restriction_path) %>
|
|
<div class="sm:flex sm:items-center sm:justify-between">
|
|
<div>
|
|
<h3 class="text-base font-semibold leading-6 text-gray-900"><%= restriction_title %>
|
|
Personal Access Token</h3>
|
|
<div class="mt-2 text-sm text-gray-500">
|
|
<p>
|
|
<% if unrestricted %>
|
|
This token currently has the same access to this project that your account has. If you would like
|
|
to restrict the access of this token, use the "Restrict Token Access" button. After restricting
|
|
token access, the token will have no access to the project, and you can grant the specific access
|
|
you want the token to have. Be aware that the token can never have more access to the project than
|
|
your account has.
|
|
<% else %>
|
|
This token currently has access to the project based on the access control entries above. If you
|
|
would like to remove access control restrictions, and grant the token full access to your account,
|
|
click on the "Unrestrict Token Access" button.
|
|
<% end %>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div id="restrict-<%=@token.ubid%>" class="mt-5 sm:ml-6 sm:mt-0 sm:flex sm:flex-shrink-0 sm:items-center">
|
|
<div class="col-span-12 sm:col-span-2 flex justify-end items-end">
|
|
<%== render("components/form/submit_button", locals: { text: "#{restriction_title} Token Access" }) %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
</div>
|