ФУНКЦИИ - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: policy создания workspace в Launcher

This commit is contained in:
DCCONSTRUCTIONS
2026-05-06 09:38:14 +03:00
parent 168010f05e
commit 6b002ec176
4 changed files with 126 additions and 4 deletions
+16 -1
View File
@@ -29,6 +29,9 @@ const defaultSettings = {
brand: {
logoLinkUrl: "/",
},
taskManager: {
workspaceCreationPolicy: "any_authorized_user",
},
};
export function createControlPlaneStore({ projectRoot }) {
@@ -195,6 +198,10 @@ export function createControlPlaneStore({ projectRoot }) {
...(data.settings?.brand ?? {}),
...(patch.brand ?? {}),
},
taskManager: {
...(data.settings?.taskManager ?? {}),
...(patch.taskManager ?? {}),
},
});
data.settings = settings;
@@ -203,7 +210,7 @@ export function createControlPlaneStore({ projectRoot }) {
objectType: "settings",
objectName: "Brand settings",
result: "success",
details: `Logo link: ${settings.brand.logoLinkUrl}`,
details: `Logo link: ${settings.brand.logoLinkUrl}; Tasker workspace policy: ${settings.taskManager.workspaceCreationPolicy}`,
});
await writeData(data);
@@ -1051,11 +1058,19 @@ function normalizeData(payload) {
function normalizeSettings(payload) {
const settings = typeof payload === "object" && payload !== null ? payload : {};
const brand = typeof settings.brand === "object" && settings.brand !== null ? settings.brand : {};
const taskManager = typeof settings.taskManager === "object" && settings.taskManager !== null ? settings.taskManager : {};
return {
brand: {
logoLinkUrl: optionalString(brand.logoLinkUrl, defaultSettings.brand.logoLinkUrl),
},
taskManager: {
workspaceCreationPolicy: pickEnum(
taskManager.workspaceCreationPolicy,
new Set(["any_authorized_user", "task_admins_only", "disabled"]),
defaultSettings.taskManager.workspaceCreationPolicy
),
},
};
}
+40
View File
@@ -373,6 +373,8 @@ 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 workspacePolicy =
serviceSlug === "task-manager" ? resolveTaskManagerWorkspacePolicy(snapshot.data, groups, allowed) : null;
res.json({
ok: true,
@@ -381,6 +383,7 @@ app.post("/api/internal/access/check", (req, res) => {
serviceSlug,
groups,
matchedGroups: app?.matchedGroups ?? [],
workspacePolicy,
user: {
id: user.id,
email: user.email,
@@ -1234,6 +1237,43 @@ function pruneExpiredServiceHandoffs() {
}
}
function resolveTaskManagerWorkspacePolicy(data, groups, hasTaskManagerAccess) {
const mode = data.settings?.taskManager?.workspaceCreationPolicy ?? "any_authorized_user";
const groupSet = new Set(groups);
const isSuperAdmin = groupSet.has("nodedc:superadmin");
const isTaskManagerAdmin = groupSet.has("nodedc:taskmanager:admin");
if (!hasTaskManagerAccess) {
return {
mode,
canCreateWorkspace: false,
reason: "Нет доступа к Operational Core.",
};
}
if (mode === "disabled") {
return {
mode,
canCreateWorkspace: false,
reason: "Создание рабочих пространств отключено на уровне платформы.",
};
}
if (mode === "task_admins_only" && !isSuperAdmin && !isTaskManagerAdmin) {
return {
mode,
canCreateWorkspace: false,
reason: "Создание рабочих пространств доступно только администраторам Operational Core.",
};
}
return {
mode,
canCreateWorkspace: true,
reason: "Создание рабочих пространств разрешено платформенной policy.",
};
}
function getFrontchannelLogoutUrls() {
const urls = [config.taskLogoutUrl];
const launcherData = readLauncherData();