From e68569b9b4772b45e39d0a29392d69757e8ed48f Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Sat, 20 Apr 2024 09:46:25 +0200 Subject: [PATCH] Add basic token rights editor --- virtweb_frontend/src/api/TokensApi.ts | 4 +- .../src/widgets/tokens/APITokenDetails.tsx | 21 ++- ...htsEditor.tsx => TokenRawRightsEditor.tsx} | 2 +- .../src/widgets/tokens/TokenRightsEditor.tsx | 151 ++++++++++++++++++ 4 files changed, 173 insertions(+), 5 deletions(-) rename virtweb_frontend/src/widgets/tokens/{RawRightsEditor.tsx => TokenRawRightsEditor.tsx} (98%) create mode 100644 virtweb_frontend/src/widgets/tokens/TokenRightsEditor.tsx diff --git a/virtweb_frontend/src/api/TokensApi.ts b/virtweb_frontend/src/api/TokensApi.ts index 8969b47..da1dead 100644 --- a/virtweb_frontend/src/api/TokensApi.ts +++ b/virtweb_frontend/src/api/TokensApi.ts @@ -1,7 +1,9 @@ import { APIClient } from "./ApiClient"; +export type RightVerb = "POST" | "GET" | "PUT" | "DELETE" | "PATCH"; + export interface TokenRight { - verb: "POST" | "GET" | "PUT" | "DELETE" | "PATCH"; + verb: RightVerb; path: string; } diff --git a/virtweb_frontend/src/widgets/tokens/APITokenDetails.tsx b/virtweb_frontend/src/widgets/tokens/APITokenDetails.tsx index 6f51a64..a5a9ed1 100644 --- a/virtweb_frontend/src/widgets/tokens/APITokenDetails.tsx +++ b/virtweb_frontend/src/widgets/tokens/APITokenDetails.tsx @@ -15,7 +15,8 @@ import { EditSection } from "../forms/EditSection"; import { IPInputWithMask } from "../forms/IPInput"; import { RadioGroupInput } from "../forms/RadioGroupInput"; import { TextInput } from "../forms/TextInput"; -import { RawRightsEditor } from "./RawRightsEditor"; +import { TokenRawRightsEditor } from "./TokenRawRightsEditor"; +import { TokenRightsEditor } from "./TokenRightsEditor"; const SECS_PER_DAY = 3600 * 24; @@ -106,7 +107,7 @@ function APITokenDetailsInner(p: DetailsInnerProps): React.ReactElement { ]} /> {currTab === TokenTab.General && } - {/* todo: rights */} + {currTab === TokenTab.Rights && } {currTab === TokenTab.RawRights && } {currTab === TokenTab.Danger && } @@ -198,10 +199,24 @@ function APITokenTabGeneral(p: DetailsInnerProps): React.ReactElement { ); } +function APITokenRights(p: DetailsInnerProps): React.ReactElement { + return ( +
+ +
+ ); +} + function APITokenRawRights(p: DetailsInnerProps): React.ReactElement { return (
- +
); } diff --git a/virtweb_frontend/src/widgets/tokens/RawRightsEditor.tsx b/virtweb_frontend/src/widgets/tokens/TokenRawRightsEditor.tsx similarity index 98% rename from virtweb_frontend/src/widgets/tokens/RawRightsEditor.tsx rename to virtweb_frontend/src/widgets/tokens/TokenRawRightsEditor.tsx index 2df4fb1..654e8a6 100644 --- a/virtweb_frontend/src/widgets/tokens/RawRightsEditor.tsx +++ b/virtweb_frontend/src/widgets/tokens/TokenRawRightsEditor.tsx @@ -17,7 +17,7 @@ import { APIToken } from "../../api/TokensApi"; import { SelectInput } from "../forms/SelectInput"; import { TextInput } from "../forms/TextInput"; -export function RawRightsEditor(p: { +export function TokenRawRightsEditor(p: { token: APIToken; editable: boolean; onChange?: () => void; diff --git a/virtweb_frontend/src/widgets/tokens/TokenRightsEditor.tsx b/virtweb_frontend/src/widgets/tokens/TokenRightsEditor.tsx new file mode 100644 index 0000000..b568d76 --- /dev/null +++ b/virtweb_frontend/src/widgets/tokens/TokenRightsEditor.tsx @@ -0,0 +1,151 @@ +import { + Checkbox, + FormControlLabel, + Paper, + Tooltip, + Typography, +} from "@mui/material"; +import React from "react"; +import { NWFilter } from "../../api/NWFilterApi"; +import { NetworkInfo } from "../../api/NetworksApi"; +import { APIToken, TokenRight } from "../../api/TokensApi"; +import { VMInfo } from "../../api/VMApi"; + +export function TokenRightsEditor(p: { + token: APIToken; + editable: boolean; + onChange?: () => void; + vms: VMInfo[]; + networks: NetworkInfo[]; + nwFilters: NWFilter[]; + tokens: APIToken[]; +}): React.ReactElement { + return ( + <> + {/* ISO files */} + + + + + + + + + {/* Server general information */} + + + + + + + + + ); +} + +function RightsSection( + p: React.PropsWithChildren<{ label: string }> +): React.ReactElement { + return ( + + {p.label} + {p.children} + + ); +} + +function RouteRight(p: { + right: TokenRight; + label?: string; + editable: boolean; + token: APIToken; + onChange?: () => void; + parent?: TokenRight; +}): React.ReactElement { + const activated = + p.token.rights.find( + (r) => r.verb === p.right.verb && r.path === p.right.path + ) !== undefined; + + const toggle = (a: boolean) => { + if (a) { + p.token.rights.push(p.right); + } else { + p.token.rights.splice(p.token.rights.indexOf(p.right), 1); + } + p.onChange?.(); + }; + + return ( +
+ + toggle(a)} + /> + } + label={p.label} + /> + +
+ ); +}