U
    >iS                     @   s>  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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Zd dlmZmZ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" e#e	e
eee#ef f  dddZ$e%edddZ&e#e#dddZ'e#e	e# dddZ(ee#ef edddZ)e#e	e
eeee#ef f  dddZ*ee#ef e	e ddd Z+e#e#e	ee#ef  d!d"d#Z,dd$e#e#e#e	ee#ef  e-e
e#ee#ef f d%d&d'Z.eee#e-f d(d)d*Z/ee#d(d+d,Z0eee#ef e#d-d.d/Z1eee#ef dd0d1d2Z2dS )3    N)AnyDictOptionalTuple)settings)get_user_model)SessionBase)SimpleLazyObject)Cipher
algorithmsmodes)str_to_user_iduser_id_to_str)jwkkit)get_session_user)app_settings)lookup_session)tokenreturnc                    sX   t | d}|d krd S tjr0t|}|d kr0d S |d }t| t fdd}||fS )Naccesssubc                      s   t  jj dS )Npk)r   Zobjectsget r   r   S/tmp/pip-unpacked-wheel-upujnpc2/allauth/headless/tokens/strategies/jwt/internal.py<lambda>"       z'validate_access_token.<locals>.<lambda>)decode_tokenr   ZJWT_STATEFUL_VALIDATION_ENABLEDget_token_sessionr   r	   )r   payloadsessionr   Z	lazy_userr   r   r   validate_access_token   s    
r"   )initialization_vectorr   c                 C   s:   t j}t|  }t|}t	| }t
||}|S )N)r   Z
SECRET_KEYhashlibsha256encodedigestr   ZAESr   ZCTRr
   )r#   Z
secret_keykey	algorithmmodecipherr   r   r   get_session_key_cipher&   s    


r,   )session_keyr   c                 C   sF   t d}t|}| }||  |  }t|| 	 }|S )a
  
    In case an access token leaks, we do not want the session encoded in
    that token to be put to use as an X-Session-Token or session
    cookie. Therefore, we encrypt the sesison key. Unauthenticated symmetric
    encryption is fine, as the JWT is signed.
       )
secretsZtoken_bytesr,   	encryptorupdater&   finalizebase64	b64encodedecode)r-   r#   r+   r0   encrypted_messagesidr   r   r   session_key_to_sid/   s    
r8   )r7   r   c                 C   s   zt | }W n tjk
r&   Y d S X |d d }|dd  }t|dkrPd S t|}| }|||  }z
|	 W S  t
k
r   Y d S X d S )Nr.   r   )r3   	b64decodebinasciiErrorlenr,   	decryptorr1   r2   r5   UnicodeDecodeError)r7   Zencrypted_datar#   r6   r+   r=   Zmessage_decryptedr   r   r   session_key_from_sid>   s    
r?   )r   r!   c                 C   s0   t |}|d krd S t|}|| d kr,d S |S )Nr   )r   r   )r   r!   userr   r   r   r   validate_token_userP   s    rA   c                 C   st   t | d}|d krd S |d }t|}|d kr2d S t|}||}t }|d ks\||kr`d S t||}|||fS )Nrefreshjti)r   r   get_refresh_token_stater   timerA   )r   r    rC   r!   refresh_token_jti_to_expexpnowr@   r   r   r   validate_refresh_tokenZ   s    


rI   )r    r   c                 C   s@   |  d}t|tsd S t|}|s(d S t|}|d kr<d S |S )Nr7   )r   
isinstancestrr?   r   )r    r7   r-   r!   r   r   r   r   m   s    

r   )r   user   c              	   C   s   z6t tj\}}tj| | dgdddddd}W n tjk
rN   Y d S X |d|krbd S dD ]}||}t	|t
sf d S qf|S d S )NRS256TF)Zverify_signatureZ
verify_issZ
verify_audZ
verify_exp)r(   r   options	token_use)rC   r   r7   )r   load_jwk_from_pemr   JWT_PRIVATE_KEYjwtr5   Z
public_keyZ
PyJWTErrorr   rJ   rK   )r   rL   jwk_dictprivate_keyr    r(   valuer   r   r   r   z   s*    


r   )claims)rO   r   r7   rV   
expires_inr   c          	   	   C   st   t tj\}}tt }i }|d k	r2|| |||| |tt	 | |d t
j||dd|d id|fS )N)ZiatrG   r7   rC   rO   r   rM   Zkid)r)   headers)r   rP   r   rQ   intrE   r1   rK   uuidZuuid4rR   r&   )	rO   r   r7   rV   rW   rS   rT   rH   r    r   r   r   create_token   s,    


r[   )r!   r   c                 C   s   |  di S )NZheadless_refresh_tokens)
setdefault)r!   r   r   r   rD      s    rD   c                 C   sX   | j s
t|jstt| }t|j}td||tjd\}}t|}|d ||d < |S )NrB   )r   r7   rW   rG   rC   )	is_authenticatedAssertionErrorr-   r   r8   r[   r   ZJWT_REFRESH_TOKEN_EXPIRES_INrD   )r@   r!   r   r7   r   r    rF   r   r   r   create_refresh_token   s    



r_   )r!   rV   r   c                 C   s>   | j s
t|jstt|j}t| }td|||tjdd S )Nr   )r   r7   rV   rW   r   )r]   r^   r-   r8   r   r[   r   ZJWT_ACCESS_TOKEN_EXPIRES_IN)r@   r!   rV   r7   r   r   r   r   create_access_token   s    


r`   )r!   r   r   c                 C   s    t | }|d }||d  d S )NrC   )rD   pop)r!   r   rF   rC   r   r   r   invalidate_refresh_token   s    rb   )3r3   r:   r$   r/   rE   rZ   typingr   r   r   r   Zdjango.confr   Zdjango.contrib.authr   Z%django.contrib.sessions.backends.baser   Zdjango.utils.functionalr	   rR   Z&cryptography.hazmat.primitives.ciphersr
   r   r   Z allauth.account.internal.userkitr   r   Zallauth.core.internalr   Z allauth.core.internal.sessionkitr   Zallauth.headlessr   Z$allauth.headless.internal.sessionkitr   rK   r"   bytesr,   r8   r?   rA   rI   r   r   rY   r[   rD   r_   r`   rb   r   r   r   r   <module>   sP   $	"