fix(tasks): gate cookbook serve task execution (#5235)

This commit is contained in:
RaresKeY
2026-07-05 14:19:04 +02:00
committed by GitHub
parent 3592285db7
commit 2826dcfc33
5 changed files with 456 additions and 34 deletions
+47
View File
@@ -0,0 +1,47 @@
"""Shared privilege policy for scheduled task actions."""
from __future__ import annotations
ADMIN_ONLY_TASK_ACTIONS = frozenset({
"run_local",
"run_script",
"ssh_command",
"cookbook_serve",
})
def is_admin_only_task_action(task_type: str | None, action: str | None) -> bool:
return (task_type or "llm") == "action" and (action or "") in ADMIN_ONLY_TASK_ACTIONS
def owner_has_admin_task_privileges(owner: str | None) -> bool:
try:
from src.auth_helpers import _auth_disabled
if _auth_disabled():
return True
except Exception:
pass
if owner:
try:
from core.middleware import INTERNAL_TOOL_USER
if owner == INTERNAL_TOOL_USER:
return True
except Exception:
pass
try:
from core.auth import AuthManager
auth = AuthManager()
if not auth.is_configured:
return True
if not owner:
return False
return bool(auth.is_admin(owner))
except Exception:
pass
if not owner:
return False
return False
+26
View File
@@ -10,6 +10,10 @@ from datetime import datetime, timedelta, timezone
from typing import Any, Awaitable, Callable, Dict, Tuple
from core.auth import RESERVED_USERNAMES
from src.task_action_policy import (
is_admin_only_task_action,
owner_has_admin_task_privileges,
)
logger = logging.getLogger(__name__)
@@ -821,6 +825,28 @@ class TaskScheduler:
db.commit()
return
if (
is_admin_only_task_action(task.task_type, task.action)
and not owner_has_admin_task_privileges(task.owner)
):
msg = f"Action '{task.action}' requires admin privileges"
blocked = db.query(TaskRun).filter(TaskRun.id == run_id).first()
if blocked:
blocked.status = "error"
blocked.result = msg
blocked.error = msg
blocked.finished_at = _utcnow()
task.status = "paused"
task.next_run = None
task.last_run = _utcnow()
logger.warning(
"Paused admin-only task %s for non-admin owner %r",
task_id,
task.owner,
)
db.commit()
return
if gate_foreground:
waiting = db.query(TaskRun).filter(TaskRun.id == run_id).first()
if waiting and waiting.status == "queued":