FEAT - LAUNCHER: wire Engine access roles
This commit is contained in:
parent
ec91821fdc
commit
55ab952ae8
|
|
@ -6,7 +6,14 @@ const platformGroups = {
|
|||
launcherUser: "nodedc:launcher:user",
|
||||
taskManagerAdmin: "nodedc:taskmanager:admin",
|
||||
taskManagerUser: "nodedc:taskmanager:user",
|
||||
engineAdmin: "nodedc:engine:admin",
|
||||
engineEditor: "nodedc:engine:editor",
|
||||
engineViewer: "nodedc:engine:viewer",
|
||||
engineLegacyAdmin: "nodedc_admin",
|
||||
engineLegacyEditor: "nodedc_editor",
|
||||
engineLegacyViewer: "nodedc_viewer",
|
||||
};
|
||||
const engineServiceSlugs = new Set(["nodedc", "engine", "nodedc-engine"]);
|
||||
const publicPoolClientId = "client_public_pool";
|
||||
const publicPoolClient = {
|
||||
id: publicPoolClientId,
|
||||
|
|
@ -200,6 +207,7 @@ export function resolveRequiredGroups(data, user) {
|
|||
groupNames.add(platformGroups.launcherAdmin);
|
||||
groupNames.add(platformGroups.taskManagerAdmin);
|
||||
groupNames.add(platformGroups.taskManagerUser);
|
||||
addGroups(groupNames, resolveEngineRoleGroups("admin"));
|
||||
return [...groupNames];
|
||||
}
|
||||
|
||||
|
|
@ -219,7 +227,9 @@ export function resolveRequiredGroups(data, user) {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (service.slug === "task-manager") {
|
||||
if (isEngineService(service)) {
|
||||
addGroups(groupNames, resolveEngineRoleGroups(access.appRole));
|
||||
} else if (service.slug === "task-manager") {
|
||||
groupNames.add(platformGroups.taskManagerUser);
|
||||
|
||||
if (access.appRole === "admin" || access.appRole === "owner") {
|
||||
|
|
@ -234,6 +244,32 @@ export function resolveRequiredGroups(data, user) {
|
|||
return [...groupNames];
|
||||
}
|
||||
|
||||
function isEngineService(service) {
|
||||
return (
|
||||
engineServiceSlugs.has(service.slug) ||
|
||||
engineServiceSlugs.has(service.authentikApplicationSlug) ||
|
||||
service.id === "service_nodedc"
|
||||
);
|
||||
}
|
||||
|
||||
function resolveEngineRoleGroups(appRole) {
|
||||
if (appRole === "admin" || appRole === "owner") {
|
||||
return [platformGroups.engineAdmin, platformGroups.engineLegacyAdmin];
|
||||
}
|
||||
|
||||
if (appRole === "viewer") {
|
||||
return [platformGroups.engineViewer, platformGroups.engineLegacyViewer];
|
||||
}
|
||||
|
||||
return [platformGroups.engineEditor, platformGroups.engineLegacyEditor];
|
||||
}
|
||||
|
||||
function addGroups(target, groups) {
|
||||
for (const group of groups) {
|
||||
target.add(group);
|
||||
}
|
||||
}
|
||||
|
||||
function getUserRuntimeClients(data, userId) {
|
||||
const clients = [...data.clients];
|
||||
const hasPublicPoolMembership = data.memberships.some(
|
||||
|
|
|
|||
|
|
@ -37,6 +37,14 @@ const accessRequestStatuses = new Set(["new", "approved", "rejected"]);
|
|||
const taskerInviteRequestStatuses = new Set(["new", "approved", "rejected", "cancelled"]);
|
||||
const taskManagerInviteRoles = new Set(["guest", "member", "admin"]);
|
||||
const publicPoolClientId = "client_public_pool";
|
||||
const engineAuthentikGroups = [
|
||||
"nodedc:engine:admin",
|
||||
"nodedc:engine:editor",
|
||||
"nodedc:engine:viewer",
|
||||
"nodedc_admin",
|
||||
"nodedc_editor",
|
||||
"nodedc_viewer",
|
||||
];
|
||||
const publicPoolClient = {
|
||||
id: publicPoolClientId,
|
||||
type: "person",
|
||||
|
|
@ -1811,6 +1819,7 @@ export function createControlPlaneStore({ projectRoot }) {
|
|||
"nodedc:superadmin",
|
||||
"nodedc:launcher:admin",
|
||||
"nodedc:launcher:user",
|
||||
...engineAuthentikGroups,
|
||||
...data.services.flatMap((service) => (service.authentikGroupName ? [service.authentikGroupName] : [])),
|
||||
...data.groups.map((group) => `client:${group.clientId}:group:${slugify(group.name)}`),
|
||||
],
|
||||
|
|
@ -1931,6 +1940,7 @@ function normalizeData(payload) {
|
|||
...client,
|
||||
integrations: normalizeClientIntegrations(client.integrations),
|
||||
}));
|
||||
data.services = data.services.map(normalizeService);
|
||||
data.accessRequests = data.accessRequests.map(normalizeAccessRequest).filter(Boolean);
|
||||
data.revokedAccounts = data.revokedAccounts.map(normalizeRevokedAccount).filter(Boolean);
|
||||
data.serviceModuleEntitlements = data.serviceModuleEntitlements.map(normalizeServiceModuleEntitlement).filter(Boolean);
|
||||
|
|
@ -1938,6 +1948,23 @@ function normalizeData(payload) {
|
|||
return data;
|
||||
}
|
||||
|
||||
function normalizeService(service) {
|
||||
if (typeof service !== "object" || service === null) return service;
|
||||
if (service.id !== "service_nodedc" && service.slug !== "nodedc" && service.authentikApplicationSlug !== "nodedc") return service;
|
||||
|
||||
return {
|
||||
...service,
|
||||
title: service.title === "AGENT CORE" || service.title === "NodeDC" ? "ENGINE" : service.title,
|
||||
url: service.url === "https://nodedc.ru/" || service.url === "https://dev.handhdc.ru/sso/launch" ? "https://engine.nodedc.ru/" : service.url,
|
||||
launchUrl:
|
||||
service.launchUrl === "https://nodedc.ru/" || service.launchUrl === "https://dev.handhdc.ru/sso/launch"
|
||||
? "https://engine.nodedc.ru/"
|
||||
: service.launchUrl,
|
||||
authentikApplicationSlug: service.authentikApplicationSlug === "nodedc" ? "nodedc-engine" : service.authentikApplicationSlug,
|
||||
authentikGroupName: service.authentikGroupName === "service-nodedc" ? "nodedc:engine:viewer" : service.authentikGroupName,
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeServiceModuleEntitlement(payload) {
|
||||
if (typeof payload !== "object" || payload === null) return null;
|
||||
const clientId = nullableString(payload.clientId);
|
||||
|
|
|
|||
|
|
@ -2134,7 +2134,7 @@ function getAppCatalog() {
|
|||
const launcherData = readLauncherData();
|
||||
const services = Array.isArray(launcherData?.services) ? launcherData.services : [];
|
||||
const serviceCatalog = services.map((service) => {
|
||||
const specialGroups = specialRequiredGroups(service.slug);
|
||||
const specialGroups = specialRequiredGroups(service);
|
||||
const requiredGroups = specialGroups.length
|
||||
? specialGroups
|
||||
: service.authentikGroupName
|
||||
|
|
@ -2175,9 +2175,26 @@ function getAppCatalog() {
|
|||
];
|
||||
}
|
||||
|
||||
function specialRequiredGroups(slug) {
|
||||
const engineRequiredGroups = [
|
||||
"nodedc:engine:admin",
|
||||
"nodedc:engine:editor",
|
||||
"nodedc:engine:viewer",
|
||||
"nodedc_admin",
|
||||
"nodedc_editor",
|
||||
"nodedc_viewer",
|
||||
];
|
||||
|
||||
function specialRequiredGroups(serviceOrSlug) {
|
||||
const slug = typeof serviceOrSlug === "string" ? serviceOrSlug : serviceOrSlug?.slug;
|
||||
const applicationSlug = typeof serviceOrSlug === "string" ? null : serviceOrSlug?.authentikApplicationSlug;
|
||||
const serviceId = typeof serviceOrSlug === "string" ? null : serviceOrSlug?.id;
|
||||
|
||||
if (slug === "launcher") return ["nodedc:launcher:admin", "nodedc:launcher:user"];
|
||||
if (slug === "task-manager") return ["nodedc:taskmanager:admin", "nodedc:taskmanager:user"];
|
||||
if (slug === "nodedc" || slug === "engine" || slug === "nodedc-engine" || applicationSlug === "nodedc-engine" || serviceId === "service_nodedc") {
|
||||
return engineRequiredGroups;
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -77,19 +77,19 @@ export const mockServices: Service[] = [
|
|||
{
|
||||
id: "service_nodedc",
|
||||
slug: "nodedc",
|
||||
title: "NodeDC",
|
||||
title: "ENGINE",
|
||||
subtitle: "Агентная платформа",
|
||||
description: "Сборка, запуск и мониторинг агентных workflow.",
|
||||
fullDescription:
|
||||
"NodeDC используется для настройки агентных процессов, визуальной оркестрации, интеграций и runtime-мониторинга.",
|
||||
url: "https://dev.handhdc.ru/sso/launch",
|
||||
launchUrl: "https://dev.handhdc.ru/sso/launch",
|
||||
url: "https://engine.nodedc.ru/",
|
||||
launchUrl: "https://engine.nodedc.ru/",
|
||||
accentColor: "#B5FF5A",
|
||||
fallbackGradient: "linear-gradient(128deg, rgba(181, 255, 90, 0.84), rgba(37, 58, 36, 0.86) 42%, #0A0D10 82%)",
|
||||
status: "active",
|
||||
order: 10,
|
||||
authentikApplicationSlug: "nodedc",
|
||||
authentikGroupName: "service-nodedc",
|
||||
authentikApplicationSlug: "nodedc-engine",
|
||||
authentikGroupName: "nodedc:engine:viewer",
|
||||
createdAt: "2026-04-01T10:00:00Z",
|
||||
updatedAt: now,
|
||||
},
|
||||
|
|
@ -207,6 +207,8 @@ export const mockGrants: ServiceGrant[] = [
|
|||
grant("grant_dctouch_task_admins", "service_task_manager", "group", "group_dctouch_admins", "admin"),
|
||||
grant("grant_dctouch_task_managers", "service_task_manager", "group", "group_dctouch_managers", "member"),
|
||||
grant("grant_dctouch_nodedc_admins", "service_nodedc", "group", "group_dctouch_admins", "admin"),
|
||||
grant("grant_engine_user_silver_psih_yahoo_com", "service_nodedc", "user", "user_silver_psih", "member"),
|
||||
grant("grant_engine_user_constr_dc_yahoo_com", "service_nodedc", "user", "user_constr_dc_yahoo_com", "viewer"),
|
||||
];
|
||||
|
||||
export const mockExceptions: ServiceAccessException[] = [];
|
||||
|
|
|
|||
Loading…
Reference in New Issue