U
    ÔÉ>i÷  ã                   @   sÎ   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 d dlm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mZ G dd„ deƒZ e dœdd„ZdS )é    )ÚBytesIO)ÚDict)Úquote)Ú	urlencode)ÚgettextÚgettext_lazy)Úapp_settings)Úget_adapter)Úuser_displayÚ
user_emailÚuser_pk_to_url_strÚuser_username)Úcontext)ÚBaseAdapter)ÚAuthenticator)Úimport_attributec                   @   s
  e Zd ZdZedƒedƒedƒedƒedƒdœZedœd	d
„Zedœdd„Zedœdd„Z	eedœdd„Z
eedœdd„Zedœdd„Zeedœdd„Zeedœdd„Zeedœdd„Zd d!„ Zd,edœd#d$„Zejed%œd&d'„Zeeef dœd(d)„Zedœd*d+„Zd"S )-ÚDefaultMFAAdaptera4  The adapter class allows you to override various functionality of the
    ``allauth.mfa`` app.  To do so, point ``settings.MFA_ADAPTER`` to your own
    class that derives from ``DefaultMFAAdapter`` and override the behavior by
    altering the implementation of the methods according to your own needs.
    zUYou cannot add an email address to an account protected by two-factor authentication.z0You cannot deactivate two-factor authentication.zTYou cannot generate recovery codes without having two-factor authentication enabled.zIncorrect code.zYYou cannot activate two-factor authentication until you have verified your email address.)Zadd_email_blockedZcannot_delete_authenticatorZcannot_generate_recovery_codesZincorrect_codeZunverified_email©Úreturnc                 C   s
   |   |¡S )zZReturns the label used for representing the given user in a TOTP QR
        code.
        )Ú_get_user_identifier©ÚselfÚuser© r   ú7/tmp/pip-unpacked-wheel-upujnpc2/allauth/mfa/adapter.pyÚget_totp_label/   s    z DefaultMFAAdapter.get_totp_labelc                 C   s$   t |ƒ}|st|ƒ}|s t|ƒ}|S )z`Human-palatable identifier for a user account. It is intended only
        for display.
        )r   r   Ústr)r   r   Úlabelr   r   r   r   5   s    z&DefaultMFAAdapter._get_user_identifierc                 C   s   t j}|s|  ¡ }|S )zYReturns the TOTP issuer name that will be contained in the TOTP QR
        code.
        )r   ZTOTP_ISSUERÚ_get_site_name)r   Úissuerr   r   r   Úget_totp_issuer@   s    z!DefaultMFAAdapter.get_totp_issuer)Úsecretr   c                 C   s\   |   |¡}|  ¡ }||dœ}tjdkr0tj|d< tjdkrDtj|d< dt|ƒ› dt|ƒ› S )N)r!   r   é   Údigitsé   Zperiodzotpauth://totp/ú?)r   r    r   ZTOTP_DIGITSZTOTP_PERIODr   r   )r   r   r!   r   r   Úparamsr   r   r   Úbuild_totp_urlI   s    
ü



z DefaultMFAAdapter.build_totp_url)Úurlr   c                 C   s@   dd l }ddlm} |j||d}tƒ }| |¡ | ¡  d¡S )Nr   )ÚSvgPathImage)Zimage_factoryÚutf8)ÚqrcodeZqrcode.image.svgr)   Úmaker   ÚsaveÚgetvalueÚdecode)r   r(   r+   r)   ÚimgÚbufr   r   r   Úbuild_totp_svgX   s    
z DefaultMFAAdapter.build_totp_svgc                 C   s0   t jr"ddlm} |j tj¡jS tj 	¡ S d S )Nr   )ÚSite)
Úallauth_settingsZSITES_ENABLEDZdjango.contrib.sites.modelsr3   ÚobjectsZget_currentr   ÚrequestÚnameÚget_host)r   r3   r   r   r   r   a   s    z DefaultMFAAdapter._get_site_name)Útextr   c                 C   s   |S )z³Secrets such as the TOTP key are stored in the database.  This
        hook can be used to encrypt those so that they are not stored in the
        clear in the database.
        r   )r   r9   r   r   r   Úencrypti   s    zDefaultMFAAdapter.encrypt)Úencrypted_textr   c                 C   s   |}|S )zCounter part of ``encrypt()``.r   )r   r;   r9   r   r   r   Údecryptp   s    zDefaultMFAAdapter.decrypt)Úauthenticatorr   c                 C   s   dS )NTr   )r   r=   r   r   r   Úcan_delete_authenticatoru   s    z*DefaultMFAAdapter.can_delete_authenticatorc                 O   s   t ƒ j||ŽS ©N)Úget_account_adapterÚsend_notification_mail)r   ÚargsÚkwargsr   r   r   rA   x   s    z(DefaultMFAAdapter.send_notification_mailNc                 C   s4   |j r
dS tjj|d}|dk	r,|j|d}| ¡ S )zM
        Returns ``True`` if (and only if) the user has 2FA enabled.
        F)r   N)Ztype__in)Zis_anonymousr   r5   ÚfilterÚexists)r   r   ÚtypesÚqsr   r   r   Úis_mfa_enabled{   s    z DefaultMFAAdapter.is_mfa_enabled)Útyper   c                 C   sH   t jj||d ¡ }|dkr$tdƒS |dkr4tdƒS tdƒj|d dS )zi
        Generate a human friendly name for the key. Used to prefill the "Add
        key" form.
        )r   rI   r   z
Master keyé   z
Backup keyzKey nr. {number})Únumber)r   r5   rD   Úcountr   Úformat)r   r   rI   Únr   r   r   Úgenerate_authenticator_name†   s    z-DefaultMFAAdapter.generate_authenticator_namec                 C   s"   |   ¡ }tj ¡  d¡d |dœS )Nú:r   )Úidr7   )r   r   r6   r8   Ú	partition)r   r7   r   r   r   Ú#get_public_key_credential_rp_entity’   s    þz5DefaultMFAAdapter.get_public_key_credential_rp_entityc                 C   s    t |ƒ d¡t|ƒ|  |¡dœS )Nr*   )rQ   Zdisplay_namer7   )r   Úencoder
   r   r   r   r   r   Ú%get_public_key_credential_user_entity™   s    ýz7DefaultMFAAdapter.get_public_key_credential_user_entity)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú_Zerror_messagesr   r   r   r    r'   r2   r   r:   r<   r   Úboolr>   rA   rH   ÚTyperO   r   rS   ÚdictrU   r   r   r   r   r      s:   ÿÿÿÿõ		r   r   c                   C   s   t tjƒƒ S r?   )r   r   ZADAPTERr   r   r   r   r	   ¡   s    r	   N)!Úior   Útypingr   Úurllib.parser   Zdjango.utils.httpr   Zdjango.utils.translationr   r   rZ   Zallauthr   r4   Zallauth.account.adapterr	   r@   Zallauth.account.utilsr
   r   r   r   Zallauth.corer   Zallauth.core.internal.adapterr   Zallauth.mfaZallauth.mfa.modelsr   Zallauth.utilsr   r   r   r   r   r   Ú<module>   s    