§
    óÇãi$  ã                   ó$  — d dl m Z mZmZ d dlmZmZ d dlmZmZ d dl	m
Z
 d dlmZmZmZmZmZ d dlmZ d dlmZ dd	lmZ dd
lmZ ddlmZ ddlmZmZ ddlmZm Z   e
dgd¬¦  «        Z! edd¬¦  «        Z"dedee#         fd„Z$ ed¦  «        dfdee#         dee#         de#fd„Z%de#de#de&fd„Z'de#de#fd„Z(d4d e)d!ee         de#fd"„Z*d e)de#fd#„Z+ ee¦  «        fded$edefd%„Z, ee,¦  «        fd&edefd'„Z- ee-¦  «        fd&edefd(„Z. ee-¦  «        fd&edefd)„Z/ ee-¦  «        fd&edefd*„Z0 ee-¦  «        fd&edefd+„Z1 ee¦  «        fded$edee         fd,„Z2d-ed$edee#         fd.„Z3d-ed/e#d$ede&fd0„Z4d/e#fd1„Z5d2ee#         fd3„Z6dS )5é    )ÚdatetimeÚ	timedeltaÚtimezone)ÚOptionalÚList)ÚJWTErrorÚjwt)ÚCryptContext)ÚDependsÚHTTPExceptionÚstatusÚRequestÚHeader)ÚOAuth2PasswordBearer)ÚSessioné   )Úsettings)Úget_db)ÚUser)Ú
PermissionÚRolePermission)Úget_supported_languagesÚDEFAULT_LANGUAGEÚargon2Úauto)ÚschemesÚ
deprecatedzapi/auth/loginF)ÚtokenUrlÚ
auto_errorÚrequestÚreturnc                 ó6   — | j                              d¦  «        S )z%Get access token from HttpOnly cookieÚaccess_token)ÚcookiesÚget)r    s    ú/app/app/auth.pyÚget_token_from_cookier'      s   € àŒ?×Ò˜~Ñ.Ô.Ð.ó    NÚaccept_languageÚlangc              ƒ   óP  K  — |r|t          ¦   «         v r|S | rˆ|                      d¦  «        }|D ]p}|                     d¦  «        d                              ¦   «         }|                     d¦  «        d                              ¦   «         }|t          ¦   «         v r|c S Œqt          S )a(  
    Get the preferred language from Accept-Language header or query parameter.
    
    Args:
        accept_language: Accept-Language header (e.g., "de-DE,de;q=0.9,en;q=0.8")
        lang: Language query parameter (e.g., "de")
    
    Returns:
        The language code (e.g., "de", "en")
    ú,ú;r   ú-)r   ÚsplitÚstripÚlowerr   )r)   r*   Ú	languagesÚ	lang_pairÚ	lang_partÚ	lang_codes         r&   Úget_languager6      sÁ   è è € ð ð �Õ/Ñ1Ô1Ð1Ð1Øˆàð 
!ð $×)Ò)¨#Ñ.Ô.ˆ	Ø"ð 	!ð 	!ˆIà!Ÿš¨Ñ,Ô,¨QÔ/×5Ò5Ñ7Ô7ˆIà!Ÿš¨Ñ,Ô,¨QÔ/×5Ò5Ñ7Ô7ˆIØÕ3Ñ5Ô5Ð5Ð5Ø Ð Ð Ð ð 6õ Ðr(   Úplain_passwordÚhashed_passwordc                 ó8   — t                                | |¦  «        S ©N)Úpwd_contextÚverify)r7   r8   s     r&   Úverify_passwordr=   8   s   € Ý×Ò˜n¨oÑ>Ô>Ð>r(   Úpasswordc                 ó6   — t                                | ¦  «        S r:   )r;   Úhash)r>   s    r&   Úget_password_hashrA   <   s   € Ý×Ò˜HÑ%Ô%Ð%r(   ÚdataÚexpires_deltac                 ól  — |                       ¦   «         }|r"t          j        t          j        ¦  «        |z   }n9t          j        t          j        ¦  «        t          t          j        ¬¦  «        z   }|                     d|i¦  «         t          j
        |t          j        t          j        ¬¦  «        }|S )N)ÚminutesÚexp©Ú	algorithm)Úcopyr   Únowr   Úutcr   r   ÚJWT_ACCESS_TOKEN_EXPIRE_MINUTESÚupdater	   ÚencodeÚJWT_SECRET_KEYÚJWT_ALGORITHM)rB   rC   Ú	to_encodeÚexpireÚencoded_jwts        r&   Úcreate_access_tokenrT   @   sŽ   € Ø—	’	‘”€IØð jÝ”�hœlÑ+Ô+¨mÑ;ˆˆå”�hœlÑ+Ô+­iÅÔ@hÐ.iÑ.iÔ.iÑiˆØ×Ò�e˜V�_Ñ%Ô%Ð%Ý”*˜Y­Ô(?Í8ÔKaÐbÑbÔb€KØÐr(   c                 ó&  — |                       ¦   «         }t          j        t          j        ¦  «        t          t          j        ¬¦  «        z   }|                     |ddœ¦  «         t          j
        |t          j        t          j        ¬¦  «        }|S )N)ÚdaysÚrefresh)rF   ÚtyperG   )rI   r   rJ   r   rK   r   r   ÚJWT_REFRESH_TOKEN_EXPIRE_DAYSrM   r	   rN   rO   rP   )rB   rQ   rR   rS   s       r&   Úcreate_refresh_tokenrZ   K   sq   € Ø—	’	‘”€IÝŒ\�(œ,Ñ'Ô'­)½Ô9_Ð*`Ñ*`Ô*`Ñ`€FØ×Ò˜V¨YÐ7Ð7Ñ8Ô8Ð8Ý”*˜Y­Ô(?Í8ÔKaÐbÑbÔb€KØÐr(   Údbc              ƒ   óê  K  — t          t          j        dddi¬¦  «        }t          | ¦  «        }|st	          | ¦  «        ƒ d {V —†}|s|‚	 t          j        |t          j        t          j	        g¬¦  «        }| 
                    d¦  «        }|€|‚n# t          $ r |‚w xY w|                     t          ¦  «                             t          j        |k    ¦  «                             ¦   «         }|€|‚|S )NzCould not validate credentialszWWW-AuthenticateÚBearer)Ústatus_codeÚdetailÚheaders©Ú
algorithmsÚsub)r   r   ÚHTTP_401_UNAUTHORIZEDr'   Úoauth2_schemer	   Údecoder   rO   rP   r%   r   Úqueryr   ÚfilterÚidÚfirst)r    r[   Úcredentials_exceptionÚtokenÚpayloadÚuser_idÚusers          r&   Úget_current_userrp   S   s  è è € õ *ÝÔ0Ø/Ø# XÐ.ðñ ô Ðõ " 'Ñ*Ô*€Eð ð -Ý# GÑ,Ô,Ð,Ð,Ð,Ð,Ð,Ð,ˆàð $Ø#Ð#ð$Ý”*˜U¥HÔ$;ÍÔI_ÐH`ÐaÑaÔaˆØ—{’{ 5Ñ)Ô)ˆØˆ?Ø'Ð'ð øåð $ð $ð $Ø#Ð#ð$øøøð �8Š8•D‰>Œ>× Ò ¥¤¨GÒ!3Ñ4Ô4×:Ò:Ñ<Ô<€DØ€|Ø#Ð#Ø€Ks   ÁAB ÂBÚcurrent_userc              ƒ   ó:   K  — | j         st          dd¬¦  «        ‚| S )Ni�  zInactive user©r^   r_   )Ú	is_activer   ©rq   s    r&   Úget_current_active_userrv   u   s-   è è € ð Ô!ð EÝ¨°OÐDÑDÔDÐDØÐr(   c              ƒ   ó¤   K  — | j         st          t          j        d¬¦  «        ‚| j        j        dk    rt          t          j        d¬¦  «        ‚| S )NúNo role assignedrs   ÚadminzAdmin access required©Úrole_idr   r   ÚHTTP_403_FORBIDDENÚroleÚnameru   s    r&   Úget_current_admin_userr   }   sn   è è € ð Ôð 
ÝÝÔ1Ø%ð
ñ 
ô 
ð 	
ð ÔÔ Ò(Ð(ÝÝÔ1Ø*ð
ñ 
ô 
ð 	
ð Ðr(   c              ƒ   ó    K  — | j         st          t          j        d¬¦  «        ‚| j        j        dvrt          t          j        d¬¦  «        ‚| S )Nrx   rs   )Úmodry   zModerator access requiredrz   ru   s    r&   Úget_current_mod_userr‚   �   so   è è € ð Ôð 
ÝÝÔ1Ø%ð
ñ 
ô 
ð 	
ð ÔÔÐ%5Ð5Ð5ÝÝÔ1Ø.ð
ñ 
ô 
ð 	
ð Ðr(   c              ƒ   ó    K  — | j         st          t          j        d¬¦  «        ‚| j        j        dvrt          t          j        d¬¦  «        ‚| S )Nrx   rs   )Úcreatorry   zCreator access requiredrz   ru   s    r&   Úget_current_creator_userr…   �   so   è è € ð Ôð 
ÝÝÔ1Ø%ð
ñ 
ô 
ð 	
ð ÔÔÐ%9Ð9Ð9ÝÝÔ1Ø,ð
ñ 
ô 
ð 	
ð Ðr(   c              ƒ   ó    K  — | j         st          t          j        d¬¦  «        ‚| j        j        dvrt          t          j        d¬¦  «        ‚| S )Nrx   rs   )Ú
subscriberr„   ry   zSubscriber access requiredrz   ru   s    r&   Úget_current_subscriber_userrˆ   ­   so   è è € ð Ôð 
ÝÝÔ1Ø%ð
ñ 
ô 
ð 	
ð ÔÔÐ%GÐGÐGÝÝÔ1Ø/ð
ñ 
ô 
ð 	
ð Ðr(   c              ƒ   ó´  K  — t          | ¦  «        }|st          | ¦  «        ƒ d{V —†}|sdS 	 t          j        |t          j        t          j        g¬¦  «        }|                     d¦  «        }|€dS |                     t          ¦  «         
                    t          j        |k    ¦  «                             ¦   «         }|S # t          t          f$ r Y dS w xY w)zPGet current user from token (cookie or header), return None if not authenticatedNra   rc   )r'   re   r	   rf   r   rO   rP   r%   rg   r   rh   ri   rj   r   Ú	Exception)r    r[   rl   rm   rn   ro   s         r&   Úget_current_user_optionalr‹   ½   sæ   è è € õ " 'Ñ*Ô*€Eð ð -Ý# GÑ,Ô,Ð,Ð,Ð,Ð,Ð,Ð,ˆàð ØˆtðÝ”*˜U¥HÔ$;ÍÔI_ÐH`ÐaÑaÔaˆØ—{’{ 5Ñ)Ô)ˆØˆ?Ø�4Ø�xŠx�‰~Œ~×$Ò$¥T¤W°Ò%7Ñ8Ô8×>Ò>Ñ@Ô@ˆØˆøÝ•iÐ ð ð ð Øˆtˆtðøøøs   ®AC Á3AC ÃCÃCro   c                 ó   — | j         sg S |                     t          ¦  «                             t          ¦  «                             t          j         | j         k    ¦  «                             ¦   «         }d„ |D ¦   «         S )z7Get all permission names for a user based on their rolec                 ó   — g | ]	}|j         ‘Œ
S © )r~   )Ú.0Úperms     r&   ú
<listcomp>z(get_user_permissions.<locals>.<listcomp>á   s   € Ð.Ð.Ð.˜$ˆDŒIÐ.Ð.Ð.r(   )r{   rg   r   Újoinr   rh   Úall)ro   r[   Úpermissionss      r&   Úget_user_permissionsr•   ×   sq   € àŒ<ð Øˆ	ð —(’(�:Ñ&Ô&×+Ò+­NÑ;Ô;×BÒBÝÔ $¤,Ò.ñô ç	‚c�e„eð ð /Ð. +Ð.Ñ.Ô.Ð.r(   Úpermission_namec                 ó2  — | j         sdS | j        j        dk    rdS |                     t          ¦  «                             t          ¦  «                             t          j         | j         k    t          j        |k    ¦  «                             ¦   «         }|duS )z'Check if user has a specific permissionFry   TN)	r{   r}   r~   rg   r   r’   r   rh   rj   )ro   r–   r[   Ú
permissions       r&   Úhas_permissionr™   ä   sŠ   € àŒ<ð Øˆuð „y„~˜Ò Ð Øˆtð —’�*Ñ%Ô%×*Ò*­>Ñ:Ô:×AÒAÝÔ $¤,Ò.ÝŒ˜?Ò*ñô ÷ ‚e�g„gð ð
 ˜TÐ!Ð!r(   c                 óŒ   ‡ — t          t          ¦  «        t          t          ¦  «        fdt          dt          dt          fˆ fd„}|S )z3Dependency factory to require a specific permissionrq   r[   r!   c              “   ój   •K  — t          | ‰|¦  «        st          t          j        d‰› �¬¦  «        ‚| S )NzPermission required: rs   )r™   r   r   r|   )rq   r[   r–   s     €r&   Úpermission_dependencyz1require_permission.<locals>.permission_dependencyø   sM   øè è € õ ˜l¨O¸RÑ@Ô@ð 	ÝÝ"Ô5Ø@¨Ð@Ð@ðñ ô ð ð Ðr(   ©r   rv   r   r   r   )r–   rœ   s   ` r&   Úrequire_permissionrž   ö   s_   ø€ õ %Õ%<Ñ=Ô=Ý�f‘o”oð	ð 	Ýð	åð	õ 
ð	ð 	ð 	ð 	ð 	ð 	ð !Ð r(   Úpermission_namesc                 óŒ   ‡ — t          t          ¦  «        t          t          ¦  «        fdt          dt          dt          fˆ fd„}|S )z>Dependency factory to require any of the specified permissionsrq   r[   r!   c              “   óÐ   •K  — | j         r| j         j        dk    r| S ‰D ]}t          | ||¦  «        r| c S Œt          t          j        dd                     ‰¦  «        › �¬¦  «        ‚)Nry   z#One of these permissions required: z, rs   )r}   r~   r™   r   r   r|   r’   )rq   r[   Ú	perm_namerŸ   s      €r&   rœ   z5require_any_permission.<locals>.permission_dependency  s—   øè è € ð
 Ôð 	  Ô!2Ô!7¸7Ò!BÐ!BØÐð *ð 	$ð 	$ˆIÝ˜l¨I°rÑ:Ô:ð $Ø#Ð#Ð#Ð#ð$õ ÝÔ1ØV¸¿ºÐCSÑ9TÔ9TÐVÐVð
ñ 
ô 
ð 	
r(   r�   )rŸ   rœ   s   ` r&   Úrequire_any_permissionr£     s_   ø€ õ %Õ%<Ñ=Ô=Ý�f‘o”oð
ð 
Ýð
åð
õ 
ð
ð 
ð 
ð 
ð 
ð 
ð" !Ð r(   r:   )7r   r   r   Útypingr   r   Újoser   r	   Úpasslib.contextr
   Úfastapir   r   r   r   r   Úfastapi.securityr   Úsqlalchemy.ormr   Úconfigr   Údatabaser   Úmodels.userr   Úmodels.permissionr   r   Úi18nr   r   r;   re   Ústrr'   r6   Úboolr=   rA   ÚdictrT   rZ   rp   rv   r   r‚   r…   rˆ   r‹   r•   r™   rž   r£   rŽ   r(   r&   ú<module>r²      s›  ðØ 2Ð 2Ð 2Ð 2Ð 2Ð 2Ð 2Ð 2Ð 2Ð 2Ø !Ð !Ð !Ð !Ð !Ð !Ð !Ð !Ø Ð Ð Ð Ð Ð Ð Ð Ø (Ð (Ð (Ð (Ð (Ð (Ø CÐ CÐ CÐ CÐ CÐ CÐ CÐ CÐ CÐ CÐ CÐ CÐ CÐ CØ 1Ð 1Ð 1Ð 1Ð 1Ð 1Ø "Ð "Ð "Ð "Ð "Ð "Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø 9Ð 9Ð 9Ð 9Ð 9Ð 9Ð 9Ð 9Ø ;Ð ;Ð ;Ð ;Ð ;Ð ;Ð ;Ð ;àˆl H :¸&ÐAÑAÔA€Ø$Ð$Ð.>È5ÐQÑQÔQ€ð/ 7ð /¨x¸¬}ð /ð /ð /ð /ð &, V¨D¡\¤\Øðð Ø˜c”]ðà
�3Œ-ðð 	ðð ð ð ðB? Cð ?¸#ð ?À$ð ?ð ?ð ?ð ?ð& ð &¨ð &ð &ð &ð &ðð ˜dð °8¸IÔ3Fð ÐRUð ð ð ð ð˜tð ¨ð ð ð ð ð �'˜&‘/”/ðð Øðàðð 
ðð ð ð ðF !˜Ð!1Ñ2Ô2ðð Øðà	ðð ð ð ð !˜Ð!8Ñ9Ô9ðð Øðà	ðð ð ð ð" !˜Ð!8Ñ9Ô9ðð Øðà	ðð ð ð ð" !˜Ð!8Ñ9Ô9ðð Øðà	ðð ð ð ð" !˜Ð!8Ñ9Ô9ðð Øðà	ðð ð ð ð$ �'˜&‘/”/ðð Øðàðð ˆd„^ðð ð ð ð4
/˜tð 
/¨ð 
/°T¸#´Yð 
/ð 
/ð 
/ð 
/ð"˜ð "°ð "¸ð "ÀTð "ð "ð "ð "ð$!¨ð !ð !ð !ð !ð!¨T°#¬Yð !ð !ð !ð !ð !ð !r(   