Ë
    {Ìj°  ã                   óº   — d Z ddlZddlmZ ddlmZ ddlmZmZ ddl	m
Z
 dddœded	ed
edee   dee   ddfd„Zddedefd„Zdd„Zded	ed
edefd„Zdeddfd„Zy)u•  
rate_limit.py â€” limiteur de tentatives PERSISTANT (MySQL), par clÃ© (ex. IP).

StockÃ© en base et non en mÃ©moire : la fenÃªtre est partagÃ©e entre tous les
workers uvicorn et survit Ã  un redÃ©marrage â€” un attaquant ne peut plus
remettre son compteur Ã  zÃ©ro en provoquant un restart.

    from core.rate_limit import enforce
    enforce(f"photos-lookup:{ip}", max_attempts=20, window_seconds=300)
é    N)ÚOptional)ÚHTTPException)Úget_dbÚ
named_lock)Ú	client_ip)Úaudit_actionÚ
ip_addressÚkeyÚmax_attemptsÚwindow_secondsr   r	   Úreturnc                óÞ  — t        j                   «       }||z
  }t        d| › �«      5  t        «       5 }|j                  d| |f«       |j                  d| f«      j	                  «       d   }||k\  }	|	s|j                  d| |f«       |j                  «        ddd«       ddd«       	r-|rddlm}
 |
j                  ||||d	œd
¬«       t        dd¬«      ‚y# 1 sw Y   ŒAxY w# 1 sw Y   ŒExY w)uŽ   LÃ¨ve HTTPException(429) si `key` a dÃ©passÃ© `max_attempts` dans les
    `window_seconds` derniÃ¨res secondes. Sinon enregistre la tentative.zrate:z*DELETE FROM rate_hits WHERE key=? AND ts<?z/SELECT COUNT(*) AS n FROM rate_hits WHERE key=?Únú,INSERT INTO rate_hits (key, ts) VALUES (?,?)Nr   )Úaudit_service)r   r   Úcritical)r	   ÚdetailsÚseverityi­  u&   Too many attempts â€” try again later.)Údetail)
Útimer   r   ÚexecuteÚfetchoneÚcommitÚservicesr   Ú	log_eventr   )r
   r   r   r   r	   ÚnowÚcutoffÚconnr   Úblockedr   s              ú*/var/www/photos/backend/core/rate_limit.pyÚenforcer!      sø   € ô �)‰)‹+€CØ�>Ñ!€Fä	�e˜C˜5�MÓ	"ñ ¤F£Hð °Ø�‰ÐAÀCÈÀ=ÔQØ�L‰LÐJÈSÈFÓS×\Ñ\Ó^Ð_bÑcˆØ�|Ñ#ˆÙØ�L‰LÐGÈ#ÈsÈÔTØ�‰Œ÷÷ ñ ÙÝ.Ø×#Ñ#Ø¨Ø)5ÈÑXØ#ð $ô ô
 ˜CÐ(PÔQÐQð ÷ð ú÷ ð ús#   ¨C#³A$CÂC#ÃC 	ÃC#Ã#C,Úmax_age_secondsc                 óÊ   — t        «       5 }|j                  dt        j                  «       | z
  f«      }|j                  «        |j                  cd d d «       S # 1 sw Y   y xY w)Nz DELETE FROM rate_hits WHERE ts<?)r   r   r   r   Úrowcount)r"   r   Úcurs      r    Ú	purge_oldr&   /   sM   € Ü	‹ð �TØ�l‰lÐ=ÄÇ	Á	ÃÈoÑ@]Ð?_Ó`ˆØ�‰ŒØ�|‰|÷÷ ò ús   ‹AAÁA"c                  ó„   — t        «       5 } | j                  d«       | j                  «        ddd«       y# 1 sw Y   yxY w)z Vide tous les compteurs (tests).zDELETE FROM rate_hitsN)r   r   r   )r   s    r    Ú	reset_allr(   6   s4   € ä	‹ð �TØ�‰Ð,Ô-Ø�‰Œ÷÷ ñ ús   ‹"6¶?c                 óÊ   — t        j                   «       |z
  }t        «       5 }|j                  d| |f«      j                  «       d   }ddd«       ||k\  S # 1 sw Y   |k\  S xY w)u±   Vrai si `key` a dÃ©jÃ  `max_attempts` Ã©vÃ©nements enregistrÃ©s dans la fenÃªtre.
    Ne compte rien lui-mÃªme : Ã  associer Ã  `record_hit` (ex. n'enregistrer que les Ã©checs).z9SELECT COUNT(*) AS n FROM rate_hits WHERE key=? AND ts>=?r   N)r   r   r   r   )r
   r   r   r   r   r   s         r    Ú
is_blockedr*   =   sk   € ô �Y‰Y‹[˜>Ñ)€FÜ	‹ð u�TØ�L‰LÐTÐWZÐ\bÐVcÓd×mÑmÓoÐpsÑtˆ÷uà�ÑÐ÷uà�ÑÐús   ¢&AÁA"c                 ó®   — t        «       5 }|j                  d| t        j                  «       f«       |j                  «        d d d «       y # 1 sw Y   y xY w)Nr   )r   r   r   r   )r
   r   s     r    Ú
record_hitr,   F   sA   € Ü	‹ð �TØ�‰ÐCÀcÌ4Ï9É9Ë;ÐEWÔXØ�‰Œ÷÷ ñ ús   ‹7AÁA)i€Q )r   N)Ú__doc__r   Útypingr   Úfastapir   Úcore.dbr   r   Úcore.securityr   ÚstrÚintr!   r&   r(   Úboolr*   r,   © ó    r    ú<module>r7      s´   ðñ	ó Ý å !ç &Ý #ð
 &*ÀtòRØ	ðRØðRØ14ðRà˜c‘]ðRà7?À±}ðRð 
óRñ6˜sð ¨só óð�Cð  sð ¸Cð ÀDó ð�Cð ˜Dô r6   