mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-08-04 18:46:07 +00:00
404e3466d9
* feat(cloud): add scoped support admin sessions * style(web): format support admin session changes * fix(cloud): isolate support adapter sessions * fix(cloud): authenticate plugin assets and report workspace resources --------- Co-authored-by: dadachann <185672915+dadachann@users.noreply.github.com>
98 lines
2.6 KiB
Python
98 lines
2.6 KiB
Python
from __future__ import annotations
|
|
|
|
import dataclasses
|
|
import enum
|
|
|
|
|
|
class PrincipalType(enum.StrEnum):
|
|
"""Kinds of authenticated principals accepted by LangBot."""
|
|
|
|
ACCOUNT = 'account'
|
|
API_KEY = 'api_key'
|
|
SUPPORT_ADMIN = 'support_admin'
|
|
SYSTEM = 'system'
|
|
PUBLIC_BOT = 'public_bot'
|
|
|
|
|
|
@dataclasses.dataclass(frozen=True, slots=True)
|
|
class PrincipalContext:
|
|
"""Authenticated identity before Workspace authorization is applied."""
|
|
|
|
principal_type: PrincipalType
|
|
account_uuid: str | None = None
|
|
actor_account_uuid: str | None = None
|
|
api_key_uuid: str | None = None
|
|
support_session_id: str | None = None
|
|
|
|
|
|
@dataclasses.dataclass(frozen=True, slots=True)
|
|
class WorkspaceContext:
|
|
"""Workspace membership and effective permissions for one request."""
|
|
|
|
workspace_uuid: str
|
|
membership_uuid: str | None
|
|
role: str | None
|
|
permissions: frozenset[str]
|
|
membership_revision: int = 0
|
|
|
|
|
|
@dataclasses.dataclass(frozen=True, slots=True)
|
|
class RequestContext:
|
|
"""Trusted authorization context passed to HTTP services."""
|
|
|
|
instance_uuid: str
|
|
placement_generation: int
|
|
request_id: str
|
|
auth_type: str
|
|
principal: PrincipalContext
|
|
workspace: WorkspaceContext
|
|
entitlement_revision: int = 0
|
|
|
|
@property
|
|
def workspace_uuid(self) -> str:
|
|
"""Return the selected Workspace UUID."""
|
|
|
|
return self.workspace.workspace_uuid
|
|
|
|
@property
|
|
def account_uuid(self) -> str | None:
|
|
"""Return the Account UUID when the principal is an Account."""
|
|
|
|
return self.principal.account_uuid
|
|
|
|
|
|
@dataclasses.dataclass(frozen=True, slots=True)
|
|
class ExecutionContext:
|
|
"""Workspace context propagated to asynchronous and runtime work."""
|
|
|
|
instance_uuid: str
|
|
workspace_uuid: str
|
|
placement_generation: int
|
|
bot_uuid: str | None = None
|
|
pipeline_uuid: str | None = None
|
|
query_uuid: str | None = None
|
|
trigger_principal: PrincipalContext | None = None
|
|
entitlement_revision: int = 0
|
|
|
|
@classmethod
|
|
def from_request(
|
|
cls,
|
|
ctx: RequestContext,
|
|
*,
|
|
bot_uuid: str | None = None,
|
|
pipeline_uuid: str | None = None,
|
|
query_uuid: str | None = None,
|
|
) -> ExecutionContext:
|
|
"""Create a runtime context without losing the tenant generation."""
|
|
|
|
return cls(
|
|
instance_uuid=ctx.instance_uuid,
|
|
workspace_uuid=ctx.workspace_uuid,
|
|
placement_generation=ctx.placement_generation,
|
|
bot_uuid=bot_uuid,
|
|
pipeline_uuid=pipeline_uuid,
|
|
query_uuid=query_uuid,
|
|
trigger_principal=ctx.principal,
|
|
entitlement_revision=ctx.entitlement_revision,
|
|
)
|