U
    >i:                     @   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 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Zd"eed
ddZd#eedddZee dddZeeedddZeedddZeedddZeeedddZG d d! d!ZdS )$    N)Iterator)cache)context)app_settings)Authenticator)decryptencryptzmfa.totp.secret   )lengthreturnc                 C   s   t | }t|dS )Nzutf-8)secretsZtoken_bytesbase64	b32encodedecode)r
   Zrandom_bytes r   B/tmp/pip-unpacked-wheel-upujnpc2/allauth/mfa/totp/internal/auth.pygenerate_totp_secret   s    
r   F)
regenerater   c                 C   s0   d }| st jjt}|s,t  }t jjt< |S N)r   requestsessiongetSECRET_SESSION_KEYr   )r   secretr   r   r   get_totp_secret   s    r   )r   c                  c   s>   t t } | tj }ttj tjd D ]}|| V  q*d S )N   )inttimer   TOTP_PERIODrangeZTOTP_TOLERANCE)current_timecounterir   r   r   yield_hotp_counters_from_time"   s    
r#   )r   r!   r   c                 C   s   t d|}tj| ddd}t||tj	 }|d d@ }t
|||d  }|d d	@ |d< t d
|d }|dtj ; }|S )Nz>QasciiT)casefold      r      z>I
   )structpackr   	b32decodeencodehmacnewhashlibsha1digest	bytearrayunpackr   TOTP_DIGITS)r   r!   Zcounter_bytesZ
secret_encZhmac_resultoffsetZtruncated_hashvaluer   r   r   
hotp_value)   s    r9   )r8   r   c                 C   s   | dt j S )N0)r   r6   )r8   r   r   r   format_hotp_value;   s    r;   coder   c                 C   s   t | otj| kS r   )boolr   ZTOTP_INSECURE_BYPASS_CODE)r=   r   r   r   _is_insecure_bypass?   s    r?   )r   r=   r   c                 C   s<   t |rdS t }|D ] }t| |}|t|kr dS qdS )NTF)r?   r#   r9   r;   )r   r=   Zcountersr!   r8   r   r   r   validate_totp_codeC   s    
r@   c                   @   sp   e Zd ZeddddZeed dddZeedd	d
Z	eedddZ
eedddZeddddZdS )TOTPN)instancer   c                 C   s
   || _ d S r   )rB   )selfrB   r   r   r   __init__O   s    zTOTP.__init__)r   r   c                 C   s*   t |t jjdt|id}|  | |S )Nr   )usertypedata)r   TyperA   r   save)clsrE   r   rB   r   r   r   activateR   s      
zTOTP.activater<   c                 C   sF   t |rdS | |rdS t| jjd }t||}|rB| | |S )NTFr   )r?   _is_code_usedr   rB   rG   r@   _mark_code_used)rC   r=   r   Zvalidr   r   r   validate_codeZ   s    


zTOTP.validate_codec                 C   s   d| j j d| S )Nzallauth.mfa.totp.used?user=z&code=)rB   Zuser_idrC   r=   r   r   r   _get_used_cache_keyf   s    zTOTP._get_used_cache_keyc                 C   s   t | |dkS )Ny)r   r   rP   rO   r   r   r   rL   i   s    zTOTP._is_code_usedc                 C   s   t j| |dtjd d S )NrQ   )timeout)r   setrP   r   r   rO   r   r   r   rM   l   s    zTOTP._mark_code_used)__name__
__module____qualname__r   rD   classmethodstrrK   r>   rN   rP   rL   rM   r   r   r   r   rA   N   s   rA   )r	   )F)r   r1   r/   r   r+   r   typingr   Zdjango.core.cacher   Zallauth.corer   Zallauth.mfar   Zallauth.mfa.modelsr   Zallauth.mfa.utilsr   r   r   r   rX   r   r>   r   r#   r9   r;   r?   r@   rA   r   r   r   r   <module>   s(   	