Update permission logic

This commit is contained in:
Tuan Dang
2025-04-08 18:45:16 -07:00
parent 728c3f56a7
commit 20ebfcefaa
11 changed files with 109 additions and 63 deletions
@@ -57,12 +57,12 @@ export const SshCertificatesTable = () => {
</Td>
<Td>
{certificate.notBefore
? format(new Date(certificate.notBefore), "yyyy-MM-dd")
? format(new Date(certificate.notBefore), "yyyy-MM-dd | HH:mm:ss")
: "-"}
</Td>
<Td>
{certificate.notAfter
? format(new Date(certificate.notAfter), "yyyy-MM-dd")
? format(new Date(certificate.notAfter), "yyyy-MM-dd | HH:mm:ss")
: "-"}
</Td>
</Tr>
@@ -43,17 +43,19 @@ export const SshHostsSection = () => {
<div className="mb-4 flex justify-between">
<p className="text-xl font-semibold text-mineshaft-100">Hosts</p>
<ProjectPermissionCan I={ProjectPermissionActions.Create} a={ProjectPermissionSub.SshHosts}>
{(isAllowed) => (
<Button
colorSchema="primary"
type="submit"
leftIcon={<FontAwesomeIcon icon={faPlus} />}
onClick={() => handlePopUpOpen("sshHost")}
isDisabled={!isAllowed}
>
Add Host
</Button>
)}
{(isAllowed) =>
isAllowed && (
<Button
colorSchema="primary"
type="submit"
leftIcon={<FontAwesomeIcon icon={faPlus} />}
onClick={() => handlePopUpOpen("sshHost")}
isDisabled={!isAllowed}
>
Add Host
</Button>
)
}
</ProjectPermissionCan>
</div>
<SshHostsTable handlePopUpOpen={handlePopUpOpen} />
@@ -1,7 +1,15 @@
import { faEllipsis, faPencil, faServer, faTrash } from "@fortawesome/free-solid-svg-icons";
import {
faDownload,
faEllipsis,
faPencil,
faServer,
faTrash
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import FileSaver from "file-saver";
import { twMerge } from "tailwind-merge";
import { createNotification } from "@app/components/notifications";
import { ProjectPermissionCan } from "@app/components/permissions";
import {
DropdownMenu,
@@ -20,7 +28,7 @@ import {
Tr
} from "@app/components/v2";
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
import { useListWorkspaceSshHosts } from "@app/hooks/api";
import { fetchSshHostUserCaPublicKey, useListWorkspaceSshHosts } from "@app/hooks/api";
import { UsePopUpState } from "@app/hooks/usePopUp";
type Props = {
@@ -34,6 +42,24 @@ export const SshHostsTable = ({ handlePopUpOpen }: Props) => {
const { currentWorkspace } = useWorkspace();
const { data, isPending } = useListWorkspaceSshHosts(currentWorkspace?.id || "");
const downloadTxtFile = (filename: string, content: string) => {
const blob = new Blob([content], { type: "text/plain;charset=utf-8" });
FileSaver.saveAs(blob, filename);
};
const handleDownloadUserCaKey = async (sshHostId: string) => {
try {
const publicKey = await fetchSshHostUserCaPublicKey(sshHostId);
downloadTxtFile("infisical_user_ca.pub", publicKey);
} catch (err) {
console.error("Failed to download User CA public key", err);
createNotification({
type: "error",
text: "Failed to download User CA public key"
});
}
};
return (
<div>
<TableContainer>
@@ -41,6 +67,7 @@ export const SshHostsTable = ({ handlePopUpOpen }: Props) => {
<THead>
<Tr>
<Th>Hostname</Th>
<Th>Login User - Authorized Principals Mapping</Th>
<Th />
</Tr>
</THead>
@@ -52,11 +79,28 @@ export const SshHostsTable = ({ handlePopUpOpen }: Props) => {
data.map((host) => {
return (
<Tr
className="h-10 cursor-pointer transition-colors duration-100 hover:bg-mineshaft-700"
// className="h-10 cursor-pointer transition-colors duration-100 hover:bg-mineshaft-700"
className="h-10"
key={`ssh-host-${host.id}`}
>
<Td>{host.hostname}</Td>
<Td className="flex justify-end">
<Td>
{host.loginMappings.length === 0 ? (
<span className="italic text-mineshaft-400">None</span>
) : (
host.loginMappings.map(({ loginUser, allowedPrincipals }) => (
<div key={`${host.id}-${loginUser}`} className="mb-2">
<div className="text-mineshaft-200">{loginUser}</div>
{allowedPrincipals.map((principal) => (
<div key={principal} className="ml-4">
└─ {principal}
</div>
))}
</div>
))
)}
</Td>
<Td className="text-right align-middle">
<DropdownMenu>
<DropdownMenuTrigger asChild className="rounded-lg">
<div className="hover:text-primary-400 data-[state=open]:text-primary-400">
@@ -66,6 +110,15 @@ export const SshHostsTable = ({ handlePopUpOpen }: Props) => {
</div>
</DropdownMenuTrigger>
<DropdownMenuContent align="start" className="p-1">
<DropdownMenuItem
onClick={async (e) => {
e.stopPropagation();
handleDownloadUserCaKey(host.id);
}}
icon={<FontAwesomeIcon icon={faDownload} />}
>
Download User CA Public Key
</DropdownMenuItem>
<ProjectPermissionCan
I={ProjectPermissionActions.Edit}
a={ProjectPermissionSub.SshHosts}