ubicloud/views/project/access-control.erb
Jeremy Evans 311699eac2 Use herb linter for linting erb files, and fix most issues
After running these changes, there are 1 error and 3 warnings when
running the linter, due to bugs in the linter
(https://github.com/marcoroth/herb/issues 480, 481, 483).
2025-09-05 14:51:03 -07:00

214 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 = path(@token)
table_headers = %w[Action Object]
edit_perm = true
unrestricted = @token.unrestricted_token_for_project?(@project.id)
restriction_title, restriction_path =
if unrestricted
["Restrict", "#{@project.path}/token/#{@token.ubid}/restrict-access"]
else
["Unrestrict", "#{@project.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 = "#{user_path}/access-control"
table_headers = %w[Subject Action Object]
edit_perm = has_project_permission("Project:editaccess")
end
@page_title = "#{@project.name} - #{page_header}" %>
<%== render("project/user-tabbar") unless @token %>
<div class="space-y-1">
<%== part(
"components/page_header",
title: page_header,
breadcrumbs: [%w[Projects /project], [@project.name, @project.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(action: form_action, role: :form, method: :post, id: "access-control-form") do %>
<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.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">
<%== part(
"components/form/select",
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">
<%== part("components/form/hidden", name: "aces[][ubid]", value: ubid) %>
<%== part("components/form/checkbox", 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">
<%== part("components/button", icon: "hero-plus", text: "New Access Control Entry", attributes: { id: "new-ace-btn" }) %>
<%== part("components/button", text: "Save All") %>
</div>
<% end %>
</div>
<% end %>
<% 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) do %>
<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">
<%== part("components/form/submit_button", text: "#{restriction_title} Token Access") %>
</div>
</div>
</div>
<% end %>
</div>
</div>
<% end %>
</div>