feat: enforce MCP restart class permissions (#663)
This commit is contained in:
+29
-1
@@ -22342,10 +22342,15 @@ def gitea_request_mcp_restart(
|
||||
request_override: bool = False,
|
||||
session_id: str | None = None,
|
||||
limit: int = 200,
|
||||
restart_class: str = "full_mcp_restart",
|
||||
target_session_id: str | None = None,
|
||||
target_role: str | None = None,
|
||||
target_connector: str | None = None,
|
||||
) -> dict:
|
||||
"""Evaluate a proposed MCP restart and return an impact preview (#658).
|
||||
|
||||
Central restart coordinator: gathers live control-plane state (sessions,
|
||||
Central restart coordinator: resolves the requested restart class, gathers
|
||||
live control-plane state (sessions,
|
||||
leases/locks, in-flight issue/PR work, mutations, worktrees) and returns a
|
||||
blast-radius impact report with a ``safe`` / ``unsafe`` / ``override``
|
||||
verdict, so the console (#642/#652) and operators can see what a restart
|
||||
@@ -22439,6 +22444,9 @@ def gitea_request_mcp_restart(
|
||||
|
||||
profile = get_profile()
|
||||
profile_name = (profile.get("profile_name") or "").strip() or "session"
|
||||
requester_role = (
|
||||
profile.get("role_kind") or profile.get("role") or ""
|
||||
).strip().lower()
|
||||
sid = (session_id or "").strip() or f"{profile_name}-{os.getpid()}"
|
||||
|
||||
# Override authority is read from the environment only — a worker session
|
||||
@@ -22448,6 +22456,15 @@ def gitea_request_mcp_restart(
|
||||
(os.environ.get("GITEA_OPERATOR_RESTART_OVERRIDE_AUTHORIZATION") or "").strip()
|
||||
)
|
||||
operator_override = bool(request_override and operator_authorized)
|
||||
controller_approved = bool(
|
||||
(
|
||||
os.environ.get("GITEA_CONTROLLER_RESTART_APPROVAL_AUTHORIZATION")
|
||||
or ""
|
||||
).strip()
|
||||
)
|
||||
requester_permissions = restart_coordinator.permissions_for_role(
|
||||
requester_role
|
||||
)
|
||||
|
||||
inventory = {
|
||||
"sessions": sessions,
|
||||
@@ -22462,6 +22479,14 @@ def gitea_request_mcp_restart(
|
||||
operator_override=operator_override,
|
||||
requesting_session_id=sid,
|
||||
dry_run=True, # coordinator is always analysis-only (#658)
|
||||
restart_class=restart_class,
|
||||
requester_role=requester_role,
|
||||
requester_permissions=requester_permissions,
|
||||
controller_approved=controller_approved,
|
||||
operator_authorized=operator_authorized,
|
||||
target_session_id=target_session_id,
|
||||
target_role=target_role,
|
||||
target_connector=target_connector,
|
||||
)
|
||||
|
||||
payload = report.as_dict()
|
||||
@@ -22473,6 +22498,9 @@ def gitea_request_mcp_restart(
|
||||
payload["requesting_session_id"] = sid
|
||||
payload["operator_override_requested"] = bool(request_override)
|
||||
payload["operator_override_authorized"] = operator_authorized
|
||||
payload["controller_approval_authorized"] = controller_approved
|
||||
payload["requester_role"] = requester_role
|
||||
payload["requester_permissions"] = list(requester_permissions)
|
||||
payload["apply_supported"] = False
|
||||
if not dry_run:
|
||||
payload["reasons"] = list(payload.get("reasons") or []) + [
|
||||
|
||||
Reference in New Issue
Block a user