Add API tokens support (#9)
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Make it possible to create token authorized to query predetermined set of routes. Reviewed-on: #9 Co-authored-by: Pierre HUBERT <pierre.git@communiquons.org> Co-committed-by: Pierre HUBERT <pierre.git@communiquons.org>
This commit is contained in:
111
virtweb_frontend/src/widgets/tokens/TokenRawRightsEditor.tsx
Normal file
111
virtweb_frontend/src/widgets/tokens/TokenRawRightsEditor.tsx
Normal file
@ -0,0 +1,111 @@
|
||||
import AddIcon from "@mui/icons-material/Add";
|
||||
import DeleteIcon from "@mui/icons-material/Delete";
|
||||
import {
|
||||
IconButton,
|
||||
Paper,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableContainer,
|
||||
TableHead,
|
||||
TableRow,
|
||||
Tooltip,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import { ServerApi } from "../../api/ServerApi";
|
||||
import { APIToken } from "../../api/TokensApi";
|
||||
import { SelectInput } from "../forms/SelectInput";
|
||||
import { TextInput } from "../forms/TextInput";
|
||||
|
||||
export function TokenRawRightsEditor(p: {
|
||||
token: APIToken;
|
||||
editable: boolean;
|
||||
onChange?: () => void;
|
||||
}): React.ReactElement {
|
||||
const addRule = () => {
|
||||
p.token.rights.push({ path: "/api/", verb: "GET" });
|
||||
p.onChange?.();
|
||||
};
|
||||
|
||||
const deleteRule = (id: number) => {
|
||||
p.token.rights.splice(id, 1);
|
||||
p.onChange?.();
|
||||
};
|
||||
|
||||
return (
|
||||
<TableContainer component={Paper}>
|
||||
<div
|
||||
style={{
|
||||
padding: "10px 10px 0px 10px",
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
<Typography variant="h5">Raw rights</Typography>
|
||||
<div>
|
||||
{p.editable && (
|
||||
<Tooltip title="Add a new right rule">
|
||||
<IconButton onClick={addRule}>
|
||||
<AddIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>Verb</TableCell>
|
||||
<TableCell>URI</TableCell>
|
||||
{p.editable && <TableCell>Actions</TableCell>}
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{p.token.rights.map((r, num) => (
|
||||
<TableRow key={num} hover>
|
||||
<TableCell style={{ width: "100px" }}>
|
||||
<SelectInput
|
||||
{...p}
|
||||
value={r.verb}
|
||||
onValueChange={(v) => {
|
||||
r.verb = v as any;
|
||||
p.onChange?.();
|
||||
}}
|
||||
options={[
|
||||
{ value: "GET" },
|
||||
{ value: "POST" },
|
||||
{ value: "PATCH" },
|
||||
{ value: "PUT" },
|
||||
{ value: "DELETE" },
|
||||
]}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<TextInput
|
||||
{...p}
|
||||
value={r.path}
|
||||
onValueChange={(v) => {
|
||||
r.path = v ?? "";
|
||||
p.onChange?.();
|
||||
}}
|
||||
checkValue={(v) => v.startsWith("/api/")}
|
||||
size={ServerApi.Config.constraints.api_token_right_path_size}
|
||||
/>
|
||||
</TableCell>
|
||||
{p.editable && (
|
||||
<TableCell style={{ width: "100px" }}>
|
||||
<IconButton onClick={() => deleteRule(num)}>
|
||||
<Tooltip title="Remove the rule">
|
||||
<DeleteIcon />
|
||||
</Tooltip>
|
||||
</IconButton>
|
||||
</TableCell>
|
||||
)}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
);
|
||||
}
|
Reference in New Issue
Block a user