mirror of
https://github.com/tale/headplane.git
synced 2026-08-12 14:46:52 +00:00
190 lines
4.9 KiB
TypeScript
190 lines
4.9 KiB
TypeScript
import { data } from "react-router";
|
|
|
|
import { Capabilities } from "~/server/web/roles";
|
|
|
|
import type { Route } from "./+types/overview";
|
|
|
|
export async function restrictionAction({ request, context }: Route.ActionArgs) {
|
|
const principal = await context.auth.require(request);
|
|
const check = context.auth.can(principal, Capabilities.configure_iam);
|
|
|
|
if (!check) {
|
|
throw data("You do not have permission to modify IAM settings.", {
|
|
status: 403,
|
|
});
|
|
}
|
|
|
|
if (!context.hs.writable()) {
|
|
throw data("The Headscale configuration file is not editable.", {
|
|
status: 403,
|
|
});
|
|
}
|
|
|
|
const formData = await request.formData();
|
|
const action = formData.get("action_id")?.toString();
|
|
if (!action) {
|
|
throw data("No action provided.", {
|
|
status: 400,
|
|
});
|
|
}
|
|
|
|
// We only need healthchecks which don't rely on an API key
|
|
const api = context.hsApi.getRuntimeClient("fake-api-key");
|
|
switch (action) {
|
|
case "add_domain": {
|
|
const domain = formData.get("domain")?.toString()?.trim();
|
|
if (!domain) {
|
|
throw data("No domain provided.", {
|
|
status: 400,
|
|
});
|
|
}
|
|
|
|
const domains = [...new Set([...(context.hs.c?.oidc?.allowed_domains ?? []), domain])];
|
|
|
|
await context.hs.patch([
|
|
{
|
|
path: "oidc.allowed_domains",
|
|
value: domains,
|
|
},
|
|
]);
|
|
|
|
context.integration?.onConfigChange(api);
|
|
return data("Domain added successfully.");
|
|
}
|
|
|
|
case "remove_domain": {
|
|
const domain = formData.get("domain")?.toString()?.trim();
|
|
if (!domain) {
|
|
throw data("No domain provided.", {
|
|
status: 400,
|
|
});
|
|
}
|
|
|
|
const storedDomains = context.hs.c?.oidc?.allowed_domains ?? [];
|
|
if (!storedDomains.includes(domain)) {
|
|
// Domain not found in the list
|
|
throw data(`Domain "${domain}" not found in allowed domains.`, {
|
|
status: 400,
|
|
});
|
|
}
|
|
|
|
// Filter out the domain to remove it from the list
|
|
const domains = storedDomains.filter((d: string) => d !== domain);
|
|
await context.hs.patch([
|
|
{
|
|
path: "oidc.allowed_domains",
|
|
value: domains,
|
|
},
|
|
]);
|
|
context.integration?.onConfigChange(api);
|
|
return data("Domain removed successfully.");
|
|
}
|
|
|
|
case "add_group": {
|
|
const group = formData.get("group")?.toString()?.trim();
|
|
if (!group) {
|
|
throw data("No group provided.", {
|
|
status: 400,
|
|
});
|
|
}
|
|
|
|
const groups = [...new Set([...(context.hs.c?.oidc?.allowed_groups ?? []), group])];
|
|
|
|
await context.hs.patch([
|
|
{
|
|
path: "oidc.allowed_groups",
|
|
value: groups,
|
|
},
|
|
]);
|
|
|
|
context.integration?.onConfigChange(api);
|
|
return data("Group added successfully.");
|
|
}
|
|
|
|
case "remove_group": {
|
|
const group = formData.get("group")?.toString()?.trim();
|
|
if (!group) {
|
|
throw data("No group provided.", {
|
|
status: 400,
|
|
});
|
|
}
|
|
|
|
const storedGroups = context.hs.c?.oidc?.allowed_groups ?? [];
|
|
if (!storedGroups.includes(group)) {
|
|
// Group not found in the list
|
|
throw data(`Group "${group}" not found in allowed groups.`, {
|
|
status: 400,
|
|
});
|
|
}
|
|
|
|
// Filter out the group to remove it from the list
|
|
const groups = storedGroups.filter((d: string) => d !== group);
|
|
await context.hs.patch([
|
|
{
|
|
path: "oidc.allowed_groups",
|
|
value: groups,
|
|
},
|
|
]);
|
|
|
|
context.integration?.onConfigChange(api);
|
|
return data("Group removed successfully.");
|
|
}
|
|
|
|
case "add_user": {
|
|
const user = formData.get("user")?.toString()?.trim();
|
|
if (!user) {
|
|
throw data("No user provided.", {
|
|
status: 400,
|
|
});
|
|
}
|
|
|
|
const users = [...new Set([...(context.hs.c?.oidc?.allowed_users ?? []), user])];
|
|
|
|
await context.hs.patch([
|
|
{
|
|
path: "oidc.allowed_users",
|
|
value: users,
|
|
},
|
|
]);
|
|
|
|
context.integration?.onConfigChange(api);
|
|
return data("User added successfully.");
|
|
}
|
|
|
|
case "remove_user": {
|
|
const user = formData.get("user")?.toString()?.trim();
|
|
if (!user) {
|
|
throw data("No user provided.", {
|
|
status: 400,
|
|
});
|
|
}
|
|
|
|
const storedUsers = context.hs.c?.oidc?.allowed_users ?? [];
|
|
if (!storedUsers.includes(user)) {
|
|
// User not found in the list
|
|
throw data(`User "${user}" not found in allowed users.`, {
|
|
status: 400,
|
|
});
|
|
}
|
|
|
|
// Filter out the user to remove it from the list
|
|
const users = storedUsers.filter((d: string) => d !== user);
|
|
await context.hs.patch([
|
|
{
|
|
path: "oidc.allowed_users",
|
|
value: users,
|
|
},
|
|
]);
|
|
|
|
context.integration?.onConfigChange(api);
|
|
return data("User removed successfully.");
|
|
}
|
|
|
|
default: {
|
|
throw data("Invalid action provided.", {
|
|
status: 400,
|
|
});
|
|
}
|
|
}
|
|
}
|