Ë
    OK¸iÔ6  ã                   óî   — d dl Z d dlZd dlZd dlZd dl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lmZmZ d dlmZ d dlmZ d d	lmZ d d
lmZmZ  ej6                  e«      Zdd„Z G d„ de	«      Zy)é    N)Úget_user_model)ÚModelBackend)ÚImproperlyConfiguredÚSuspiciousOperation)Úreverse)Úforce_bytesÚ	smart_str)Úimport_string)ÚHTTPBasicAuth)Ú	HTTPError)Ú
absolutifyÚimport_from_settingsc                 ó´   — t        j                  t        j                  t	        | «      «      j                  «       «      j                  d«      }t        |«      S )zÞGenerate username for the Django user.

    :arg str/unicode email: the email address to use to generate a username
    :arg dic claims: the claims from your OIDC provider, currently unused

    :returns: str/unicode

    ó   =)Úbase64Úurlsafe_b64encodeÚhashlibÚsha1r   ÚdigestÚrstripr	   )ÚemailÚclaimsÚusernames      úO/var/www/aura-ras/venv/lib/python3.12/site-packages/mozilla_django_oidc/auth.pyÚdefault_username_algor      sG   € ô ×'Ñ'Ü�‰”[ Ó'Ó(×/Ñ/Ó1óç�fˆTƒlð ô �XÓÐó    c                   óŒ   — e Zd ZdZd„ Zed„ «       Zd„ Zd„ Zd„ Z	d„ Z
d„ Zd	„ Zd
„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zy)ÚOIDCAuthenticationBackendz!Override Django's authentication.c                 óD  — | j                  d«      | _        | j                  d«      | _        | j                  dd«      | _        | j                  d«      | _        | j                  d«      | _        | j                  dd«      | _        | j                  d	d«      | _        | j                  j                  d
«      s| j                  j                  d«      r>| j                  €2| j                  €&d}t        |j                  | j                  «      «      ‚t        «       | _        y)zInitialize settings.ÚOIDC_OP_TOKEN_ENDPOINTÚOIDC_OP_USER_ENDPOINTÚOIDC_OP_JWKS_ENDPOINTNÚOIDC_RP_CLIENT_IDÚOIDC_RP_CLIENT_SECRETÚOIDC_RP_SIGN_ALGOÚHS256ÚOIDC_RP_IDP_SIGN_KEYÚRSÚESzO{} alg requires OIDC_RP_IDP_SIGN_KEY or OIDC_OP_JWKS_ENDPOINT to be configured.)Úget_settingsr    r!   r"   r#   r$   r%   r'   Ú
startswithr   Úformatr   Ú	UserModel)ÚselfÚargsÚkwargsÚmsgs       r   Ú__init__z"OIDCAuthenticationBackend.__init__-   sÿ   € à&*×&7Ñ&7Ð8PÓ&QˆÔ#Ø%)×%6Ñ%6Ð7NÓ%OˆÔ"Ø%)×%6Ñ%6Ð7NÐPTÓ%UˆÔ"Ø!%×!2Ñ!2Ð3FÓ!GˆÔØ%)×%6Ñ%6Ð7NÓ%OˆÔ"Ø!%×!2Ñ!2Ð3FÈÓ!PˆÔØ$(×$5Ñ$5Ð6LÈdÓ$SˆÔ!ð ×"Ñ"×-Ñ-¨dÔ3Ø×%Ñ%×0Ñ0°Ô6à×%Ñ%Ð-°$×2LÑ2LÐ2TàcˆCÜ& s§z¡z°$×2HÑ2HÓ'IÓJÐJä'Ó)ˆ�r   c                 ó   — t        | g|¢­Ž S ©N)r   )Úattrr/   s     r   r*   z&OIDCAuthenticationBackend.get_settingsB   s   € ä# DÐ0¨4Ò0Ð0r   c                 óF   — |j                  d«      }dj                  |«      S )Nr   zemail {})Úgetr,   ©r.   r   r   s      r   Údescribe_user_by_claimsz1OIDCAuthenticationBackend.describe_user_by_claimsF   s!   € Ø—
‘
˜7Ó#ˆØ× Ñ  Ó'Ð'r   c                 ó¼   — |j                  d«      }|s$| j                  j                  j                  «       S | j                  j                  j	                  |¬«      S )z.Return all users matching the specified email.r   )Úemail__iexact)r7   r-   ÚobjectsÚnoneÚfilterr8   s      r   Úfilter_users_by_claimsz0OIDCAuthenticationBackend.filter_users_by_claimsJ   sJ   € à—
‘
˜7Ó#ˆÙØ—>‘>×)Ñ)×.Ñ.Ó0Ð0Ø�~‰~×%Ñ%×,Ñ,¸5Ð,ÓAÐAr   c                 ó~   — | j                  dd«      }d|j                  «       v rd|v S t        j                  d«       y)zIVerify the provided claims to decide if authentication should be allowed.ÚOIDC_RP_SCOPESzopenid emailr   zcCustom OIDC_RP_SCOPES defined. You need to override `verify_claims` for custom claims verification.T)r*   ÚsplitÚLOGGERÚwarning)r.   r   Úscopess      r   Úverify_claimsz'OIDCAuthenticationBackend.verify_claimsQ   sG   € ð ×"Ñ"Ð#3°^ÓDˆØ�f—l‘l“nÑ$Ø˜fÐ$Ð$ä�‰ðSô	
ð
 r   c                 ó”   — |j                  d«      }| j                  |«      }| j                  j                  j	                  ||¬«      S )z/Return object for a newly created user account.r   )r   )r7   Úget_usernamer-   r<   Úcreate_user)r.   r   r   r   s       r   rI   z%OIDCAuthenticationBackend.create_user`   s@   € à—
‘
˜7Ó#ˆØ×$Ñ$ VÓ,ˆØ�~‰~×%Ñ%×1Ñ1°(À%Ð1ÓHÐHr   c                 óJ  — | j                  dd«      }|rut        |t        «      rt        |«      }t	        t        j                  |«      j                  «      dk(  r ||j                  d«      «      S  ||j                  d«      |«      S t        |j                  d«      |«      S )z"Generate username based on claims.ÚOIDC_USERNAME_ALGONé   r   )
r*   Ú
isinstanceÚstrr
   ÚlenÚinspectÚgetfullargspecr/   r7   r   )r.   r   Úusername_algos      r   rH   z&OIDCAuthenticationBackend.get_usernamef   sŽ   € ð
 ×)Ñ)Ð*>ÀÓEˆáÜ˜-¬Ô-Ü -¨mÓ <�Ü”7×)Ñ)¨-Ó8×=Ñ=Ó>À!ÒCá$ V§Z¡Z°Ó%8Ó9Ð9ñ % V§Z¡Z°Ó%8¸&ÓAÐAä$ V§Z¡Z°Ó%8¸&ÓAÐAr   c                 ó   — |S )zHUpdate existing user with new claims, if necessary save, and return user© )r.   Úuserr   s      r   Úupdate_userz%OIDCAuthenticationBackend.update_usery   s   € àˆr   c                 óB  — t        j                  |«      }	 |d   }|| j                  k7  rdj                  |«      }t        |«      ‚	 t        j                  |||ddi¬«      S # t        $ r d}t        |«      ‚w xY w# t         j                  $ r d}t        |«      ‚w xY w)zFVerify the given JWS payload with the given key and return the payloadÚalgzNo alg value found in headerzJThe provider algorithm {!r} does not match the client's OIDC_RP_SIGN_ALGO.Ú
verify_audF)Ú
algorithmsÚoptionszJWS token verification failed.)ÚjwtÚget_unverified_headerÚKeyErrorr   r%   r,   ÚdecodeÚDecodeError)r.   ÚpayloadÚkeyÚjwsrX   r1   s         r   Ú_verify_jwsz%OIDCAuthenticationBackend._verify_jws}   s¹   € ä×'Ñ'¨Ó0ˆð	+Ø�e‘*ˆCð
 �$×(Ñ(Ò(ð%ß%+¡V¨C£[ð ô & cÓ*Ð*ð	+ä—:‘:Ø˜¨°|ÀUÐ6Kôð øô ò 	+Ø0ˆCÜ% cÓ*Ð*ð	+ûô  �‰ò 	+Ø2ˆCÜ% cÓ*Ð*ð	+ús   —A# ÁA= Á#A:Á=!Bc           	      óæ  — t        j                  | j                  | j                  dd«      | j                  dd«      | j                  dd«      ¬«      }|j	                  «        |j                  «       }t        j                  |«      }d}|d   D ]>  }t        dd«      r|d	   t        |d	   «      k7  rŒ$d
|v r|d
   t        |d
   «      k7  rŒ=|}Œ@ |€t        d«      ‚t        j                  |«      S )zßGet the signing key by exploring the JWKS endpoint of the OP.

        Don't use jwt.PyJWKClient()get_signing_key_from_jwt() because it doesn't check
        the algorithm in case of multiple jwk with the same kid.
        ÚOIDC_VERIFY_SSLTÚOIDC_TIMEOUTNÚ
OIDC_PROXY)ÚverifyÚtimeoutÚproxiesÚkeysÚOIDC_VERIFY_KIDÚkidrX   zCould not find a valid JWKS.)Úrequestsr7   r"   r*   Úraise_for_statusÚjsonr\   r]   r   r	   r   ÚPyJWK)r.   ÚtokenÚresponse_jwksÚjwksrc   rb   Újwks          r   Úretrieve_matching_jwkz/OIDCAuthenticationBackend.retrieve_matching_jwk—   s  € ô !Ÿ™Ø×&Ñ&Ø×$Ñ$Ð%6¸Ó=Ø×%Ñ% n°dÓ;Ø×%Ñ% l°DÓ9ô	
ˆð 	×&Ñ&Ô(Ø×!Ñ!Ó#ˆô ×'Ñ'¨Ó.ˆàˆØ˜‘<ò 	ˆCÜ#Ð$5°tÔ<ÀØñBä˜3˜u™:Ó&òB'ð Ø˜‰|  E¡
¬i¸¸E¹
Ó.CÒ CØØ‰Cð	ð ˆ;Ü%Ð&DÓEÐEÜ�y‰y˜‹~Ðr   c                 ó¾   — | j                  dd«      r:t        j                  |«      }d|v r!|d   dk(  rt        j                  |ddi¬«      S | j	                  ||«      S )z2Helper method to get the payload of the JWT token.ÚOIDC_ALLOW_UNSECURED_JWTFrX   r=   Úverify_signature)r[   )r*   r\   r]   r_   rd   )r.   rs   rb   Úheaders       r   Úget_payload_dataz*OIDCAuthenticationBackend.get_payload_data¶   sc   € à×ÑÐ7¸Ô?Ü×.Ñ.¨uÓ5ˆFð ˜‰ 6¨%¡=°FÒ#:Ü—z‘z %Ð2DÀeÐ1LÔMÐMð ×Ñ  sÓ+Ð+r   c                 ó�  — |j                  d«      }| j                  j                  d«      s| j                  j                  d«      r+| j                  �| j                  }n| j	                  |«      }n| j
                  }| j                  ||«      }|j                  d«      }| j                  dd«      r||k7  rd}t        |«      ‚|S )zValidate the token signature.Únoncer(   r)   ÚOIDC_USE_NONCETzJWT Nonce verification failed.)	r7   r%   r+   r'   rw   r$   r|   r*   r   )r.   rs   r0   r~   rb   ra   Útoken_noncer1   s           r   Úverify_tokenz&OIDCAuthenticationBackend.verify_tokenÂ   s»   € à—
‘
˜7Ó#ˆà×!Ñ!×,Ñ,¨TÔ2°d×6LÑ6L×6WÑ6WØô7
ð ×(Ñ(Ð4Ø×/Ñ/‘à×0Ñ0°Ó7‘à×,Ñ,ˆCà×'Ñ'¨¨sÓ3ˆØ—k‘k 'Ó*ˆà×ÑÐ-¨tÔ4¸À+Ò9MØ2ˆCÜ% cÓ*Ð*Øˆr   c                 óx  — d}| j                  dd«      r1|j                  d«      }|j                  d«      }t        ||«      }|d= t        j                  | j
                  ||| j                  dd«      | j                  dd«      | j                  d	d«      ¬
«      }| j                  |«       |j                  «       S )z$Return token object as a dictionary.NÚOIDC_TOKEN_USE_BASIC_AUTHFÚ	client_idÚclient_secretrf   Trg   rh   )ÚdataÚauthri   rj   rk   )r*   r7   r   ro   Úpostr    Úraise_token_response_errorrq   )r.   ra   r‡   rU   ÚpwÚresponses         r   Ú	get_tokenz#OIDCAuthenticationBackend.get_tokenØ   s´   € ð ˆØ×ÑÐ8¸%Ô@à—;‘;˜{Ó+ˆDØ—‘˜_Ó-ˆBä   rÓ*ˆDØ˜Ð(ä—=‘=Ø×'Ñ'ØØØ×$Ñ$Ð%6¸Ó=Ø×%Ñ% n°dÓ;Ø×%Ñ% l°DÓ9ô
ˆð 	×'Ñ'¨Ô1Ø�}‰}‹Ðr   c                 ó�   — |j                   dk(  ryd|j                  › d|j                   › d|j                  › d�}t        ||¬«      ‚)z~Raises :class:`HTTPError`, if one occurred.
        as per: https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
        éÈ   NzGet Token Error (url: z
, status: z, body: ú))r‹   )Ústatus_codeÚurlÚtextr   )r.   r‹   Úhttp_error_msgs      r   r‰   z4OIDCAuthenticationBackend.raise_token_response_errorï   s\   € ð
 ×Ñ 3Ò&Øð % X§\¡\ Nð 3Ø×+Ñ+Ð,ð -Ø—]‘]�O 1ð&ð 	ô
 ˜°Ô:Ð:r   c           
      ó´  — t        j                  | j                  ddj                  |«      i| j	                  dd«      | j	                  dd«      | j	                  dd«      ¬«      }|j                  «        |j                  j                  d	d
«      j                  «       j                  d«      r| j                  |j                  «      S |j                  «       S )z˜Return user details dictionary. The id_token and payload are not used in
        the default implementation, but may be used when overriding this methodÚAuthorizationz
Bearer {0}rf   Trg   Nrh   )Úheadersri   rj   rk   zcontent-typeÚ zapplication/jwt)ro   r7   r!   r,   r*   rp   r–   Úlowerr+   r�   r’   rq   )r.   Úaccess_tokenÚid_tokenra   Úuser_responses        r   Úget_userinfoz&OIDCAuthenticationBackend.get_userinfoþ   sÆ   € ô !Ÿ™Ø×&Ñ&Ø$ l×&9Ñ&9¸,Ó&GÐHØ×$Ñ$Ð%6¸Ó=Ø×%Ñ% n°dÓ;Ø×%Ñ% l°DÓ9ô
ˆð 	×&Ñ&Ô(ð ×!Ñ!×%Ñ% n°bÓ9ß‰U‹Wß‰ZÐ)Ó*ð+ð
 ×$Ñ$ ]×%7Ñ%7Ó8Ð8ð ×!Ñ!Ó#Ð#r   c           
      ó  — || _         | j                   sy| j                   j                  j                  d«      }| j                   j                  j                  d«      }|j                  dd«      }|j                  dd«      }|r|sy| j	                  dd«      }| j
                  | j                  d|t        | j                   t        |«      «      d	œ}|�|j                  d|i«       | j                  |«      }	|	j                  d
«      }
|	j                  d«      }| j                  |
|¬«      }|r&| j                  ||
«       	 | j                  ||
|«      S y# t        $ r }t        j!                  d|«       Y d}~yd}~ww xY w)z1Authenticates a user based on the OIDC code flow.NÚstateÚcoder~   Úcode_verifierÚ OIDC_AUTHENTICATION_CALLBACK_URLÚoidc_authentication_callbackÚauthorization_code)r„   r…   Ú
grant_typerŸ   Úredirect_urirš   r™   )r~   z failed to get or create user: %s)ÚrequestÚGETr7   Úpopr*   r#   r$   r   r   ÚupdaterŒ   r�   Ústore_tokensÚget_or_create_userr   rC   rD   )r.   r¦   r0   rž   rŸ   r~   r    Úreverse_urlÚtoken_payloadÚ
token_inforš   r™   ra   Úexcs                 r   Úauthenticatez&OIDCAuthenticationBackend.authenticate  so  € ð ˆŒØ�|Š|Øà—‘× Ñ ×$Ñ$ WÓ-ˆØ�|‰|×Ñ×#Ñ# FÓ+ˆØ—
‘
˜7 DÓ)ˆØŸ
™
 ?°DÓ9ˆá™5Øà×'Ñ'Ø.Ð0Nó
ˆð
 ×/Ñ/Ø!×7Ñ7Ø.ØÜ& t§|¡|´W¸[Ó5IÓJñ
ˆð Ð$Ø× Ñ  /°=Ð!AÔBð —^‘^ MÓ2ˆ
Ø—>‘> *Ó-ˆØ!—~‘~ nÓ5ˆð ×#Ñ# H°EÐ#Ó:ˆáØ×Ñ˜l¨HÔ5ðØ×.Ñ.¨|¸XÀwÓOÐOð
 øô	 'ò Ü—‘ÐAÀ3ÔGÜûðús   ÅE Å	F Å E;Å;F c                 óŽ   — | j                   j                  }| j                  dd«      r||d<   | j                  dd«      r||d<   yy)zStore OIDC tokens.ÚOIDC_STORE_ACCESS_TOKENFÚoidc_access_tokenÚOIDC_STORE_ID_TOKENÚoidc_id_tokenN)r¦   Úsessionr*   )r.   r™   rš   r¶   s       r   rª   z&OIDCAuthenticationBackend.store_tokensG  sM   € à—,‘,×&Ñ&ˆà×ÑÐ6¸Ô>Ø+7ˆGÐ'Ñ(à×ÑÐ2°EÔ:Ø'/ˆG�OÒ$ð ;r   c                 óœ  — | j                  |||«      }| j                  |«      }|sd}t        |«      ‚| j                  |«      }t	        |«      dk(  r| j                  |d   |«      S t	        |«      dkD  rd}t        |«      ‚| j                  dd«      r| j                  |«      }|S t        j                  d| j                  |«      «       y)	z—Returns a User instance if 1 user is found. Creates a user if not found
        and configured to do so. Returns nothing if multiple users are matched.zClaims verification failedrL   r   zMultiple users returnedÚOIDC_CREATE_USERTzBLogin failed: No user with %s found, and OIDC_CREATE_USER is FalseN)rœ   rF   r   r?   rO   rV   r*   rI   rC   Údebugr9   )	r.   r™   rš   ra   Ú	user_infoÚclaims_verifiedr1   ÚusersrU   s	            r   r«   z,OIDCAuthenticationBackend.get_or_create_userQ  sÔ   € ð ×%Ñ% l°H¸gÓFˆ	à×,Ñ,¨YÓ7ˆÙØ.ˆCÜ% cÓ*Ð*ð ×+Ñ+¨IÓ6ˆäˆu‹:˜Š?Ø×#Ñ# E¨!¡H¨iÓ8Ð8Ü�‹Z˜!Š^ð ,ˆCÜ% cÓ*Ð*Ø×ÑÐ1°4Ô8Ø×#Ñ# IÓ.ˆDØˆKä�L‰LØTØ×,Ñ,¨YÓ7ôð r   c                 óŽ   — 	 | j                   j                  j                  |¬«      S # | j                   j                  $ r Y yw xY w)zReturn a user based on the id.)ÚpkN)r-   r<   r7   ÚDoesNotExist)r.   Úuser_ids     r   Úget_userz"OIDCAuthenticationBackend.get_userp  sA   € ð	Ø—>‘>×)Ñ)×-Ñ-°Ð-Ó9Ð9øØ�~‰~×*Ñ*ò 	Ùð	ús   ‚%( ¨AÁAN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r2   Ústaticmethodr*   r9   r?   rF   rI   rH   rV   rd   rw   r|   r�   rŒ   r‰   rœ   r°   rª   r«   rÁ   rT   r   r   r   r   *   sw   „ Ù+ò*ð* ñ1ó ð1ò(òBòòIòBò&ò+ò4ò>
,òò,ò.;ò$ò0/òb0òó>r   r   r4   ) r   r   ÚloggingrP   r\   ro   Údjango.contrib.authr   Údjango.contrib.auth.backendsr   Údjango.core.exceptionsr   r   Údjango.urlsr   Údjango.utils.encodingr   r	   Údjango.utils.module_loadingr
   Úrequests.authr   Úrequests.exceptionsr   Úmozilla_django_oidc.utilsr   r   Ú	getLoggerrÂ   rC   r   r   rT   r   r   ú<module>rÒ      sW   ðÛ Û Û ã Û 
Û Ý .Ý 5ß LÝ ß 8Ý 5Ý 'Ý )ç Fà	ˆ×	Ñ	˜8Ó	$€óô(L õ Lr   