FEAT - LAUNCHER: выдача service module entitlement в access check

This commit is contained in:
DCCONSTRUCTIONS 2026-05-14 20:40:40 +03:00
parent 34917e007a
commit 0782e13c77
1 changed files with 27 additions and 2 deletions

View File

@ -423,8 +423,11 @@ app.post("/api/internal/access/check", (req, res) => {
const groups = resolveRequiredGroups(snapshot.data, user);
const app = getAppsForUser(groups).find((candidate) => candidate.slug === serviceSlug);
const allowed = Boolean(app?.hasAccess);
const serviceModules = resolveUserServiceModules(snapshot.data, user, serviceSlug);
const workspacePolicy =
serviceSlug === "task-manager" ? resolveTaskManagerWorkspacePolicy(snapshot.data, groups, allowed, user) : null;
serviceSlug === "task-manager"
? resolveTaskManagerWorkspacePolicy(snapshot.data, groups, allowed, user, null, serviceModules)
: null;
res.json({
ok: true,
@ -433,6 +436,7 @@ app.post("/api/internal/access/check", (req, res) => {
serviceSlug,
groups,
matchedGroups: app?.matchedGroups ?? [],
serviceModules,
workspacePolicy,
user: {
id: user.id,
@ -2390,7 +2394,7 @@ function pruneExpiredServiceHandoffs() {
}
}
function resolveTaskManagerWorkspacePolicy(data, groups, hasTaskManagerAccess, user, workspaceSlug = null) {
function resolveTaskManagerWorkspacePolicy(data, groups, hasTaskManagerAccess, user, workspaceSlug = null, serviceModules = {}) {
const mode = data.settings?.taskManager?.workspaceCreationPolicy ?? "any_authorized_user";
const groupSet = new Set(groups);
const isSuperAdmin = groupSet.has("nodedc:superadmin");
@ -2415,6 +2419,7 @@ function resolveTaskManagerWorkspacePolicy(data, groups, hasTaskManagerAccess, u
inviteApproval: "disabled",
defaultInviteApproval,
workspaces,
serviceModules,
canCreateWorkspace: false,
reason: "Нет доступа к Operational Core.",
};
@ -2428,6 +2433,7 @@ function resolveTaskManagerWorkspacePolicy(data, groups, hasTaskManagerAccess, u
inviteApproval: "disabled",
defaultInviteApproval,
workspaces,
serviceModules,
canCreateWorkspace: false,
reason: "Создание рабочих пространств отключено на уровне платформы.",
};
@ -2442,6 +2448,7 @@ function resolveTaskManagerWorkspacePolicy(data, groups, hasTaskManagerAccess, u
inviteApproval: "launcher",
defaultInviteApproval: "launcher",
workspaces,
serviceModules,
canCreateWorkspace: false,
reason: "Рабочие пространства этого пользователя управляются через Launcher.",
};
@ -2455,6 +2462,7 @@ function resolveTaskManagerWorkspacePolicy(data, groups, hasTaskManagerAccess, u
inviteApproval: defaultInviteApproval,
defaultInviteApproval,
workspaces,
serviceModules,
canCreateWorkspace: false,
reason: "Self-service workspace работает через Tasker, approve инвайтов выполняет Launcher.",
};
@ -2467,6 +2475,7 @@ function resolveTaskManagerWorkspacePolicy(data, groups, hasTaskManagerAccess, u
inviteApproval: "launcher",
defaultInviteApproval: "launcher",
workspaces,
serviceModules,
canCreateWorkspace: false,
reason: "Рабочие пространства этого пользователя управляются через Launcher.",
};
@ -2480,6 +2489,7 @@ function resolveTaskManagerWorkspacePolicy(data, groups, hasTaskManagerAccess, u
inviteApproval: defaultInviteApproval,
defaultInviteApproval,
workspaces,
serviceModules,
canCreateWorkspace: false,
reason: "Создание рабочих пространств доступно только администраторам Operational Core.",
};
@ -2492,11 +2502,26 @@ function resolveTaskManagerWorkspacePolicy(data, groups, hasTaskManagerAccess, u
inviteApproval: defaultInviteApproval,
defaultInviteApproval,
workspaces,
serviceModules,
canCreateWorkspace: true,
reason: "Создание рабочих пространств разрешено платформенной policy.",
};
}
function resolveUserServiceModules(data, user, serviceSlug) {
if (!user?.id) return {};
const service = data.services.find(
(candidate) => candidate.slug === serviceSlug || candidate.authentikApplicationSlug === serviceSlug
);
if (!service?.id) return {};
return Object.fromEntries(
(data.serviceModuleEntitlements ?? [])
.filter((entitlement) => entitlement.userId === user.id && entitlement.serviceId === service.id && entitlement.enabled)
.map((entitlement) => [entitlement.moduleId, true])
);
}
function getFrontchannelLogoutUrls() {
const urls = [config.taskLogoutUrl];
const launcherData = readLauncherData();