o
    &zh                     @   s  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mZmZ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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( d dl)m*Z* d dl+m,Z, d dl-m.Z. d dl/m0Z1 d dl2m3Z4 d dl5m3Z3m6Z6 d dl7m8Z8 d dl9m:Z: d dl;m<Z< d dl=m>Z> d dl?m@Z@mAZA d dlBmCZCmDZD G dd de<ZEd!deEfdd ZFdS )"    N)urlparse)settings)messages)authenticateget_backendsget_user_modelloginlogout)AbstractUser)MinimumLengthValidatorvalidate_password)get_current_site)FieldDoesNotExist)EmailMessageEmailMultiAlternatives)HttpResponseHttpResponseRedirect)resolve_url)TemplateDoesNotExist)render_to_stringreverse)timezone)get_random_string	force_str)gettext_lazyapp_settings)r   signals)context)	ratelimit)BaseAdaptergenerate_user_code)headed_redirect_responseis_headless_request)generate_unique_usernameimport_attributec                	   @   s  e Zd ZdZi deddeddedded	d
eddeddeddeddeddeddeddeddeddeddedd ed!d"ed#ed$ed%ed&ejd'jd( ed)ed*ed+d,Zd-d. Z	d/d0 Z
d1d2 Zd3efd4d5Zd3efd6d7Zd8d9 Zdd;d<Zd=ed>ed?ed3d:fd@dAZdBdC ZdDdE ZdFdG ZdHdI ZdJdK ZdLdM ZdNdO ZdPdQ ZddRdSZddUdVZddXdYZd>ed3efdZd[Zdd\d]Z d^ed3efd_d`Z!dadb Z"	:	:	c	:ddddeZ#ddfdgZ$dhdi Z%djdk Z&dldm Z'dndo Z(dpdq Z)drds Z*ddtduZ+dvdw Z,dxdy Z-dzd{ Z.d|d} Z/d~d Z0d3efddZ1d>ed3d:fddZ2dd Z3dd Z4dd Z5dd Z6dd Z7dddZ8dd Z9dd Z:dd Z;dd Z<dd Z=d3efddZ>dd Z?dd Z@dd ZAdd ZBdddZCd3efddZDd3efddZEd3efddZFd3efddZGd3efddZHdd ZId^ed3d:fddZJd^ed3d:fddZKd^edefddZLeMd3efddZNd^edefddZOd3ePjQePjReef  fddZSd^efddZTd^efddÄZUd:S )DefaultAccountAdapteraD  The adapter class allows you to override various functionality of the
    ``allauth.account`` app.  To do so, point ``settings.ACCOUNT_ADAPTER`` to
    your own class that derives from ``DefaultAccountAdapter`` and override the
    behavior by altering the implementation of the methods according to your own
    needs.
    account_inactivez#This account is currently inactive.cannot_remove_primary_emailz-You cannot remove your primary email address.duplicate_emailz;This email address is already associated with this account.email_password_mismatchz@The email address and/or password you specified are not correct.phone_password_mismatchz?The phone number and/or password you specified are not correct.email_takenz5A user is already registered with this email address.enter_current_passwordz"Please type your current password.incorrect_codezIncorrect code.incorrect_passwordzIncorrect password.invalid_or_expired_keyzInvalid or expired key.invalid_loginzInvalid login.invalid_password_resetz%The password reset token was invalid.max_email_addressesz,You cannot add more than %d email addresses.phone_takenz4A user is already registered with this phone number.too_many_login_attemptsz0Too many failed login attempts. Try again later.unknown_emailz6The email address is not assigned to any user account.unknown_phonez5The phone number is not assigned to any user account.z,Your primary email address must be verified.z4Username can not be used. Please use other username.z;The username and/or password you specified are not correct.usernameuniquezPlease select only one.z5The new value must be different from the current one.z.Be patient, you are sending too many requests.)unverified_primary_emailusername_blacklistedusername_password_mismatchusername_takenselect_only_onesame_as_currentrate_limitedc                 C   s   ||j d< d S Naccount_verified_email)session)selfrequestemail rJ   R/var/www/html/kangema/venv/lib/python3.10/site-packages/allauth/account/adapter.pystash_verified_email_      z*DefaultAccountAdapter.stash_verified_emailc                 C   s   |j d}d |j d< |S rD   )rF   get)rG   rH   retrJ   rJ   rK   unstash_verified_emailb   s   
z,DefaultAccountAdapter.unstash_verified_emailc                 C   s(   d}|j d}|r| | k}|S )z
        Checks whether or not the email address is already verified
        beyond allauth scope, for example, by having accepted an
        invitation before signing up.
        FrE   )rF   rN   lower)rG   rH   rI   rO   verified_emailrJ   rJ   rK   is_email_verifiedg   s
   z'DefaultAccountAdapter.is_email_verifiedreturnc                 C   sh   ddl m} |jj|jdj|jd }tj	tj
jhk}|jr*|r$dS |r(dS dS |r.dS |r2dS dS )zP
        Returns whether or not the given email address can be deleted.
        r   EmailAddress)user_id)pkFT)allauth.account.modelsrV   objectsfilterrW   excluderX   existsr   LOGIN_METHODSLoginMethodEMAILprimary)rG   email_addressrV   	has_otherlogin_by_emailrJ   rJ   rK   can_delete_emails   s$   z&DefaultAccountAdapter.can_delete_emailc                 C   s2   t j}|du rttj}dj|jd}|t| S )z2
        Formats the given email subject.
        Nz	[{name}] )name)r   EMAIL_SUBJECT_PREFIXr   r    rH   formatrf   r   )rG   subjectprefixsiterJ   rJ   rK   format_email_subject   s
   
z*DefaultAccountAdapter.format_email_subjectc                 C   s   t jS )z
        This is a hook that can be overridden to programmatically
        set the 'from' email address for sending emails
        )r   DEFAULT_FROM_EMAILrG   rJ   rJ   rK   get_from_email   s   z$DefaultAccountAdapter.get_from_emailNc              	   C   s  t |tr|gn|}td||}d|  }| |}|  }i }t	j
}	|	dfD ](}
zd||
}t||t d j ||
< W q- tyU   |
dkrS|sS Y q-w d|v rst||d |||d}|	|v rq|||	 d |S t|||	 |||d}d|_|S )	z
        Renders an email to `email`.  `template_prefix` identifies the
        email that is to be sent, e.g. "account/email/email_confirmation"
        z{0}_subject.txt txtz{0}_message.{1}r    )headersz	text/htmlhtml)
isinstancestrr   rh   join
splitlinesstriprl   ro   r   TEMPLATE_EXTENSIONglobalsrH   r   r   attach_alternativer   content_subtype)rG   template_prefixrI   r    rr   tori   
from_emailbodieshtml_extexttemplate_namemsgrJ   rJ   rK   render_mail   sD   


z!DefaultAccountAdapter.render_mailr}   rI   r    c                 C   s@   t  d j}||t|d}|| | |||}|  d S )Nr    )rH   rI   current_site)rz   rH   r   updater   send)rG   r}   rI   r    rH   ctxr   rJ   rJ   rK   	send_mail   s   
zDefaultAccountAdapter.send_mailc                 C   
   t tjS )zS
        Returns the default URL to redirect to directly after signing up.
        )r   r   SIGNUP_REDIRECT_URLrG   rH   rJ   rJ   rK   get_signup_redirect_url      
z-DefaultAccountAdapter.get_signup_redirect_urlc                 C   s>   |j jsJ ttdd}|rtdt t|S tj}t|S )z
        Returns the default URL to redirect to after logging in.  Note
        that URLs passed explicitly (e.g. by passing along a `next`
        GET parameter) take precedence over the value returned here.
        LOGIN_REDIRECT_URLNAMENzSLOGIN_REDIRECT_URLNAME is deprecated, simply use LOGIN_REDIRECT_URL with a URL name)	useris_authenticatedgetattrr   warningswarnDeprecationWarningLOGIN_REDIRECT_URLr   )rG   rH   urlrJ   rJ   rK   get_login_redirect_url   s   z,DefaultAccountAdapter.get_login_redirect_urlc                 C   r   )a  
        Returns the URL to redirect to after the user logs out. Note that
        this method is also invoked if you attempt to log out while no users
        is logged in. Therefore, request.user is not guaranteed to be an
        authenticated user.
        )r   r   LOGOUT_REDIRECT_URLr   rJ   rJ   rK   get_logout_redirect_url   s   
z-DefaultAccountAdapter.get_logout_redirect_urlc                 C   sB   t | dd}|r|| jS | jjjrtjrtjS | | jS tjS )z@
        The URL to return to after email verification.
        #get_email_confirmation_redirect_urlN)r   rH   r   r   r   -EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URLr   )EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL)rG   rb   get_urlrJ   rJ   rK   #get_email_verification_redirect_url   s   

z9DefaultAccountAdapter.get_email_verification_redirect_urlc                 C      t dS )z
        The URL to redirect to after a successful password change/set.

        NOTE: Not called during the password reset flow.
        account_change_passwordr   r   rJ   rJ   rK    get_password_change_redirect_url  s   z6DefaultAccountAdapter.get_password_change_redirect_urlc                 C      dS )z
        Checks whether or not the site is open for signups.

        Next to simply returning True/False you can also intervene the
        regular flow by raising an ImmediateHttpResponse
        TrJ   r   rJ   rJ   rK   is_open_for_signup  s   z(DefaultAccountAdapter.is_open_for_signupc                 C   s   t   }|S )z3
        Instantiates a new User instance.
        )r   rG   rH   r   rJ   rJ   rK   new_user  s   zDefaultAccountAdapter.new_userc           
   	   C   sd   ddl m}m}m} ||d}||d}||}||}	tjr0|||	p,| ||||	dg dS dS )z
        Fills in a valid username, if required and missing.  If the
        username is already present it is assumed to be valid
        (unique).
           
user_email
user_fielduser_username
first_name	last_namer   N)utilsr   r   r   r   USER_MODEL_USERNAME_FIELDr'   )
rG   rH   r   r   r   r   r   r   rI   r;   rJ   rJ   rK   populate_username  s   

z'DefaultAccountAdapter.populate_usernamec                 C   s
   t ||S N)r'   )rG   txtsregexrJ   rJ   rK   r'   4  s   
z.DefaultAccountAdapter.generate_unique_usernameTc                 C   s   ddl m}m}m} |j}|d}	|d}
|d}|d}||| ||| |	r3||d|	 |
r;||d|
 d|v rG||d  nd|v rS||d  n|  | || |rc|	  |j
ru|jd	}|ru| ||d
 |S )zd
        Saves a new `User` instance using information provided in the
        signup form.
        r   r   r   r   rI   r;   	password1passwordphoneF)r   r   r   r   cleaned_datarN   set_passwordset_unusable_passwordr   save_has_phone_field	set_phone)rG   rH   r   formcommitr   r   r   datar   r   rI   r;   r   rJ   rJ   rK   	save_user7  s2   





zDefaultAccountAdapter.save_userFc                 C   sd   t jD ]}|| qdd t jD }| |v r| d|s0ddlm} || r0| d|S )z
        Validates the username. You can hook into this if you want to
        (dynamically) restrict what usernames can be chosen.
        c                 S   s   g | ]}|  qS rJ   )rQ   ).0ubrJ   rJ   rK   
<listcomp>a  s    z8DefaultAccountAdapter.clean_username.<locals>.<listcomp>r>   r   )filter_users_by_usernamer@   )r   USERNAME_VALIDATORSUSERNAME_BLACKLISTrQ   validation_errorr   r   r]   )rG   r;   shallow	validatorusername_blacklist_lowerr   rJ   rJ   rK   clean_usernameX  s   



z$DefaultAccountAdapter.clean_usernamec                 C      |S )z
        Validates an email value. You can hook into this if you want to
        (dynamically) restrict what email addresses can be chosen.
        rJ   rG   rI   rJ   rJ   rK   clean_emailo     z!DefaultAccountAdapter.clean_emailc                 C   s&   t j}|rt|| t|| |S )z{
        Validates a password. You can hook into this if you want to
        restric the allowed password choices.
        )r   PASSWORD_MIN_LENGTHr   validater   )rG   r   r   
min_lengthrJ   rJ   rK   clean_passwordv  s
   
z$DefaultAccountAdapter.clean_passwordr   c                 C   r   )z
        Validates a phone number. You can hook into this if you want to
        (dynamically) restrict what phone numbers can be chosen.
        rJ   rG   r   rJ   rJ   rK   clean_phone  r   z!DefaultAccountAdapter.clean_phonec                 C   r   r   rJ   r   rJ   rJ   rK   validate_unique_email     z+DefaultAccountAdapter.validate_unique_email c                 C   s   t |rdS dtjv rH|rtj||||d dS z%|du ri }t||tj }|r;t	
|}tj||||d W dS W dS  tyG   Y dS w dS )zx
        Wrapper of `django.contrib.messages.add_message`, that reads
        the message text from a template.
        Nzdjango.contrib.messages)
extra_tags)r&   r   INSTALLED_APPSr   add_messager   r    rH   rx   rs   unescaper   )rG   rH   levelmessage_templatemessage_contextr   messageescaped_messagerJ   rJ   rK   r     s0   

z!DefaultAccountAdapter.add_messagec                 C   s   i }|j }|rd}||d< |r8|jdkr| rd}nd}nd}| ||d< t|dr0|  |jd|d< |d ur@||d	< tt	
||d
dS )N   locationPOSTi  r   renderutf8rs   r   application/json)statuscontent_type)status_codemethodis_validajax_response_formhasattrr   contentdecoder   jsondumps)rG   rH   responseredirect_tor   r   respr   rJ   rJ   rK   ajax_response  s(   

z#DefaultAccountAdapter.ajax_responsec              	   C   s   i g |  d}|D ]3}t|j| t|jdd |jD ddd |jjj	 D id}||d |j
< |d	 |j
 q
|S )
N)fieldsfield_ordererrorsc                 S   s   g | ]}t |qS rJ   r   )r   erJ   rJ   rK   r     s    z<DefaultAccountAdapter.ajax_response_form.<locals>.<listcomp>attrsc                 S   s   i | ]	\}}|t |qS rJ   r   )r   kvrJ   rJ   rK   
<dictcomp>  s    z<DefaultAccountAdapter.ajax_response_form.<locals>.<dictcomp>)labelvalue	help_textr   widgetr   r   )non_field_errorsr   r   r  r  r   fieldr  r   items	html_nameappend)rG   r   	form_specr  
field_specrJ   rJ   rK   r     s"   z(DefaultAccountAdapter.ajax_response_formc                C   s   |j s	| ||S d S r   )	is_activerespond_user_inactive)rG   rH   r   email_verificationsignal_kwargsrI   signupredirect_urlrJ   rJ   rK   	pre_login  s   zDefaultAccountAdapter.pre_loginc                C   s   ddl m} t|rddlm}	 |	|}
n	t||||d}
|d u r$i }tjjd	|j	||
|d| | 
|tjdd|i |
S )
Nr   )r   r   )AuthenticationResponse)r  )senderrH   r   r   zaccount/messages/logged_in.txtr   rJ   )r   r   r&   allauth.headless.base.responser  r   r   user_logged_inr   	__class__r   r   SUCCESS)rG   rH   r   r  r  rI   r  r  r   r  r   rJ   rJ   rK   
post_login  s0   
z DefaultAccountAdapter.post_loginc                 C   sv   t |ds4ddlm} t }d }|D ]}t||r|} n
|s&t |dr&|}qd|j|jjg}||_	t
|| d S )Nbackendr   AuthenticationBackendget_user.)r   auth_backendsr  r   rt   rv   
__module__r  __name__r  django_login)rG   rH   r   r  backendsr  bbackend_pathrJ   rJ   rK   r     s   

zDefaultAccountAdapter.loginc                 C   s   t | d S r   )django_logoutr   rJ   rJ   rK   r	   $  s   zDefaultAccountAdapter.logoutc                 C   s   ddl m} |||S )z@
        Marks the email address as confirmed on the db
        r   )r  )allauth.account.internal.flowsr  verify_email)rG   rH   rb   r  rJ   rJ   rK   confirm_email'  s   z#DefaultAccountAdapter.confirm_emailc                 C   s   | | |  dS )z1
        Sets the password for the user.
        N)r   r   )rG   r   r   rJ   rJ   rK   r   /  s   
z"DefaultAccountAdapter.set_passwordc              	   C   sR   g }t  }tjdddg}|D ]}z|j| || W q ty&   Y qw |S )Nr   r   rI   )r   r   r   _meta	get_fieldr  r   )rG   rO   User
candidates	candidaterJ   rJ   rK   get_user_search_fields6  s   z,DefaultAccountAdapter.get_user_search_fieldsc                 C   st   ddl m} tj httjB }dd tjD }|	| d|v r4t
|j}|r,|hnd }|||dS |||dS )Nr   )url_has_allowed_host_and_schemec                 S   s   h | ]}t |jqS rJ   )r   netloc)r   originrJ   rJ   rK   	<setcomp>N  s    
z4DefaultAccountAdapter.is_safe_url.<locals>.<setcomp>*)allowed_hosts)django.utils.httpr/  r    rH   get_hostsetr   ALLOWED_HOSTSCSRF_TRUSTED_ORIGINSr   r   r0  )rG   r   r/  r4  trusted_hostsparsed_hostallowed_hostrJ   rJ   rK   is_safe_urlG  s   

z!DefaultAccountAdapter.is_safe_urlc                 C   s   |  d||S )a_  
        Method intended to be overridden in case you need to customize the logic
        used to determine whether a user is permitted to request a password reset.
        For example, if you are enforcing something like "social only" authentication
        in your app, you may want to intervene here by checking `user.has_usable_password`

        z account/email/password_reset_key)r   )rG   r   rI   r    rJ   rJ   rK   send_password_reset_mail[  s   z.DefaultAccountAdapter.send_password_reset_mailc                 C   s   ddl m} |j| j|S )zq
        Method intended to be overridden in case the password reset email
        needs to be adjusted.
        r   flows)allauth.account.internalr@  password_resetget_reset_password_from_key_urlrH   )rG   keyr@  rJ   rJ   rK   rC  e  s   z5DefaultAccountAdapter.get_reset_password_from_key_urlc                 C   s   ddl m} |j||S )zConstructs the email confirmation (activation) url.

        Note that if you have architected your system such that email
        confirmations are sent outside of the request context `request`
        can be `None` here.
        r   r?  )rA  r@  r  get_email_verification_url)rG   rH   emailconfirmationr@  rJ   rJ   rK   get_email_confirmation_urln  s   z0DefaultAccountAdapter.get_email_confirmation_urlc                 C   r   )NTrJ   )rG   rH   rb   r  rJ   rJ   rK   should_send_confirmation_mail{  r   z3DefaultAccountAdapter.should_send_confirmation_mailc                 C   sD   ddl m} |jtj}|jtj}||d}| d|| d S )Nr   r?  )
signup_urlpassword_reset_urlz$account/email/account_already_exists)	rA  r@  r  get_signup_urlr    rH   rB  get_reset_password_urlr   )rG   rI   r@  rI  rJ  r   rJ   rJ   rK    send_account_already_exists_mail~  s   z6DefaultAccountAdapter.send_account_already_exists_mailc                 C   sb   d|j ji}tjr|d|ji n||j| ||d |r$d}nd}| ||j j| d S )Nr   code)rD  activate_urlz'account/email/email_confirmation_signupz account/email/email_confirmation)	rb   r   r   "EMAIL_VERIFICATION_BY_CODE_ENABLEDr   rD  rG  r   rI   )rG   rH   rF  r  r   email_templaterJ   rJ   rK   send_confirmation_mail  s   z,DefaultAccountAdapter.send_confirmation_mailc                 C   r   )Nr*   r%   r   rJ   rJ   rK   r       z+DefaultAccountAdapter.respond_user_inactivec                 C   r   )Naccount_email_verification_sentrS  r   rJ   rJ   rK   respond_email_verification_sent  rT  z5DefaultAccountAdapter.respond_email_verification_sentc                 K   s0   t |}|d|dd }dj|j|dS )NrI   r;   r   z{site}:{login})rk   r   )r   rN   rQ   rh   domain)rG   rH   credentialsrk   r   rJ   rJ   rK   _get_login_attempts_cache_key  s   z3DefaultAccountAdapter._get_login_attempts_cache_keyc                 K   s*   | j |fi |}tj|tjd|d d S )Nlogin_failedconfigactionrD  )rY  r!   clearr   RATE_LIMITSrG   rH   rX  	cache_keyrJ   rJ   rK   #_delete_login_attempts_cached_email  s   
z9DefaultAccountAdapter._delete_login_attempts_cached_emailc                 C   s    t | dd }|r|  d S d S )N_login_failed_rl_usage)r   rollback)rG   usagerJ   rJ   rK   _rollback_login_failed_rl_usage  s   z5DefaultAccountAdapter._rollback_login_failed_rl_usagec                 K   s<   | j |fi |}tj|tjd|d| _| js| dd S )NrZ  r[  r8   )rY  r!   consumer   r_  rc  r   r`  rJ   rJ   rK   pre_authenticate  s   
z&DefaultAccountAdapter.pre_authenticatec                 K   sl   ddl m} | j|fi | |  t|fi |}| }|p"|}|r+|   |S | j|fi | |S )z8Only authenticates, does not actually login. See `login`r   r  )allauth.account.auth_backendsr  rh  unstash_authenticated_userr   rf  authentication_failed)rG   rH   rX  r  r   alt_userrJ   rJ   rK   r     s   z"DefaultAccountAdapter.authenticatec                 K      d S r   rJ   )rG   rH   rX  rJ   rJ   rK   rk    r   z+DefaultAccountAdapter.authentication_failedc           
      C   s   ddl m} ddlm} d|i}||}|r||d< |j|}|r&||d< tjjtj	v r:| 
|}|r:|d |d< | jtjfi |}	|	d uoM|	j|jkS )Nr   rU   )r   r   r;   rI   r   )rY   rV   allauth.account.utilsr   rZ   get_primary_emailr   r_   PHONEr^   	get_phoner   r    rH   rX   )
rG   r   r   rV   r   rX  r;   rI   phone_verifiedreauth_userrJ   rJ   rK   reauthenticate  s   
z$DefaultAccountAdapter.reauthenticatec                 C   s,   t |jddk|jdk|jddkgS )NHTTP_X_REQUESTED_WITHXMLHttpRequestr   HTTP_ACCEPT)anyMETArN   r   r   rJ   rJ   rK   is_ajax  s   zDefaultAccountAdapter.is_ajaxc                 C   s2   |j d}|r|dd }|S |j d}|S )NHTTP_X_FORWARDED_FOR,r   REMOTE_ADDR)ry  rN   split)rG   rH   x_forwarded_foriprJ   rJ   rK   get_client_ip  s   z#DefaultAccountAdapter.get_client_ipc                 C   s   |j ddS )NHTTP_USER_AGENTUnspecified)ry  rN   r   rJ   rJ   rK   get_http_user_agent  rM   z)DefaultAccountAdapter.get_http_user_agentc                 C   s   t d }|S )N@   )r   rQ   )rG   rI   rD  rJ   rJ   rK   generate_emailconfirmation_key  s   z4DefaultAccountAdapter.generate_emailconfirmation_keyc                 C   sb   g }| d | d | d tjr/ddlm} | d |jr'| d |jr/| d |S )	Nz'allauth.account.stages.LoginByCodeStagez-allauth.account.stages.PhoneVerificationStagez-allauth.account.stages.EmailVerificationStager   r   z$allauth.mfa.stages.AuthenticateStagezallauth.mfa.stages.TrustStagez.allauth.mfa.webauthn.stages.PasskeySignupStage)r  allauth_app_settingsMFA_ENABLEDallauth.mfar   TRUST_ENABLEDPASSKEY_SIGNUP_ENABLED)rG   rO   mfa_settingsrJ   rJ   rK   get_login_stages  s   





z&DefaultAccountAdapter.get_login_stagesc                 C   s   ddl m} dd ||D }g }d|v r$dtdtdd}|| d	|v rX|d	 d
 }d|v s6d|v rEd	tdtd	d}|| d|v rXdtdtdd}|| |S )zThe order of the methods returned matters. The first method is the
        default when using the `@reauthentication_required` decorator.
        r   )get_reauthentication_flowsc                 S   s   i | ]}|d  |qS )idrJ   )r   frJ   rJ   rK   r      s    zFDefaultAccountAdapter.get_reauthentication_methods.<locals>.<dictcomp>rt  zUse your passwordaccount_reauthenticate)r  descriptionr   mfa_reauthenticatetypesrecovery_codestotpzUse authenticator app or codewebauthnzmfa_reauthenticate:webauthnzUse a security keymfa_reauthenticate_webauthn)/allauth.account.internal.flows.reauthenticationr  _r   r  )rG   r   r  
flow_by_idrO   entryr  rJ   rJ   rK   get_reauthentication_methods  s0   


z2DefaultAccountAdapter.get_reauthentication_methodsc                 C   sn   ddl m} tjsd S |s|j|}|sd S t | | j	| 
| j	d}|r.|| | ||| d S )Nr   rU   )	timestampr  
user_agent)rY   rV   r   EMAIL_NOTIFICATIONSrZ   ro  r   nowr  rH   r  r   r   )rG   r}   r   r    rI   rV   r   rJ   rJ   rK   send_notification_mail;  s   


z,DefaultAccountAdapter.send_notification_mailc                 C      t  S )z-
        Generates a new login code.
        r#   rn   rJ   rJ   rK   generate_login_codeM     z)DefaultAccountAdapter.generate_login_codec                 C   s
   t ddS )z6
        Generates a new password reset code.
           )lengthr#   rn   rJ   rJ   rK   generate_password_reset_codeS  r   z2DefaultAccountAdapter.generate_password_reset_codec                 C   r  )z:
        Generates a new email verification code.
        r#   rn   rJ   rJ   rK    generate_email_verification_codeY  r  z6DefaultAccountAdapter.generate_email_verification_codec                 C   r  )z:
        Generates a new phone verification code.
        r#   rn   rJ   rJ   rK    generate_phone_verification_code_  r  z6DefaultAccountAdapter.generate_phone_verification_codec                 C   sd   ddl m} d}|| j}|r|d d }|dkrdS tj}t|tr&|S |s*dS |du p1||v S )z_
        Returns whether or not login-by-code is required for the given
        login.
        r   )authenticationNr   rN  F)allauth.accountr  get_authentication_recordsrH   r   LOGIN_BY_CODE_REQUIREDrt   bool)rG   r   r  r   recordsr  rJ   rJ   rK   is_login_by_code_requirede  s   
z/DefaultAccountAdapter.is_login_by_code_requiredc                 K   s   ddl m} |di |S )zC
        Returns a form field used to input phone numbers.
        r   )
PhoneFieldNrJ   )allauth.account.fieldsr  )rG   kwargsr  rJ   rJ   rK   phone_form_fieldy  s   z&DefaultAccountAdapter.phone_form_fieldc                 K   r   )z
        In case enumeration prevention is enabled, and, a verification code
        is requested for an unlisted phone number, this method is invoked to
        send a text explaining that no account is on file.
        NrJ   )rG   r   r  rJ   rJ   rK   send_unknown_account_sms     z.DefaultAccountAdapter.send_unknown_account_smsc                 C   rm  r   rJ   r   rJ   rJ   rK   send_account_already_exists_sms  r   z5DefaultAccountAdapter.send_account_already_exists_smsrN  c                 K      t )z,
        Sends a verification code.
        NotImplementedError)rG   r   r   rN  r  rJ   rJ   rK   send_verification_code_sms     z0DefaultAccountAdapter.send_verification_code_smsc                    s   d}t  fdd|D S )zO
        Checks whether the phone number adapter is fully implemented.
        )r  r   rq  set_phone_verifiedget_user_by_phonec                 3   s&    | ]}t  j|t t|kV  qd S r   )r   r  r)   )r   r   rn   rJ   rK   	<genexpr>  s
    
z8DefaultAccountAdapter._has_phone_impl.<locals>.<genexpr>)all)rG   methodsrJ   rn   rK   _has_phone_impl  s   z%DefaultAccountAdapter._has_phone_implverifiedc                 C   r  )zQ
        Sets the phone number (and verified status) for the given user.
        r  )rG   r   r   r  rJ   rJ   rK   r     r  zDefaultAccountAdapter.set_phonec                 C   r  )z
        Returns the phone number stored for the given user. A tuple of the
        phone number itself, and whether or not the phone number was verified is
        returned.
        r  )rG   r   rJ   rJ   rK   rq    r  zDefaultAccountAdapter.get_phonec                 C   r  )z
        Marks the specified phone number for the given user as
        verified. Note that the user is already expected to have
        the phone number attached to the account.
        r  )rG   r   r   rJ   rJ   rK   r    r  z(DefaultAccountAdapter.set_phone_verifiedc                 C   r  )zr
        Looks up a user given the specified phone number. Returns ``None`` if no user
        was found.
        r  r   rJ   rJ   rK   r    r   z'DefaultAccountAdapter.get_user_by_phoner   )T)F)NNr   N)NNN)rT   N)NN)Vr   r  __qualname____doc__r  r
   r)  r*  error_messagesrL   rP   rS   r  re   ru   rl   ro   r   dictr   r   r   r   r   r   r   r   r   r'   r   r   r   r   r   r   r   r   r   r  r  r   r	   r(  r   r.  r=  r>  rC  rG  rH  rM  rR  r  rV  rY  rb  rf  rh  r   rk  rt  rz  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  propertyr  r   typingOptionalTuplerq  r  r  rJ   rJ   rJ   rK   r)   ,   s   +

(		


!


!'

	
	
#r)   rT   c                 C   s   t tj| S r   )r(   r   ADAPTER)rH   rJ   rJ   rK   get_adapter  rM   r  r   )Grs   r   r  r   urllib.parser   django.confr   django.contribr   django.contrib.authr   r   r   r   r!  r	   r%  django.contrib.auth.modelsr
   'django.contrib.auth.password_validationr   r   django.contrib.sites.shortcutsr   django.core.exceptionsr   django.core.mailr   r   django.httpr   r   django.shortcutsr   django.templater   django.template.loaderr   django.urlsr   django.utilsr   django.utils.cryptor   django.utils.encodingr   django.utils.translationr   r  allauthr   r  r  r   allauth.corer    allauth.core.internalr!   allauth.core.internal.adapterr"   allauth.core.internal.cryptokitr$   allauth.core.internal.httpkitr%   r&   allauth.utilsr'   r(   r)   r  rJ   rJ   rJ   rK   <module>   sN           