АРХ - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: managedBy split Operational Core

This commit is contained in:
DCCONSTRUCTIONS
2026-05-09 12:49:09 +03:00
parent ca9fd34e91
commit 11c8c6fb1b
11 changed files with 227 additions and 16 deletions
@@ -9,7 +9,7 @@ from plane.db.models import ExternalIdentityLink
OIDC_PROVIDER = "authentik"
def get_nodedc_workspace_creation_policy(user):
def get_nodedc_workspace_creation_policy(user, workspace_slug=None):
check_url = (
os.environ.get("PLANE_NODEDC_WORKSPACE_POLICY_URL", "").strip()
or os.environ.get("PLANE_NODEDC_ACCESS_CHECK_URL", "").strip()
@@ -21,6 +21,9 @@ def get_nodedc_workspace_creation_policy(user):
"enabled": False,
"can_create_workspace": True,
"mode": "standalone",
"managed_by": "tasker",
"default_managed_by": "tasker",
"workspaces": [],
"reason": "NODE.DC workspace policy is not configured.",
}
@@ -36,6 +39,9 @@ def get_nodedc_workspace_creation_policy(user):
"enabled": True,
"can_create_workspace": not enforce_unlinked,
"mode": "unlinked",
"managed_by": "tasker",
"default_managed_by": "tasker",
"workspaces": [],
"reason": "NODE.DC identity is not linked." if enforce_unlinked else "Standalone user without NODE.DC identity.",
}
@@ -61,6 +67,9 @@ def get_nodedc_workspace_creation_policy(user):
"enabled": True,
"can_create_workspace": False,
"mode": "unavailable",
"managed_by": "tasker",
"default_managed_by": "tasker",
"workspaces": [],
"reason": "NODE.DC workspace policy is unavailable.",
}
@@ -71,18 +80,84 @@ def get_nodedc_workspace_creation_policy(user):
"enabled": True,
"can_create_workspace": access_allowed,
"mode": "legacy_access_check",
"managed_by": "tasker",
"default_managed_by": "tasker",
"workspaces": [],
"reason": payload.get("reason") or "NODE.DC access check does not expose workspace policy.",
}
can_create_workspace = access_allowed and bool(workspace_policy.get("canCreateWorkspace"))
workspaces = normalize_workspace_management_list(workspace_policy.get("workspaces"))
managed_by = resolve_workspace_managed_by(
workspace_slug=workspace_slug,
workspaces=workspaces,
fallback=workspace_policy.get("managedBy") or workspace_policy.get("defaultManagedBy"),
)
return {
"enabled": True,
"can_create_workspace": can_create_workspace,
"mode": workspace_policy.get("mode") or "unknown",
"managed_by": managed_by,
"default_managed_by": normalize_managed_by(workspace_policy.get("defaultManagedBy") or workspace_policy.get("managedBy")),
"workspaces": workspaces,
"reason": workspace_policy.get("reason") or payload.get("reason") or "NODE.DC workspace policy decision.",
}
def is_truthy(value):
return str(value).strip().lower() in {"1", "true", "yes", "on"}
def normalize_managed_by(value):
return "launcher" if value == "launcher" else "tasker"
def normalize_workspace_management_list(value):
if not isinstance(value, list):
return []
workspaces = []
for item in value:
if not isinstance(item, dict):
continue
slug = item.get("slug")
if not isinstance(slug, str) or not slug.strip():
continue
workspaces.append(
{
"slug": slug.strip(),
"name": item.get("name") if isinstance(item.get("name"), str) and item.get("name").strip() else None,
"managed_by": normalize_managed_by(item.get("managedBy") or item.get("managed_by")),
"client_id": item.get("clientId") if isinstance(item.get("clientId"), str) else None,
"client_name": item.get("clientName") if isinstance(item.get("clientName"), str) else None,
"role": item.get("role") if item.get("role") in {"guest", "member", "admin"} else "member",
}
)
return workspaces
def resolve_workspace_managed_by(workspace_slug, workspaces, fallback):
if isinstance(workspace_slug, str) and workspace_slug.strip():
normalized_slug = workspace_slug.strip()
for workspace in workspaces:
if workspace["slug"] == normalized_slug:
return workspace["managed_by"]
return "tasker"
return normalize_managed_by(fallback)
def is_nodedc_launcher_managed_workspace(user, workspace_slug):
policy = get_nodedc_workspace_creation_policy(user, workspace_slug=workspace_slug)
return bool(policy.get("enabled")) and (
policy.get("managed_by") == "launcher" or policy.get("mode") == "unavailable"
)
def nodedc_launcher_managed_workspace_response():
return {
"error": "nodedc_launcher_managed_workspace",
"reason": "Участниками и ролями этого workspace управляет Launcher.",
}