Initial curated Unraid-AppOps-Gateway source from 3bd6f6fee310125bfbb4d4650389a817f498724d
This commit is contained in:
commit
1dfbca08a1
528 files changed
+131054
No files matched your search
@@ -0,0 +1,122 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from typing import Any
|
||||
|
||||
from fastapi import APIRouter, Depends
|
||||
from sqlmodel import Session
|
||||
|
||||
from ..connectors.tautulli import TautulliConnector
|
||||
from ..db.session import get_session
|
||||
from ..services.audit_logger import log_event
|
||||
from ..services.policy_engine import evaluate_policy
|
||||
from .connector_runtime import load_connector_runtime
|
||||
|
||||
router = APIRouter(prefix='/api/apps/tautulli', dependencies=[Depends(load_connector_runtime)])
|
||||
|
||||
|
||||
def _read(
|
||||
session: Session,
|
||||
*,
|
||||
action: str,
|
||||
source: str,
|
||||
risk_default: str,
|
||||
call: Callable[[TautulliConnector], dict[str, Any]],
|
||||
audit_read: bool = False,
|
||||
) -> dict[str, Any]:
|
||||
identity = source.strip() or 'manual'
|
||||
policy = evaluate_policy(session=session, action=action, target='tautulli', source=identity)
|
||||
risk = str(policy.get('risk', risk_default))
|
||||
if policy['decision'] == 'blocked':
|
||||
audit = log_event(
|
||||
session,
|
||||
source='read',
|
||||
identity=identity,
|
||||
action_id=action,
|
||||
target='tautulli',
|
||||
risk=risk,
|
||||
policy_decision='blocked',
|
||||
reason=policy['reason'],
|
||||
result='blocked',
|
||||
redacted_metadata={'privacySensitive': audit_read},
|
||||
)
|
||||
return {'success': False, 'decision': 'blocked', 'status': 'failed', 'message': policy['reason'], 'auditId': audit.id}
|
||||
if policy['decision'] == 'approval_required':
|
||||
audit = log_event(
|
||||
session,
|
||||
source='read',
|
||||
identity=identity,
|
||||
action_id=action,
|
||||
target='tautulli',
|
||||
risk=risk,
|
||||
policy_decision='approval_required',
|
||||
reason=policy['reason'],
|
||||
result='approval_required',
|
||||
redacted_metadata={'privacySensitive': audit_read},
|
||||
)
|
||||
return {'success': False, 'decision': 'approval_required', 'status': 'failed', 'message': 'Action requires approval before execution.', 'auditId': audit.id}
|
||||
result = call(TautulliConnector())
|
||||
if audit_read:
|
||||
log_event(
|
||||
session,
|
||||
source='read',
|
||||
identity=identity,
|
||||
action_id=action,
|
||||
target='tautulli',
|
||||
risk=risk,
|
||||
policy_decision='allowed',
|
||||
reason=policy['reason'],
|
||||
result='success' if result.get('success') else 'failed',
|
||||
redacted_metadata={'privacySensitive': True, 'status': result.get('status')},
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
@router.get('/health')
|
||||
def health():
|
||||
return TautulliConnector().health()
|
||||
|
||||
|
||||
@router.get('/status')
|
||||
def status():
|
||||
return TautulliConnector().status()
|
||||
|
||||
|
||||
@router.get('/activity')
|
||||
def activity():
|
||||
return TautulliConnector().activity()
|
||||
|
||||
|
||||
@router.get('/history')
|
||||
def history(limit: int = 25, source: str = 'manual', session: Session = Depends(get_session)):
|
||||
return _read(session, action='tautulli.history', source=source, risk_default='medium', call=lambda connector: connector.history(limit), audit_read=True)
|
||||
|
||||
|
||||
@router.get('/users')
|
||||
def users(source: str = 'manual', session: Session = Depends(get_session)):
|
||||
return _read(session, action='tautulli.users', source=source, risk_default='medium', call=lambda connector: connector.users(), audit_read=True)
|
||||
|
||||
|
||||
@router.get('/libraries')
|
||||
def libraries():
|
||||
return TautulliConnector().libraries()
|
||||
|
||||
|
||||
@router.get('/recently-added')
|
||||
def recently_added():
|
||||
return TautulliConnector().recently_added()
|
||||
|
||||
|
||||
@router.get('/watch-stats')
|
||||
def watch_stats(source: str = 'manual', session: Session = Depends(get_session)):
|
||||
return _read(session, action='tautulli.watch_stats', source=source, risk_default='medium', call=lambda connector: connector.watch_stats(), audit_read=True)
|
||||
|
||||
|
||||
@router.get('/streams')
|
||||
def streams():
|
||||
return TautulliConnector().stream_summary()
|
||||
|
||||
|
||||
@router.get('/plex-info')
|
||||
def plex_info():
|
||||
return TautulliConnector().plex_info()
|
||||
Reference in new issue
Block a user