mirror of
https://github.com/smittix/intercept.git
synced 2026-04-29 09:09:59 -07:00
Add drone ops mode and retire DMR support
This commit is contained in:
74
utils/authz.py
Normal file
74
utils/authz.py
Normal file
@@ -0,0 +1,74 @@
|
||||
"""Authorization helpers for role-based and arming-gated operations."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from functools import wraps
|
||||
from typing import Any, Callable
|
||||
|
||||
from flask import jsonify, session
|
||||
|
||||
ROLE_LEVELS: dict[str, int] = {
|
||||
'viewer': 10,
|
||||
'analyst': 20,
|
||||
'operator': 30,
|
||||
'supervisor': 40,
|
||||
'admin': 50,
|
||||
}
|
||||
|
||||
|
||||
def current_username() -> str:
|
||||
"""Get current username from session."""
|
||||
return str(session.get('username') or 'anonymous')
|
||||
|
||||
|
||||
def current_role() -> str:
|
||||
"""Get current role from session with safe default."""
|
||||
role = str(session.get('role') or 'viewer').strip().lower()
|
||||
return role if role in ROLE_LEVELS else 'viewer'
|
||||
|
||||
|
||||
def has_role(required_role: str) -> bool:
|
||||
"""Return True if current session role satisfies required role."""
|
||||
required = ROLE_LEVELS.get(required_role, ROLE_LEVELS['admin'])
|
||||
actual = ROLE_LEVELS.get(current_role(), ROLE_LEVELS['viewer'])
|
||||
return actual >= required
|
||||
|
||||
|
||||
def require_role(required_role: str) -> Callable:
|
||||
"""Decorator enforcing minimum role."""
|
||||
|
||||
def decorator(func: Callable) -> Callable:
|
||||
@wraps(func)
|
||||
def wrapper(*args: Any, **kwargs: Any):
|
||||
if not has_role(required_role):
|
||||
return jsonify({
|
||||
'status': 'error',
|
||||
'message': f'{required_role} role required',
|
||||
'required_role': required_role,
|
||||
'current_role': current_role(),
|
||||
}), 403
|
||||
return func(*args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
def require_armed(func: Callable) -> Callable:
|
||||
"""Decorator enforcing armed state for active actions."""
|
||||
|
||||
@wraps(func)
|
||||
def wrapper(*args: Any, **kwargs: Any):
|
||||
from utils.drone import get_drone_ops_service
|
||||
|
||||
service = get_drone_ops_service()
|
||||
policy = service.get_policy_state()
|
||||
if not policy.get('armed'):
|
||||
return jsonify({
|
||||
'status': 'error',
|
||||
'message': 'Action plane is not armed',
|
||||
'policy': policy,
|
||||
}), 403
|
||||
return func(*args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
Reference in New Issue
Block a user