fix: sécuriser watchlist, favorites, downloads et recommendations sans auth (#15)

- router_favorites.py: toutes les routes requièrent maintenant l'auth
  - GET utilise get_optional_user + login_prompt.html pour HTMX
  - POST/DELETE/toggle requièrent get_current_user_from_token
  - Filtrage par user_id dans toutes les requêtes favorites
- router_downloads.py: GET list et GET status protégés (401 sans token)
- router_recommendations.py: GET protégé (login_prompt HTMX, 401 JSON)
- router_sonarr.py: tous les endpoints de gestion protégés
  - Webhooks restent publics (reçus de Sonarr)
- app/favorites.py: ajout du paramètre user_id à toutes les méthodes

Closes #15
This commit is contained in:
root
2026-04-02 22:20:29 +00:00
parent c0f9c0c1c4
commit 5d264d8f3b
5 changed files with 154 additions and 45 deletions
+26 -6
View File
@@ -68,14 +68,19 @@ async def test_sonarr_webhook(request: Request):
@router.get("/sonarr/config")
async def get_sonarr_config():
async def get_sonarr_config(
current_user: User = Depends(get_current_user_from_token),
):
"""Get Sonarr webhook configuration"""
sonarr_handler = get_sonarr_handler()
return sonarr_handler.get_config()
@router.put("/sonarr/config")
async def update_sonarr_config(config: SonarrConfig):
async def update_sonarr_config(
config: SonarrConfig,
current_user: User = Depends(get_current_user_from_token),
):
"""Update Sonarr webhook configuration"""
sonarr_handler = get_sonarr_handler()
try:
@@ -87,14 +92,19 @@ async def update_sonarr_config(config: SonarrConfig):
@router.get("/sonarr/mappings")
async def get_sonarr_mappings():
async def get_sonarr_mappings(
current_user: User = Depends(get_current_user_from_token),
):
"""Get all Sonarr to anime mappings"""
sonarr_handler = get_sonarr_handler()
return sonarr_handler.get_mappings()
@router.get("/sonarr/mappings/{series_id}")
async def get_sonarr_mapping(series_id: int):
async def get_sonarr_mapping(
series_id: int,
current_user: User = Depends(get_current_user_from_token),
):
"""Get specific mapping by Sonarr series ID"""
sonarr_handler = get_sonarr_handler()
mapping = sonarr_handler.get_mapping(series_id)
@@ -104,7 +114,10 @@ async def get_sonarr_mapping(series_id: int):
@router.post("/sonarr/mappings")
async def create_sonarr_mapping(mapping: SonarrMapping):
async def create_sonarr_mapping(
mapping: SonarrMapping,
current_user: User = Depends(get_current_user_from_token),
):
"""Create or update a Sonarr to anime mapping"""
sonarr_handler = get_sonarr_handler()
try:
@@ -116,7 +129,10 @@ async def create_sonarr_mapping(mapping: SonarrMapping):
@router.delete("/sonarr/mappings/{series_id}")
async def delete_sonarr_mapping(series_id: int):
async def delete_sonarr_mapping(
series_id: int,
current_user: User = Depends(get_current_user_from_token),
):
"""Delete a Sonarr mapping"""
sonarr_handler = get_sonarr_handler()
success = sonarr_handler.delete_mapping(series_id)
@@ -130,6 +146,7 @@ async def search_anime_for_sonarr(
q: str = Query(..., description="Series title to search"),
provider: str = Query("anime-sama", description="Anime provider to search"),
lang: str = Query("vostfr", description="Language (vostfr, vf)"),
current_user: User = Depends(get_current_user_from_token),
):
"""Search for anime on providers to create Sonarr mappings"""
sonarr_handler = get_sonarr_handler()
@@ -152,6 +169,7 @@ async def get_anime_episodes(
url: str = Query(..., description="Anime URL from provider"),
provider: str = Query("anime-sama", description="Anime provider"),
lang: str = Query("vostfr", description="Language (vostfr, vf)"),
current_user: User = Depends(get_current_user_from_token),
):
"""Get episode list for anime"""
sonarr_handler = get_sonarr_handler()
@@ -174,6 +192,7 @@ async def suggest_anime_mapping(
sonarr_title: str = Query(..., description="Sonarr series title"),
provider: str = Query("anime-sama", description="Anime provider"),
lang: str = Query("vostfr", description="Language"),
current_user: User = Depends(get_current_user_from_token),
):
"""Suggest possible anime mappings based on Sonarr series title"""
sonarr_handler = get_sonarr_handler()
@@ -195,6 +214,7 @@ async def suggest_anime_mapping(
async def trigger_sonarr_download(
request: SonarrDownloadRequest,
background_tasks: BackgroundTasks,
current_user: User = Depends(get_current_user_from_token),
):
"""Manually trigger a download based on Sonarr information"""
from main import download_manager