ФУНКЦИИ - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: backend enforcement workspace policy
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
import os
|
||||
|
||||
import requests
|
||||
|
||||
from plane.authentication.views.nodedc_logout import get_nodedc_internal_token
|
||||
from plane.db.models import ExternalIdentityLink
|
||||
|
||||
|
||||
OIDC_PROVIDER = "authentik"
|
||||
|
||||
|
||||
def get_nodedc_workspace_creation_policy(user):
|
||||
check_url = (
|
||||
os.environ.get("PLANE_NODEDC_WORKSPACE_POLICY_URL", "").strip()
|
||||
or os.environ.get("PLANE_NODEDC_ACCESS_CHECK_URL", "").strip()
|
||||
)
|
||||
token = get_nodedc_internal_token()
|
||||
|
||||
if not check_url or not token:
|
||||
return {
|
||||
"enabled": False,
|
||||
"can_create_workspace": True,
|
||||
"mode": "standalone",
|
||||
"reason": "NODE.DC workspace policy is not configured.",
|
||||
}
|
||||
|
||||
link = ExternalIdentityLink.objects.filter(
|
||||
provider=OIDC_PROVIDER,
|
||||
user=user,
|
||||
status=ExternalIdentityLink.Status.ACTIVE,
|
||||
).first()
|
||||
|
||||
if link is None:
|
||||
enforce_unlinked = is_truthy(os.environ.get("PLANE_NODEDC_WORKSPACE_POLICY_ENFORCE_UNLINKED", "0"))
|
||||
return {
|
||||
"enabled": True,
|
||||
"can_create_workspace": not enforce_unlinked,
|
||||
"mode": "unlinked",
|
||||
"reason": "NODE.DC identity is not linked." if enforce_unlinked else "Standalone user without NODE.DC identity.",
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.post(
|
||||
check_url,
|
||||
json={
|
||||
"serviceSlug": os.environ.get("PLANE_NODEDC_ACCESS_SERVICE_SLUG", "task-manager"),
|
||||
"subject": link.subject,
|
||||
"email": link.email or user.email,
|
||||
"userId": None,
|
||||
},
|
||||
headers={
|
||||
"Authorization": f"Bearer {token}",
|
||||
"Accept": "application/json",
|
||||
},
|
||||
timeout=float(os.environ.get("PLANE_NODEDC_WORKSPACE_POLICY_TIMEOUT_SECONDS", "3") or "3"),
|
||||
)
|
||||
response.raise_for_status()
|
||||
payload = response.json()
|
||||
except (ValueError, requests.RequestException):
|
||||
return {
|
||||
"enabled": True,
|
||||
"can_create_workspace": False,
|
||||
"mode": "unavailable",
|
||||
"reason": "NODE.DC workspace policy is unavailable.",
|
||||
}
|
||||
|
||||
workspace_policy = payload.get("workspacePolicy") if isinstance(payload.get("workspacePolicy"), dict) else {}
|
||||
access_allowed = bool(payload.get("allowed"))
|
||||
if not workspace_policy:
|
||||
return {
|
||||
"enabled": True,
|
||||
"can_create_workspace": access_allowed,
|
||||
"mode": "legacy_access_check",
|
||||
"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"))
|
||||
|
||||
return {
|
||||
"enabled": True,
|
||||
"can_create_workspace": can_create_workspace,
|
||||
"mode": workspace_policy.get("mode") or "unknown",
|
||||
"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"}
|
||||
Reference in New Issue
Block a user