o
    Lfm                     @   s  d dl Z d dlZd dl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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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l0m1Z2 d dl3m4Z5 d dl6m7Z7 d dl8m9Z9m:Z: d dl;m<Z<m=Z= d dl>m?Z?m@Z@mAZA ddlBm4Z4 G dd deCZDdddZEdS )     N)quoteurlparse)forms)settings)messages)authenticateget_backendsget_user_modelloginlogout)AbstractUser)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)signals)AuthenticationMethodEmailVerificationMethod)context	ratelimit)build_absolute_urigenerate_unique_usernameimport_attribute   c                	   @   s"  e Zd Zedejdjd edededededed	d
ZdddZdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd ZdddZd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Zdd2d3Zdd5d6Zdd8d9Zd:d; Zdd<d=Zd>d? Z 		@ddAdBZ!ddCdDZ"dEdF Z#dGdH Z$dIdJ Z%dKdL Z&dMdN Z'dOdP Z(dQdR Z)dSdT Z*dUdV Z+dWdX Z,dYdZ Z-d[d\ Z.d]d^ Z/d_d` Z0dadb Z1dcdd Z2dedf Z3dgdh Z4didj Z5dkdl Z6dmdn Z7dodp Z8dqdr Z9dsdt Z:dudv Z;dwdx Z<dydz Z=d{d| Z>dd}d~Z?dS )DefaultAccountAdapterz4Username can not be used. Please use other username.usernameuniquez0Too many failed login attempts. Try again later.z5A user is already registered with this email address.z"Please type your current password.zIncorrect password.z-Password must be a minimum of {0} characters.z5The email address is not assigned to any user account)username_blacklistedusername_takentoo_many_login_attemptsemail_takenenter_current_passwordincorrect_passwordpassword_min_lengthunknown_emailNc                 C   s   t j| _d S N)r"   requestselfr4    r7   X/var/www/html/humari/django-venv/lib/python3.10/site-packages/allauth/account/adapter.py__init__A   s   zDefaultAccountAdapter.__init__c                 C      ||j d< d S Naccount_verified_emailsession)r6   r4   emailr7   r7   r8   stash_verified_emailF      z*DefaultAccountAdapter.stash_verified_emailc                 C   s   |j d}d |j d< |S r;   )r>   get)r6   r4   retr7   r7   r8   unstash_verified_emailI   s   
z,DefaultAccountAdapter.unstash_verified_emailc                 C   r:   Naccount_userr=   r6   r4   userr7   r7   r8   
stash_userN   rA   z DefaultAccountAdapter.stash_userc                 C   s   |j dd S rE   )r>   popr5   r7   r7   r8   unstash_userQ   rA   z"DefaultAccountAdapter.unstash_userc                 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.
        Fr<   )r>   rB   lower)r6   r4   r?   rC   verified_emailr7   r7   r8   is_email_verifiedT   s
   z'DefaultAccountAdapter.is_email_verifiedc                 C   sd   ddl m} |jj|jdj|jd }tj	t
jk}|jr(|r"dS |r&dS dS |r,dS |r0dS dS )Nr   EmailAddressuser_idpkFT)allauth.account.modelsrP   objectsfilterrR   excluderT   existsr   AUTHENTICATION_METHODr    EMAILprimary)r6   email_addressrP   	has_otherlogin_by_emailr7   r7   r8   can_delete_email`   s&   
z&DefaultAccountAdapter.can_delete_emailc                 C   s2   t j}|d u rttj}dj|jd}|t| S )Nz	[{name}] )name)r   EMAIL_SUBJECT_PREFIXr   r"   r4   formatra   r   )r6   subjectprefixsiter7   r7   r8   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)r6   r7   r7   r8   get_from_email   s   z$DefaultAccountAdapter.get_from_emailc              	   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   rc   join
splitlinesstriprg   ri   r   TEMPLATE_EXTENSIONglobalsr4   r   r   attach_alternativer   content_subtype)r6   template_prefixr?   r"   rl   tord   
from_emailbodieshtml_extexttemplate_namemsgr7   r7   r8   render_mail   sD   


z!DefaultAccountAdapter.render_mailc                 C   s:   |t t d jd}|| | |||}|  d S )Nr"   )r?   current_site)r   rt   r4   updater   send)r6   rw   r?   r"   ctxr~   r7   r7   r8   	send_mail   s   
zDefaultAccountAdapter.send_mailc                 C   
   t tjS r3   )r   r   SIGNUP_REDIRECT_URLr5   r7   r7   r8   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)	rH   is_authenticatedgetattrr   warningswarnDeprecationWarningLOGIN_REDIRECT_URLr   )r6   r4   urlr7   r7   r8   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_URLr5   r7   r7   r8   get_logout_redirect_url   s   
z-DefaultAccountAdapter.get_logout_redirect_urlc                 C   s$   |j jrtjr
tjS | |S tjS )zK
        The URL to return to after successful email confirmation.
        )rH   r   r   -EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URLr   )EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URLr5   r7   r7   r8   #get_email_confirmation_redirect_url   s
   
z9DefaultAccountAdapter.get_email_confirmation_redirect_urlc                 C   s   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   r5   r7   r7   r8    get_password_change_redirect_url   s   z6DefaultAccountAdapter.get_password_change_redirect_urlc                 C   s   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
        Tr7   r5   r7   r7   r8   is_open_for_signup   s   z(DefaultAccountAdapter.is_open_for_signupc                 C   s   t   }|S )z3
        Instantiates a new User instance.
        )r	   rG   r7   r7   r8   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).
        r'   
user_email
user_fielduser_username
first_name	last_namerH   N)utilsr   r   r   r   USER_MODEL_USERNAME_FIELDr%   )
r6   r4   rH   r   r   r   r   r   r?   r)   r7   r7   r8   populate_username   s   

z'DefaultAccountAdapter.populate_usernamec                 C   s
   t ||S r3   )r%   )r6   txtsregexr7   r7   r8   r%     r   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|  | || |rW|	  |S )zd
        Saves a new `User` instance using information provided in the
        signup form.
        r'   r   r   r   r?   r)   	password1)
r   r   r   r   cleaned_datarB   set_passwordset_unusable_passwordr   save)r6   r4   rH   formcommitr   r   r   datar   r   r?   r)   r7   r7   r8   	save_user  s&   





zDefaultAccountAdapter.save_userFc           	      C   s   t jD ]}|| qdd t jD }| |v r t| jd |sPddlm} ||	 rPt
 }t j}|j|jd}|sE| jd }tj||j|d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 r7   )rL   ).0ubr7   r7   r8   
<listcomp><  s    z8DefaultAccountAdapter.clean_username.<locals>.<listcomp>r+   r'   )filter_users_by_usernamer*   r,   )
model_namefield_label)params)r   USERNAME_VALIDATORSUSERNAME_BLACKLISTrL   r   ValidationErrorerror_messagesr   r   rY   r	   r   _meta	get_fieldrB   __name__)	r6   r)   shallow	validatorusername_blacklist_lowerr   
user_modelusername_fielderror_messager7   r7   r8   clean_username3  s4   


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.
        r7   r6   r?   r7   r7   r8   clean_emailW  s   z!DefaultAccountAdapter.clean_emailc                 C   s:   t j}|rt||k rt| jd |t|| |S )z{
        Validates a password. You can hook into this if you want to
        restric the allowed password choices.
        r1   )r   PASSWORD_MIN_LENGTHlenr   r   r   rc   r   )r6   passwordrH   
min_lengthr7   r7   r8   clean_password^  s   
z$DefaultAccountAdapter.clean_passwordc                 C   r   r3   r7   r   r7   r7   r8   validate_unique_emailk     z+DefaultAccountAdapter.validate_unique_email c                 C   sn   dt jv r5z%|du ri }t||tj }|r(t|}tj	||||d W dS W dS  t
y4   Y dS w dS )zx
        Wrapper of `django.contrib.messages.add_message`, that reads
        the message text from a template.
        zdjango.contrib.messagesN)
extra_tags)r   INSTALLED_APPSr   r"   r4   rr   rm   unescaper   add_messager   )r6   r4   levelmessage_templatemessage_contextr   escaped_messagemessager7   r7   r8   r   n  s&   

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utf8rm   r   application/json)statuscontent_type)status_codemethodis_validajax_response_formhasattrr   contentdecoder   jsondumps)r6   r4   responseredirect_tor   r   respr   r7   r7   r8   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 r7   r   )r   er7   r7   r8   r     s    z<DefaultAccountAdapter.ajax_response_form.<locals>.<listcomp>attrsc                 S   s   i | ]	\}}|t |qS r7   r   )r   kvr7   r7   r8   
<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)r6   r   	form_specr   
field_specr7   r7   r8   r     s"   z(DefaultAccountAdapter.ajax_response_formc          
      C   s   ddl m}m}	 |js| ||S |tjkrd S |tjkr2|||s.|r0|	||||d d S d S d S |tjkrJ|||sL|	||||d | 	||S d S d S )Nr'   )has_verified_emailsend_email_confirmation)signupr?   )
r   r   r  	is_activerespond_user_inactiver!   NONEOPTIONAL	MANDATORYrespond_email_verification_sent)
r6   r4   rH   email_verificationsignal_kwargsr?   r  redirect_urlr   r  r7   r7   r8   	pre_login  s   



zDefaultAccountAdapter.pre_loginc          
      C   sb   ddl m} t||||d}	|d u ri }tjjd|j||	|d| | |tj	dd|i |	S )Nr'   )r   )r  )senderr4   r   rH   zaccount/messages/logged_in.txtrH   r7   )
r   r   r   r   user_logged_inr   	__class__r   r   SUCCESS)
r6   r4   rH   r	  r
  r?   r  r  r   r   r7   r7   r8   
post_login  s*   z DefaultAccountAdapter.post_loginc           	      C   s   ddl m} t|ds:ddlm} t }d }|D ]}t||r#|} n
|s,t|dr,|}qd|j|j	j
g}||_t|| ||| d S )Nr   )record_authenticationbackendr'   AuthenticationBackendget_user.) allauth.account.reauthenticationr  r   auth_backendsr  r   rn   rp   
__module__r  r   r  django_login)	r6   r4   rH   r  r  backendsr  bbackend_pathr7   r7   r8   r
     s    


zDefaultAccountAdapter.loginc                 C   s   t | d S r3   )django_logoutr5   r7   r7   r8   r        zDefaultAccountAdapter.logoutc                 C   s   ddl m} ddlm} |jj|jdj|jd	 }|j
dds#dS |jtj d |jd	d
gd tjrP|jj|jdj|jdD ]}|  qC|||| dS )z@
        Marks the email address as confirmed on the db
        r   rO   )emit_email_changedrQ   rS   F)r   )conditionalverifiedr\   )update_fieldsT)rU   rP   allauth.account.utilsr!  rV   rW   rR   rX   rT   firstset_verifiedset_as_primaryr   CHANGE_EMAILr   remove)r6   r4   r]   rP   r!  from_email_addressinstancer7   r7   r8   confirm_email  s(   

z#DefaultAccountAdapter.confirm_emailc                 C   s   | | |  d S r3   )r   r   )r6   rH   r   r7   r7   r8   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   r?   )r	   r   r   r   r   r   r   )r6   rC   User
candidates	candidater7   r7   r8   get_user_search_fields+  s   z,DefaultAccountAdapter.get_user_search_fieldsc                 C   sZ   ddl m} tj httjB }d|v r't|j	}|r|hnd }|||dS |||dS )Nr   )url_has_allowed_host_and_scheme*)allowed_hosts)
django.utils.httpr2  r"   r4   get_hostsetr   ALLOWED_HOSTSr   netloc)r6   r   r2  r4  parsed_hostallowed_hostr7   r7   r8   is_safe_url<  s   
z!DefaultAccountAdapter.is_safe_urlc                 C   s.   t ddddd}|dt|}t| j|S )z
        Method intented to be overriden in case the password reset email
        needs to point to your frontend/SPA.
        account_reset_password_from_keyUIDKEY)uidb36key)kwargszUID-KEY)r   replacer   r$   r4   )r6   rA  pathr7   r7   r8   get_reset_password_from_key_urlI  s
   
z5DefaultAccountAdapter.get_reset_password_from_key_urlc                 C   s   t d|jgd}t||}|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.
        account_confirm_email)args)r   rA  r$   )r6   r4   emailconfirmationr   rC   r7   r7   r8   get_email_confirmation_urlW  s   
z0DefaultAccountAdapter.get_email_confirmation_urlc                 C   s   t j|d|j d}|S )Nr-  actionrA  )r#   consumer?   rL   )r6   r4   r]   r  
send_emailr7   r7   r8   should_send_confirmation_mailb  s   z3DefaultAccountAdapter.should_send_confirmation_mailc                 C   s@   t tjtd}t tjtd}tj||d}| d|| d S )Naccount_signupaccount_reset_password)r4   
signup_urlpassword_reset_urlz$account/email/account_already_exists)r$   r"   r4   r   r   )r6   r?   rQ  rR  r   r7   r7   r8    send_account_already_exists_mailj  s   
z6DefaultAccountAdapter.send_account_already_exists_mailc                 C   sB   |  ||}|jj||jd}|rd}nd}| ||jj| d S )N)rH   activate_urlrA  z'account/email/email_confirmation_signupz account/email/email_confirmation)rI  r]   rH   rA  r   r?   )r6   r4   rH  r  rT  r   email_templater7   r7   r8   send_confirmation_mailv  s   z,DefaultAccountAdapter.send_confirmation_mailc                 C      t tdS )Naccount_inactiver   r   rG   r7   r7   r8   r    r   z+DefaultAccountAdapter.respond_user_inactivec                 C   rW  )Naccount_email_verification_sentrY  rG   r7   r7   r8   r    r   z5DefaultAccountAdapter.respond_email_verification_sentc                 K   s0   t |}|d|dd }dj|j|dS )Nr?   r)   r   z{site}:{login})rf   r
   )r   rB   rL   rc   domain)r6   r4   credentialsrf   r
   r7   r7   r8   _get_login_attempts_cache_key  s   z3DefaultAccountAdapter._get_login_attempts_cache_keyc                 K   s&   | j |fi |}tj|d|d d S )Nlogin_failedrJ  )r]  r#   clearr6   r4   r\  	cache_keyr7   r7   r8   #_delete_login_attempts_cached_email  s   z9DefaultAccountAdapter._delete_login_attempts_cached_emailc                 K   s6   | j |fi |}tj|d|dst| jd d S )Nr^  rJ  r-   )r]  r#   rL  r   r   r   r`  r7   r7   r8   pre_authenticate  s   z&DefaultAccountAdapter.pre_authenticatec                 K   sv   ddl m} | j|fi | |  t|fi |}| }|p"|}|r0| j|fi | |S | j|fi | |S )z8Only authenticates, does not actually login. See `login`r   r  )allauth.account.auth_backendsr  rc  unstash_authenticated_userr   rb  authentication_failed)r6   r4   r\  r  rH   alt_userr7   r7   r8   r     s   z"DefaultAccountAdapter.authenticatec                 K   s   d S r3   r7   )r6   r4   r\  r7   r7   r8   rf    r   z+DefaultAccountAdapter.authentication_failedc           	      C   st   ddl m} ddlm} d|i}||}|r||d< |j|}|r&||d< | jtjfi |}|d uo9|j	|j	kS )Nr   rO   )r   r   r)   r?   )
rU   rP   r%  r   rV   get_primary_emailr   r"   r4   rT   )	r6   rH   r   rP   r   r\  r)   r?   reauth_userr7   r7   r8   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METArB   r   r5   r7   r7   r8   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)ro  rB   split)r6   r4   x_forwarded_foripr7   r7   r8   get_client_ip  s   z#DefaultAccountAdapter.get_client_ipc                 C   s   |j ddS )NHTTP_USER_AGENTUnspecified)ro  rB   r5   r7   r7   r8   get_http_user_agent  rA   z)DefaultAccountAdapter.get_http_user_agentc                 C   s   t d }|S )N@   )r   rL   )r6   r?   rA  r7   r7   r8   generate_emailconfirmation_key  s   z4DefaultAccountAdapter.generate_emailconfirmation_keyc                 C   s   g }t jr
|d |S )Nz$allauth.mfa.stages.AuthenticateStage)allauth_app_settingsMFA_ENABLEDr   )r6   rC   r7   r7   r8   get_login_stages  s   
z&DefaultAccountAdapter.get_login_stagesc                 C   sd   g }|j s|S | r|tdtdd tjr0ddlm} ||r0|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.
        zUse your passwordaccount_reauthenticate)descriptionr   r   )is_mfa_enabledzUse your authenticator appmfa_reauthenticate)	r   has_usable_passwordr   _r   r}  r~  allauth.mfa.utilsr  )r6   rH   rC   r  r7   r7   r8   get_reauthentication_methods  s$   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   rO   )	timestamprv  
user_agent)rU   rP   r   EMAIL_NOTIFICATIONSrV   rh  r   nowrw  r4   rz  r   r   )r6   rw   rH   r"   r?   rP   r   r7   r7   r8   send_notification_mail  s   


z,DefaultAccountAdapter.send_notification_mailr3   )T)F)Nr   )NNN)NN)@r   r  __qualname__r  r   r   r   r   r9   r@   rD   rI   rK   rN   r`   rg   ri   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   r1  r<  rE  rI  rN  rS  rV  r  r  r]  rb  rc  r   rf  rj  rp  rw  rz  r|  r  r  r  r7   r7   r7   r8   r(   /   s    

(			


$


"		r(   c                 C   s   t tj| S r3   )r&   r   ADAPTER)r4   r7   r7   r8   get_adapter  rA   r  r3   )Frm   r   r   urllib.parser   r   djangor   django.confr   django.contribr   django.contrib.authr   r   r	   r
   r  r   r  django.contrib.auth.modelsr   'django.contrib.auth.password_validationr   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}  allauth.accountr   allauth.account.app_settingsr    r!   allauth.corer"   r#   allauth.utilsr$   r%   r&   r   objectr(   r  r7   r7   r7   r8   <module>   sF         \