o
    ˷eGW                     @   sn  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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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,m-Z. d dl/m0Z0 d dl1m2Z2 d dl3m4Z4 d dl5m6Z6m7Z7m8Z8m9Z9m:Z: ddl;m<Z< G dd de=Z>dddZ?dS )    N)	timedelta)forms)settings)messages)authenticateget_backendsloginlogout)AbstractUser)validate_password)get_current_site)EmailMessageEmailMultiAlternatives)HttpResponseHttpResponseRedirect)resolve_url)TemplateDoesNotExist)render_to_string)reverse)timezone)get_random_string	force_str)gettext_lazy)	ratelimit)signals)EmailVerificationMethod)build_absolute_uriemail_address_existsgenerate_unique_usernameget_user_modelimport_attribute   )app_settingsc                   @   s  e Zd Zedejdjd ededdZdidd	Zd
d Z	dd Z
dd Zdd Zdd Zdd Zdd Zdid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did*d+Zdjd-d.Zdkd0d1Zd2d3 Zdid4d5Zd6d7 Z		8dld9d:Zdmd;d<Z d=d> Z!d?d@ Z"dAdB Z#dCdD 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\ Z0d]d^ Z1d_d` Z2dadb Z3dcdd Z4dedf Z5dgdh Z6dS )nDefaultAccountAdapterz4Username can not be used. Please use other username.usernameuniquez0Too many failed login attempts. Try again later.z6A user is already registered with this e-mail address.)username_blacklistedusername_takentoo_many_login_attemptsemail_takenNc                 C   s
   || _ d S Nrequestselfr-    r0   N/var/www/ideatree/venv/lib/python3.10/site-packages/allauth/account/adapter.py__init__:      
zDefaultAccountAdapter.__init__c                 C      ||j d< d S Naccount_verified_emailsession)r/   r-   emailr0   r0   r1   stash_verified_email=      z*DefaultAccountAdapter.stash_verified_emailc                 C   s   |j d}d |j d< |S r5   )r8   get)r/   r-   retr0   r0   r1   unstash_verified_email@   s   
z,DefaultAccountAdapter.unstash_verified_emailc                 C   r4   Naccount_userr7   r/   r-   userr0   r0   r1   
stash_userE   r;   z DefaultAccountAdapter.stash_userc                 C   s   |j dd S r?   )r8   popr.   r0   r0   r1   unstash_userH   r;   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.
        Fr6   )r8   r<   lower)r/   r-   r9   r=   verified_emailr0   r0   r1   is_email_verifiedK   s
   z'DefaultAccountAdapter.is_email_verifiedc                 C   s2   t j}|d u rt| j}dj|jd}|t| S )Nz	[{name}] )name)r#   EMAIL_SUBJECT_PREFIXr   r-   formatrI   r   )r/   subjectprefixsiter0   r0   r1   format_email_subjectW   s
   
z*DefaultAccountAdapter.format_email_subjectc                 C   s   t jS )z
        This is a hook that can be overridden to programatically
        set the 'from' email address for sending emails
        )r   DEFAULT_FROM_EMAILr/   r0   r0   r1   get_from_email^   s   z$DefaultAccountAdapter.get_from_emailc              	   C   s   t |tr|gn|}td||}d|  }| |}|  }i }dD ]%}	zd||	}
t|
|| j	 ||	< W q( t
yM   |	dkrK|sK Y q(w d|v rkt||d |||d}d|v ri||d d |S t||d |||d}d|_|S )	z
        Renders an e-mail to `email`.  `template_prefix` identifies the
        e-mail that is to be sent, e.g. "account/email/email_confirmation"
        z{0}_subject.txt )htmltxtz{0}_message.{1}rU   )headersrT   z	text/html)
isinstancestrr   rK   join
splitlinesstriprO   rR   r-   r   r   attach_alternativer   content_subtype)r/   template_prefixr9   contextrV   torL   
from_emailbodiesexttemplate_namemsgr0   r0   r1   render_maile   s>   

z!DefaultAccountAdapter.render_mailc                 C   s   |  |||}|  d S r+   )rf   send)r/   r^   r9   r_   re   r0   r0   r1   	send_mail   s   zDefaultAccountAdapter.send_mailc                 C   
   t tjS r+   )r   r#   SIGNUP_REDIRECT_URLr.   r0   r0   r1   get_signup_redirect_url   r3   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)	rB   is_authenticatedgetattrr   warningswarnDeprecationWarningLOGIN_REDIRECT_URLr   )r/   r-   urlr0   r0   r1   get_login_redirect_url   s   z,DefaultAccountAdapter.get_login_redirect_urlc                 C   ri   )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.   r0   r0   r1   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 )zL
        The URL to return to after successful e-mail confirmation.
        )rB   rm   r#   -EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URLrt   )EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URLr.   r0   r0   r1   #get_email_confirmation_redirect_url   s
   
z9DefaultAccountAdapter.get_email_confirmation_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
        Tr0   r.   r0   r0   r1   is_open_for_signup   s   z(DefaultAccountAdapter.is_open_for_signupc                 C   s   t   }|S )z3
        Instantiates a new User instance.
        )r    rA   r0   r0   r1   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_namerB   N)utilsr}   r~   r   r#   USER_MODEL_USERNAME_FIELDr   )
r/   r-   rB   r}   r~   r   r   r   r9   r%   r0   r0   r1   populate_username   s   

z'DefaultAccountAdapter.populate_usernamec                 C   s
   t ||S r+   )r   )r/   txtsregexr0   r0   r1   r      r3   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   r9   r%   	password1)
r   r}   r~   r   cleaned_datar<   set_passwordset_unusable_passwordr   save)r/   r-   rB   formcommitr}   r~   r   datar   r   r9   r%   r0   r0   r1   	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 r0   )rF   ).0ubr0   r0   r1   
<listcomp>  s    z8DefaultAccountAdapter.clean_username.<locals>.<listcomp>r'   r"   )filter_users_by_usernamer&   r(   )
model_namefield_label)params)r#   USERNAME_VALIDATORSUSERNAME_BLACKLISTrF   r   ValidationErrorerror_messagesr   r   existsr    r   _meta	get_fieldr<   __name__)	r/   r%   shallow	validatorusername_blacklist_lowerr   
user_modelusername_fielderror_messager0   r0   r1   clean_username   s4   


z$DefaultAccountAdapter.clean_usernamec                 C   s   |S )z
        Validates an email value. You can hook into this if you want to
        (dynamically) restrict what email addresses can be chosen.
        r0   r/   r9   r0   r0   r1   clean_email!  s   z!DefaultAccountAdapter.clean_emailc                 C   s8   t j}|rt||k rttd|t|| |S )z{
        Validates a password. You can hook into this if you want to
        restric the allowed password choices.
        z-Password must be a minimum of {0} characters.)r#   PASSWORD_MIN_LENGTHlenr   r   _rK   r   )r/   passwordrB   
min_lengthr0   r0   r1   clean_password(  s   
z$DefaultAccountAdapter.clean_passwordc                 C   s   t |rt| jd |S )Nr*   )r   r   r   r   r   r0   r0   r1   validate_unique_email5  s   z+DefaultAccountAdapter.validate_unique_email c                 C   sn   dt jv r5z%|du ri }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-   r[   rT   unescaper   add_messager   )r/   r-   levelmessage_templatemessage_contextr   escaped_messagemessager0   r0   r1   r   :  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utf8rT   r   application/json)statuscontent_type)status_codemethodis_validajax_response_formhasattrr   contentdecoder   jsondumps)r/   r-   responseredirect_tor   r   respr   r0   r0   r1   ajax_responseU  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 r0   r   )r   er0   r0   r1   r   y  s    z<DefaultAccountAdapter.ajax_response_form.<locals>.<listcomp>attrsc                 S   s   i | ]	\}}|t |qS r0   r   )r   kvr0   r0   r1   
<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)r/   r   	form_specr   
field_specr0   r0   r1   r   n  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)signupr9   )
r   r   r   	is_activerespond_user_inactiver   NONEOPTIONAL	MANDATORYrespond_email_verification_sent)
r/   r-   rB   email_verificationsignal_kwargsr9   r   redirect_urlr   r   r0   r0   r1   	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"   )rt   )r   )senderr-   r   rB   zaccount/messages/logged_in.txtrB   r0   )
r   rt   r   r   user_logged_inrg   	__class__r   r   SUCCESS)
r/   r-   rB   r   r   r9   r   r   rt   r   r0   r0   r1   
post_login  s*   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   rW   rY   
__module__r   r   r   django_login)r/   r-   rB   r   backendsr   bbackend_pathr0   r0   r1   r     s   

zDefaultAccountAdapter.loginc                 C   s   t | d S r+   )django_logoutr.   r0   r0   r1   r	        zDefaultAccountAdapter.logoutc                 C   s   d|_ |jdd |  dS )z@
        Marks the email address as confirmed on the db
        T)conditionalN)verifiedset_as_primaryr   )r/   r-   email_addressr0   r0   r1   confirm_email  s   z#DefaultAccountAdapter.confirm_emailc                 C   s   | | |  d S r+   )r   r   )r/   rB   r   r0   r0   r1   r     s   
z"DefaultAccountAdapter.set_passwordc                    s$   t    t fddtjdddgS )Nc                    s   | ot  | S r+   )r   )arB   r0   r1   <lambda>  s    z>DefaultAccountAdapter.get_user_search_fields.<locals>.<lambda>r   r   r9   )r    filterr#   r   rQ   r0   r  r1   get_user_search_fields  s   
z,DefaultAccountAdapter.get_user_search_fieldsc                 C   s<   zddl m} W n ty   ddl m} Y nw ||d dS )Nr   )url_has_allowed_host_and_scheme)is_safe_url)allowed_hosts)django.utils.httpr
  ImportErrorr  )r/   rs   r
  r0   r0   r1   r    s   z!DefaultAccountAdapter.is_safe_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   keyr   )r/   r-   emailconfirmationrs   r=   r0   r0   r1   get_email_confirmation_url  s   
z0DefaultAccountAdapter.get_email_confirmation_urlc                 C   sb   ddl m} ttjd}tjr tj|d|j	 d|
 d}|S |jjt | |d  }|S )Nr   )EmailConfirmation)secondsr  r"   actionr  amountduration)sent__gtr  )allauth.account.modelsr  r   r#   EMAIL_CONFIRMATION_COOLDOWNEMAIL_CONFIRMATION_HMACr   consumer9   rF   total_secondsobjectsr  r   nowr   )r/   r-   r  r  cooldown_period
send_emailr0   r0   r1   should_send_confirmation_mail  s$   
z3DefaultAccountAdapter.should_send_confirmation_mailc                 C   sL   t |}| ||}|jj|||jd}|rd}nd}| ||jj| d S )N)rB   activate_urlcurrent_siter  z'account/email/email_confirmation_signupz account/email/email_confirmation)r   r  r  rB   r  rh   r9   )r/   r-   r  r   r&  r%  ctxemail_templater0   r0   r1   send_confirmation_mail  s   z,DefaultAccountAdapter.send_confirmation_mailc                 C      t tdS )Naccount_inactiver   r   rA   r0   r0   r1   r   '  r   z+DefaultAccountAdapter.respond_user_inactivec                 C   r*  )Naccount_email_verification_sentr,  rA   r0   r0   r1   r   *  r   z5DefaultAccountAdapter.respond_email_verification_sentc                 K   s0   t |}|d|dd }dj|j|dS )Nr9   r%   r   z{site}:{login})rN   r   )r   r<   rF   rK   domain)r/   r-   credentialsrN   r   r0   r0   r1   _get_login_attempts_cache_key-  s   z3DefaultAccountAdapter._get_login_attempts_cache_keyc                 K   s0   t jr| j|fi |}tj|d|d d S d S )Nlogin_failed)r  r  )r#   LOGIN_ATTEMPTS_LIMITr0  r   clearr/   r-   r/  	cache_keyr0   r0   r1   #_delete_login_attempts_cached_email2  s   z9DefaultAccountAdapter._delete_login_attempts_cached_emailc                 K   sH   t jr | j|fi |}tj|d|t jt jds"t| jd d S d S )Nr1  r  r)   )	r#   r2  r0  r   r  LOGIN_ATTEMPTS_TIMEOUTr   r   r   r4  r0   r0   r1   pre_authenticate7  s   z&DefaultAccountAdapter.pre_authenticatec                 K   s|   ddl m} | j|fi | |  t|fi |}| }|p"|}|r3tjr3| j|fi | |S | j|fi | |S )z8Only authenticates, does not actually login. See `login`r   r   )	allauth.account.auth_backendsr   r8  unstash_authenticated_userr   r#   r2  r6  authentication_failed)r/   r-   r/  r   rB   alt_userr0   r0   r1   r   E  s   
z"DefaultAccountAdapter.authenticatec                 K   s   d S r+   r0   )r/   r-   r/  r0   r0   r1   r;  T  s   z+DefaultAccountAdapter.authentication_failedc                 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METAr<   r   r.   r0   r0   r1   is_ajaxW  s   zDefaultAccountAdapter.is_ajaxc                 C   s2   |j d}|r|dd }|S |j d}|S )NHTTP_X_FORWARDED_FOR,r   REMOTE_ADDR)rA  r<   split)r/   r-   x_forwarded_foripr0   r0   r1   get_client_ip`  s   z#DefaultAccountAdapter.get_client_ipc                 C   s   t d }|S )N@   )r   rF   )r/   r9   r  r0   r0   r1   generate_emailconfirmation_keyh  s   z4DefaultAccountAdapter.generate_emailconfirmation_keyr+   )T)F)Nr   )NNN)7r   r   __qualname__r   r
   r   r   r   r2   r:   r>   rC   rE   rH   rO   rR   rf   rh   rk   rt   rv   ry   rz   r{   r   r   r   r   r   r   r   r   r   r   r   r   r   r	   r  r   r	  r  r  r$  r)  r   r   r0  r6  r8  r   r;  rB  rI  rK  r0   r0   r0   r1   r$   +   sz    

%		


$



"
	r$   c                 C   s   t tj| S r+   )r!   r#   ADAPTERr,   r0   r0   r1   get_adapterm  r;   rN  r+   )@rT   r   ro   datetimer   djangor   django.confr   django.contribr   django.contrib.authr   r   r   r   r	   r   django.contrib.auth.modelsr
   'django.contrib.auth.password_validationr   django.contrib.sites.shortcutsr   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   allauth.accountr   allauth.account.app_settingsr   allauth.utilsr   r   r   r    r!   r   r#   objectr$   rN  r0   r0   r0   r1   <module>   s@        F