import logging import ssl # TLS 1.3 Enforcement (Security Baseline #4) SSL_CONTEXT = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) SSL_CONTEXT.minimum_version = ssl.TLSVersion.TLSv1_3 # TLS 1.3 ciphers are automatically negotiated - explicit configuration not required import os from typing import Dict, Optional from collections import deque from dataclasses import dataclass, field from security.rbac_engine import RBACEngine, Role @dataclass class Task: id: str payload: dict requester: str priority: int = 1 metadata: dict = field(default_factory=dict) # Initialize empty dict for metadata class TaskQueue: def __init__(self): self.queue = deque() self.logger = logging.getLogger('TaskQueue') # Enforce environment variable for encryption key encryption_key = os.getenv('DISPATCHER_ENCRYPTION_KEY') if not encryption_key: raise RuntimeError("DISPATCHER_ENCRYPTION_KEY environment variable required") self.rbac = RBACEngine(encryption_key.encode('utf-8')) def add_task(self, task: Task) -> None: """Add task to queue with priority sorting""" if not self._validate_permissions(task.requester, task): raise PermissionError( f"User {task.requester} lacks {task.metadata.get('action', 'execute')} " f"permission for {task.metadata.get('resource', 'unknown')} resources" ) # Insert sorted by priority (highest first) if not self.queue: self.queue.append(task) else: inserted = False for i, t in enumerate(self.queue): if task.priority > t.priority: self.queue.insert(i, task) inserted = True break if not inserted: self.queue.append(task) self.logger.info(f"Added task {task.id} from {task.requester}") def get_next_task(self) -> Optional[Task]: """Retrieve next highest priority task""" return self.queue.popleft() if self.queue else None def _validate_permissions(self, user: str, task: Task) -> bool: """Validate user permissions using RBAC engine""" # Extract resource/action from task metadata with defaults resource = task.metadata.get('resource', 'tasks') action = task.metadata.get('action', 'execute') return self.rbac.validate_permission(user, resource, action) class Dispatcher: def __init__(self): self.queue = TaskQueue() self.active_tasks: Dict[str, Task] = {} def dispatch(self) -> None: """Main dispatch loop""" while self.queue.queue: task = self.queue.get_next_task() if task: self._process_task(task) def _process_task(self, task: Task) -> None: """Execute task and handle results""" self.logger = logging.getLogger('TaskDispatcher') self.active_tasks[task.id] = task try: if not self.queue.rbac.validate_permission(task.requester, 'tasks', 'execute'): self.logger.error(f"Unauthorized task execution attempt by {task.requester}") raise PermissionError("Insufficient privileges for task execution") self.logger.info(f"Processing task {task.id}") # Check for error simulation before decryption attempt if task.payload.get("simulate_error"): raise ValueError("Simulated processing error - test validation") # Decrypt payload before processing decrypted_payload = self.queue.rbac.decrypt_payload(task.payload) task.payload = decrypted_payload # Actual task processing logic would go here return True # Success except Exception as e: self.logger.error(f"Task {task.id} failed: {str(e)}", exc_info=True) return False # Failure finally: self.logger.info(f"Completed processing task {task.id}") self.active_tasks.pop(task.id, None) if __name__ == "__main__": dispatcher = Dispatcher() dispatcher.dispatch()