swarm-ui: show and toggle an agent's unrestricted internet flag, add it to the create dialog
This commit is contained in:
parent
24beb167d8
commit
10508895c4
2 changed files with 136 additions and 2 deletions
|
|
@ -23,12 +23,18 @@ import {
|
|||
requestPermissions,
|
||||
togglePermission,
|
||||
} from "../../pages/CreateAgentPermissions.js";
|
||||
import { editorSelection, grantSummary } from "./permissions.js";
|
||||
import {
|
||||
editorSelection,
|
||||
grantSummary,
|
||||
internetBody,
|
||||
internetSummary,
|
||||
} from "./permissions.js";
|
||||
import "./AgentLimits.css";
|
||||
|
||||
// The stored grant as the route carries it; the field is absent when unset.
|
||||
interface Grant {
|
||||
permissions?: string[];
|
||||
unrestricted_internet?: boolean;
|
||||
}
|
||||
|
||||
// Mirrors swarm-controller's `Catalogue` (`GET /api/permissions`).
|
||||
|
|
@ -47,6 +53,7 @@ export function AgentPermissions({ agent }: { agent: string }) {
|
|||
// Bumped after a save or a clear, so the grant is fetched again.
|
||||
const [reload, setReload] = useState(0);
|
||||
const [editing, setEditing] = useState(false);
|
||||
const [flagBusy, setFlagBusy] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
|
|
@ -68,6 +75,28 @@ export function AgentPermissions({ agent }: { agent: string }) {
|
|||
};
|
||||
}, [agent, reload]);
|
||||
|
||||
// Flips the internet flag, sending the stored list with it.
|
||||
async function setInternet(g: Grant, unrestricted: boolean) {
|
||||
if (flagBusy) return;
|
||||
setFlagBusy(true);
|
||||
try {
|
||||
const r = await fetch(permissionsUrl(agent), {
|
||||
method: "PUT",
|
||||
headers: { "content-type": "application/json" },
|
||||
body: JSON.stringify(internetBody(g.permissions, unrestricted)),
|
||||
});
|
||||
if (!r.ok) {
|
||||
setError(await readApiError(r));
|
||||
return;
|
||||
}
|
||||
setReload((n) => n + 1);
|
||||
} catch (e: unknown) {
|
||||
setError({ detail: String(e) });
|
||||
} finally {
|
||||
setFlagBusy(false);
|
||||
}
|
||||
}
|
||||
|
||||
// A grant already loaded stays under a failed refetch, so a save that
|
||||
// worked is not hidden by a read that did not.
|
||||
const errorPanel = error ? (
|
||||
|
|
@ -99,6 +128,22 @@ export function AgentPermissions({ agent }: { agent: string }) {
|
|||
))}
|
||||
</ul>
|
||||
) : null}
|
||||
<Badge
|
||||
label="internet"
|
||||
value={internetSummary(grant.unrestricted_internet)}
|
||||
/>
|
||||
<Badge
|
||||
variant="quiet"
|
||||
value={
|
||||
grant.unrestricted_internet === false
|
||||
? "allow unrestricted"
|
||||
: "restrict"
|
||||
}
|
||||
title={`set whether ${agent}'s traffic may leave the host unfiltered`}
|
||||
onClick={() =>
|
||||
void setInternet(grant, grant.unrestricted_internet === false)
|
||||
}
|
||||
/>
|
||||
<Badge
|
||||
variant="quiet"
|
||||
value="edit"
|
||||
|
|
|
|||
|
|
@ -21,3 +21,27 @@ export function grantSummary(stored: string[] | undefined): string {
|
|||
if (stored.length === 0) return "none";
|
||||
return `${stored.length} granted`;
|
||||
}
|
||||
|
||||
/**
|
||||
* How the panel reads the stored `unrestricted_internet`. An absent value
|
||||
* counts as on, and says "legacy" because the swarm never set it.
|
||||
*/
|
||||
export function internetSummary(stored: boolean | undefined): string {
|
||||
if (stored === undefined) return "unrestricted (legacy)";
|
||||
return stored ? "unrestricted" : "restricted";
|
||||
}
|
||||
|
||||
/**
|
||||
* The `PUT` body that sets the internet flag. A `PUT` without `permissions`
|
||||
* resets a stored list to the default, so the stored list goes along; an
|
||||
* agent with none stored sends the flag alone, which leaves it unset.
|
||||
*/
|
||||
export function internetBody(
|
||||
stored: string[] | undefined,
|
||||
unrestricted: boolean,
|
||||
): { permissions?: string[]; unrestricted_internet: boolean } {
|
||||
return {
|
||||
...(stored === undefined ? {} : { permissions: stored }),
|
||||
unrestricted_internet: unrestricted,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue