from __future__ import annotations import hashlib import time from typing import Any class ExecApproval: PENDING_TTL = 300 def __init__(self) -> None: self._pending: dict[str, dict[str, Any]] = {} def create_approval_request( self, chat_guid: str, command: str, context: dict[str, Any] | None = None, ) -> str: request_id = hashlib.sha256(f"{chat_guid}:{command}:{time.monotonic()}".encode()).hexdigest()[:16] self._pending[request_id] = { "chat_guid": chat_guid, "command": command, "context": context or {}, "status": "pending", "created_at": time.monotonic(), } return request_id def approve(self, request_id: str) -> bool: entry = self._pending.get(request_id) if entry is None: return False if entry["status"] != "pending": return False if time.monotonic() - entry["created_at"] > self.PENDING_TTL: del self._pending[request_id] return False entry["status"] = "approved" return True def reject(self, request_id: str) -> bool: entry = self._pending.get(request_id) if entry is None: return False if entry["status"] != "pending": return False entry["status"] = "rejected" return True def get_request(self, request_id: str) -> dict[str, Any] | None: return self._pending.get(request_id) def cleanup(self) -> None: now = time.monotonic() expired = [ k for k, v in self._pending.items() if now - v["created_at"] > self.PENDING_TTL or v["status"] != "pending" ] for k in expired: del self._pending[k]