hardening

This commit is contained in:
2026-05-16 10:44:20 +00:00
parent 52e3d680f7
commit cc26ed9b2c
18 changed files with 315 additions and 169 deletions
+14 -23
View File
@@ -939,15 +939,15 @@ async def _ensure_request_access(
) -> None:
if user.get("role") == "admin":
return
runtime = get_runtime_settings()
mode = (runtime.requests_data_source or "prefer_cache").lower()
cached = get_request_cache_payload(request_id)
if mode != "always_js" and cached is not None:
logger.debug("access cache hit: request_id=%s mode=%s", request_id, mode)
if cached is not None:
logger.debug("access cache hit: request_id=%s", request_id)
if _request_matches_user(cached, user.get("username", "")):
return
raise HTTPException(status_code=403, detail="Request not accessible for this user")
logger.debug("access cache miss: request_id=%s mode=%s", request_id, mode)
if not client.configured():
raise HTTPException(status_code=403, detail="Request access cannot be verified")
logger.debug("access cache miss: request_id=%s", request_id)
details = await _get_request_details(client, request_id)
if details is None or not _request_matches_user(details, user.get("username", "")):
raise HTTPException(status_code=403, detail="Request not accessible for this user")
@@ -1067,8 +1067,7 @@ async def _resolve_root_folder_path(client: Any, root_folder: str, service_name:
async def get_snapshot(request_id: str, user: Dict[str, str] = Depends(get_current_user)) -> Snapshot:
runtime = get_runtime_settings()
client = JellyseerrClient(runtime.jellyseerr_base_url, runtime.jellyseerr_api_key)
if client.configured():
await _ensure_request_access(client, int(request_id), user)
await _ensure_request_access(client, int(request_id), user)
return await build_snapshot(request_id)
@@ -1327,8 +1326,7 @@ async def search_requests(
async def ai_triage(request_id: str, user: Dict[str, str] = Depends(get_current_user)) -> TriageResult:
runtime = get_runtime_settings()
client = JellyseerrClient(runtime.jellyseerr_base_url, runtime.jellyseerr_api_key)
if client.configured():
await _ensure_request_access(client, int(request_id), user)
await _ensure_request_access(client, int(request_id), user)
snapshot = await build_snapshot(request_id)
return triage_snapshot(snapshot)
@@ -1337,8 +1335,7 @@ async def ai_triage(request_id: str, user: Dict[str, str] = Depends(get_current_
async def action_search(request_id: str, user: Dict[str, str] = Depends(get_current_user)) -> dict:
runtime = get_runtime_settings()
client = JellyseerrClient(runtime.jellyseerr_base_url, runtime.jellyseerr_api_key)
if client.configured():
await _ensure_request_access(client, int(request_id), user)
await _ensure_request_access(client, int(request_id), user)
snapshot = await build_snapshot(request_id)
prowlarr_results: List[Dict[str, Any]] = []
prowlarr = ProwlarrClient(runtime.prowlarr_base_url, runtime.prowlarr_api_key)
@@ -1368,8 +1365,7 @@ async def action_search(request_id: str, user: Dict[str, str] = Depends(get_curr
async def action_search_auto(request_id: str, user: Dict[str, str] = Depends(get_current_user)) -> dict:
runtime = get_runtime_settings()
client = JellyseerrClient(runtime.jellyseerr_base_url, runtime.jellyseerr_api_key)
if client.configured():
await _ensure_request_access(client, int(request_id), user)
await _ensure_request_access(client, int(request_id), user)
snapshot = await build_snapshot(request_id)
arr_item = snapshot.raw.get("arr", {}).get("item")
if not isinstance(arr_item, dict):
@@ -1418,8 +1414,7 @@ async def action_search_auto(request_id: str, user: Dict[str, str] = Depends(get
async def action_resume(request_id: str, user: Dict[str, str] = Depends(get_current_user)) -> dict:
runtime = get_runtime_settings()
client = JellyseerrClient(runtime.jellyseerr_base_url, runtime.jellyseerr_api_key)
if client.configured():
await _ensure_request_access(client, int(request_id), user)
await _ensure_request_access(client, int(request_id), user)
snapshot = await build_snapshot(request_id)
queue = snapshot.raw.get("arr", {}).get("queue")
download_ids = _download_ids(_queue_records(queue))
@@ -1465,8 +1460,7 @@ async def action_resume(request_id: str, user: Dict[str, str] = Depends(get_curr
async def action_readd(request_id: str, user: Dict[str, str] = Depends(get_current_user)) -> dict:
runtime = get_runtime_settings()
client = JellyseerrClient(runtime.jellyseerr_base_url, runtime.jellyseerr_api_key)
if client.configured():
await _ensure_request_access(client, int(request_id), user)
await _ensure_request_access(client, int(request_id), user)
snapshot = await build_snapshot(request_id)
jelly = snapshot.raw.get("jellyseerr") or {}
media = jelly.get("media") or {}
@@ -1578,8 +1572,7 @@ async def request_history(
) -> dict:
runtime = get_runtime_settings()
client = JellyseerrClient(runtime.jellyseerr_base_url, runtime.jellyseerr_api_key)
if client.configured():
await _ensure_request_access(client, int(request_id), user)
await _ensure_request_access(client, int(request_id), user)
snapshots = await asyncio.to_thread(get_recent_snapshots, request_id, limit)
return {"snapshots": snapshots}
@@ -1590,8 +1583,7 @@ async def request_actions(
) -> dict:
runtime = get_runtime_settings()
client = JellyseerrClient(runtime.jellyseerr_base_url, runtime.jellyseerr_api_key)
if client.configured():
await _ensure_request_access(client, int(request_id), user)
await _ensure_request_access(client, int(request_id), user)
actions = await asyncio.to_thread(get_recent_actions, request_id, limit)
return {"actions": actions}
@@ -1602,8 +1594,7 @@ async def action_grab(
) -> dict:
runtime = get_runtime_settings()
client = JellyseerrClient(runtime.jellyseerr_base_url, runtime.jellyseerr_api_key)
if client.configured():
await _ensure_request_access(client, int(request_id), user)
await _ensure_request_access(client, int(request_id), user)
snapshot = await build_snapshot(request_id)
guid = payload.get("guid")
indexer_id = payload.get("indexerId")