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