U
    |e#C                     @   s  d dl Z d dlmZ d dlmZ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mZ d dlmZ d dlmZ e Z dd Z!G dd dej"Z#G dd dej$Z%G dd dej&Z'G dd dej(Z)G dd de)Z*G dd dej(Z+G dd dej,Z-G d d! d!ej,Z.G d"d# d#ej,Z/G d$d% d%e/Z0G d&d' d'ej,Z1dS )(    N)forms)authenticateget_user_modelpassword_validation)UNUSABLE_PASSWORD_PREFIXidentify_hasher)User)default_token_generator)get_current_site)ValidationError)EmailMultiAlternatives)loader)force_bytes)urlsafe_base64_encode)capfirst)gettext)gettext_lazyc                 C   s    t d|  t d| kS )z
    Perform case-insensitive comparison of two identifiers, using the
    recommended algorithm from Unicode Technical Report 36, section
    2.11.2(B)(2).
    NFKC)unicodedata	normalizecasefold)s1s2 r   V/var/www/website-v5/atlas_env/lib/python3.8/site-packages/django/contrib/auth/forms.py_unicode_ci_compare   s    r   c                       s,   e Zd ZdZdZ fddZdd Z  ZS )ReadOnlyPasswordHashWidgetz)auth/widgets/read_only_password_hash.htmlTc           	         s   t  |||}g }|r"|tr6|dtdi n`zt|}W n& tk
rh   |dtdi Y n.X ||	 D ]\}}|t||d qx||d< |S )NlabelzNo password set.z5Invalid password format or unknown hashing algorithm.)r   valuesummary)
superget_context
startswithr   appendr   r   
ValueErrorsafe_summaryitems)	selfnamer   attrscontextr   hasherkeyvalue_	__class__r   r   r!   %   s$     
z&ReadOnlyPasswordHashWidget.get_contextc                 C   s   d S Nr   )r'   id_r   r   r   id_for_label;   s    z'ReadOnlyPasswordHashWidget.id_for_label)__name__
__module____qualname__template_name	read_onlyr!   r2   __classcell__r   r   r.   r   r   !   s   r   c                       s    e Zd ZeZ fddZ  ZS )ReadOnlyPasswordHashFieldc                    s*   | dd | dd t j|| d S )NrequiredFdisabledT)
setdefaultr    __init__r'   argskwargsr.   r   r   r=   B   s    z"ReadOnlyPasswordHashField.__init__)r3   r4   r5   r   widgetr=   r8   r   r   r.   r   r9   ?   s   r9   c                       s(   e Zd Z fddZ fddZ  ZS )UsernameFieldc                    s   t dt |S )Nr   )r   r   r    	to_python)r'   r   r.   r   r   rC   I   s    zUsernameField.to_pythonc                    s   t  |dddS )Nnoneusername)Zautocapitalizeautocomplete)r    widget_attrs)r'   rA   r.   r   r   rG   L   s    
zUsernameField.widget_attrs)r3   r4   r5   rC   rG   r8   r   r   r.   r   rB   H   s   rB   c                       s   e Zd ZdZdediZejeddejddide	
 d	Zejed
ejddiddeddZG dd dZ fddZdd Z fddZd fdd	Z  ZS )BaseUserCreationFormzc
    A form that creates a user, with no privileges, from the given username and
    password.
    password_mismatch'   The two password fields didn’t match.PasswordFrF   new-passwordr)   )r   striprA   	help_textzPassword confirmation4Enter the same password as before, for verification.r   rA   rN   rO   c                   @   s   e Zd ZeZdZdeiZdS )zBaseUserCreationForm.Meta)rE   rE   Nr3   r4   r5   r   modelfieldsrB   field_classesr   r   r   r   Metaj   s   rV   c                    s:   t  j|| | jjj| jkr6d| j| jjj jjd< d S )NT	autofocus)r    r=   _metarS   USERNAME_FIELDrT   rA   r)   r>   r.   r   r   r=   o   s    zBaseUserCreationForm.__init__c                 C   s>   | j d}| j d}|r:|r:||kr:t| jd dd|S N	password1	password2rI   code)cleaned_datagetr   error_messagesr'   r[   r\   r   r   r   clean_password2v   s    z$BaseUserCreationForm.clean_password2c              
      s`   t    | jd}|r\zt|| j W n. tk
rZ } z| d| W 5 d }~X Y nX d S )Nr\   )	r    _post_cleanr_   r`   r   validate_passwordinstancer   	add_error)r'   passworderrorr.   r   r   rd      s    
z BaseUserCreationForm._post_cleanTc                    s@   t  jdd}|| jd  |r<|  t| dr<|   |S )NF)commitr[   save_m2m)r    saveset_passwordr_   hasattrrk   )r'   rj   userr.   r   r   rl      s    
zBaseUserCreationForm.save)T)r3   r4   r5   __doc___ra   r   	CharFieldPasswordInputr   "password_validators_help_text_htmlr[   r\   rV   r=   rc   rd   rl   r8   r   r   r.   r   rH   T   s*    
rH   c                   @   s   e Zd Zdd ZdS )UserCreationFormc                 C   sR   | j d}|rJ| jjjj|d rJ| td| j	
| jjdgi n|S dS )z*Reject usernames that differ only in case.rE   )Zusername__iexactN)r_   r`   rX   rS   objectsfilterexists_update_errorsr   rf   unique_error_message)r'   rE   r   r   r   clean_username   s       
zUserCreationForm.clean_usernameN)r3   r4   r5   r{   r   r   r   r   ru      s   ru   c                       s>   e Zd ZeededdZG dd dZ fddZ  ZS )UserChangeFormrK   u   Raw passwords are not stored, so there is no way to see this user’s password, but you can change the password using <a href="{}">this form</a>.)r   rO   c                   @   s   e Zd ZeZdZdeiZdS )zUserChangeForm.Meta__all__rE   NrR   r   r   r   r   rV      s   rV   c                    sZ   t  j|| | jd}|r8|jd| jj d|_| jd}|rV|j	d|_d S )Nrh   z../../z
/password/user_permissionscontent_type)
r    r=   rT   r`   rO   formatrf   pkquerysetselect_related)r'   r?   r@   rh   r~   r.   r   r   r=      s    zUserChangeForm.__init__)	r3   r4   r5   r9   rq   rh   rV   r=   r8   r   r   r.   r   r|      s   	r|   c                       s   e Zd ZdZeejddiddZeje	ddej
dd	idd
Ze	de	ddZd fdd	Zdd Zdd Zdd Zdd Z  ZS )AuthenticationFormzs
    Base class for authenticating users. Extend this to get a form that accepts
    username/password logins.
    rW   TrM   )rA   rK   FrF   current-passwordr   rN   rA   z^Please enter a correct %(username)s and password. Note that both fields may be case-sensitive.zThis account is inactive.)invalid_logininactiveNc                    s|   || _ d| _t j|| tjtj| _| jj	p4d}|| j
d _	|| j
d jjd< | j
d jdkrxt| jj| j
d _dS )z
        The 'request' parameter is set for custom auth use by subclasses.
        The form data comes in via the standard 'data' kwarg.
        N   rE   	maxlength)request
user_cacher    r=   	UserModelrX   	get_fieldrY   username_field
max_lengthrT   rA   r)   r   r   verbose_name)r'   r   r?   r@   Zusername_max_lengthr.   r   r   r=      s    zAuthenticationForm.__init__c                 C   s\   | j d}| j d}|d k	rV|rVt| j||d| _| jd krJ|  n| | j | j S )NrE   rh   )rE   rh   )r_   r`   r   r   r   get_invalid_login_errorconfirm_login_allowed)r'   rE   rh   r   r   r   clean   s      

zAuthenticationForm.cleanc                 C   s   |j st| jd dddS )a  
        Controls whether the given User may log in. This is a policy setting,
        independent of end-user authentication. This default behavior is to
        allow login by active users, and reject login by inactive users.

        If the given user cannot log in, this method should raise a
        ``ValidationError``.

        If the given user may log in, this method should return None.
        r   r]   N)	is_activer   ra   )r'   ro   r   r   r   r      s
    z(AuthenticationForm.confirm_login_allowedc                 C   s   | j S r0   )r   r'   r   r   r   get_user  s    zAuthenticationForm.get_userc                 C   s   t | jd dd| jjidS )Nr   rE   )r^   params)r   ra   r   r   r   r   r   r   r     s
    
z*AuthenticationForm.get_invalid_login_error)N)r3   r4   r5   rp   rB   r   	TextInputrE   rr   rq   rs   rh   ra   r=   r   r   r   r   r8   r   r   r.   r   r      s"   r   c                	   @   sZ   e Zd ZejeddejddiddZddd	Zd
d Z	dddde
ddddf	ddZdS )PasswordResetFormZEmailr   rF   emailrM   )r   r   rA   Nc                 C   sb   t ||}d| }t ||}t||||g}	|dk	rVt ||}
|	|
d |	  dS )zO
        Send a django.core.mail.EmailMultiAlternatives to `to_email`.
         Nz	text/html)r   render_to_stringjoin
splitlinesr   attach_alternativesend)r'   subject_template_nameemail_template_namer*   
from_emailZto_emailhtml_email_template_namesubjectbodyZemail_messageZ
html_emailr   r   r   	send_mail  s    zPasswordResetForm.send_mailc                    s6   t  t jjf d  ddi} fdd|D S )a  Given an email, return matching user(s) who should receive a reset.

        This allows subclasses to more easily customize the default policies
        that prevent inactive users and users with unusable passwords from
        resetting their password.
        z
%s__iexactr   Tc                 3   s*   | ]"}|  rt t|r|V  qd S r0   )has_usable_passwordr   getattr).0ur   email_field_namer   r   	<genexpr>E  s   z.PasswordResetForm.get_users.<locals>.<genexpr>)r   get_email_field_name_default_managerrw   )r'   r   Zactive_usersr   r   r   	get_users7  s      zPasswordResetForm.get_usersz'registration/password_reset_subject.txtz&registration/password_reset_email.htmlFc
              	   C   s   | j d }
|s$t|}|j}|j}n| }}t }| |
D ]X}t||}|||tt	|j
||||rpdndd|	p|i }| j||||||d q>dS )zf
        Generate a one-use only link for resetting password and send it to the
        user.
        r   httpshttp)r   domain	site_nameuidro   tokenprotocol)r   N)r_   r
   r(   r   r   r   r   r   r   r   r   Z
make_tokenr   )r'   Zdomain_overrider   r   Z	use_httpsZtoken_generatorr   r   r   Zextra_email_contextr   Zcurrent_siter   r   r   ro   Z
user_emailr*   r   r   r   rl   L  s6    



zPasswordResetForm.save)N)r3   r4   r5   r   
EmailFieldrq   
EmailInputr   r   r   r	   rl   r   r   r   r   r     s$    
r   c                       s   e Zd ZdZdediZejedejddidde	
 d	Zejed
dejddiddZ fddZdd ZdddZ  ZS )SetPasswordFormzZ
    A form that lets a user set their password without entering the old
    password
    rI   rJ   zNew passwordrF   rL   rM   FrQ   zNew password confirmationr   c                    s   || _ t j|| d S r0   ro   r    r=   r'   ro   r?   r@   r.   r   r   r=     s    zSetPasswordForm.__init__c                 C   sL   | j d}| j d}|r:|r:||kr:t| jd ddt|| j |S )Nnew_password1new_password2rI   r]   r_   r`   r   ra   r   re   ro   rb   r   r   r   clean_new_password2  s    z#SetPasswordForm.clean_new_password2Tc                 C   s*   | j d }| j| |r$| j  | jS )Nr   r_   ro   rm   rl   r'   rj   rh   r   r   r   rl     s
    

zSetPasswordForm.save)T)r3   r4   r5   rp   rq   ra   r   rr   rs   r   rt   r   r   r=   r   rl   r8   r   r   r.   r   r   z  s$    r   c                   @   sV   e Zd ZdZejdediZejeddej	dddd	d
Z
dddgZdd ZdS )PasswordChangeFormz[
    A form that lets a user change their password by entering their old
    password.
    password_incorrectzAYour old password was entered incorrectly. Please enter it again.zOld passwordFr   TrF   rW   rM   r   old_passwordr   r   c                 C   s,   | j d }| j|s(t| jd dd|S )zB
        Validate that the old_password field is correct.
        r   r   r]   )r_   ro   check_passwordr   ra   )r'   r   r   r   r   clean_old_password  s    
z%PasswordChangeForm.clean_old_passwordN)r3   r4   r5   rp   r   ra   rq   r   rr   rs   r   field_orderr   r   r   r   r   r     s     
r   c                       s   e Zd ZdZdediZdZejedej	dddd	d
e
 dZejedej	ddid	d
eddZ fddZdd ZdddZe fddZ  ZS )AdminPasswordChangeFormzN
    A form used to change the password of a user in the admin interface.
    rI   rJ   r:   rK   rL   Tr   rM   FrQ   zPassword (again)rF   rP   c                    s   || _ t j|| d S r0   r   r   r.   r   r   r=     s    z AdminPasswordChangeForm.__init__c                 C   sL   | j d}| j d}|r:|r:||kr:t| jd ddt|| j |S rZ   r   rb   r   r   r   rc     s    z'AdminPasswordChangeForm.clean_password2c                 C   s*   | j d }| j| |r$| j  | jS )zSave the new password.r[   r   r   r   r   r   rl     s
    

zAdminPasswordChangeForm.savec                    s*   t  j}| jD ]}||krg   S qdgS )Nrh   )r    changed_datarT   )r'   datar(   r.   r   r   r     s
    

z$AdminPasswordChangeForm.changed_data)T)r3   r4   r5   rp   rq   ra   required_css_classr   rr   rs   r   rt   r[   r\   r=   rc   rl   propertyr   r8   r   r   r.   r   r     s0    
r   )2r   djangor   django.contrib.authr   r   r   django.contrib.auth.hashersr   r   django.contrib.auth.modelsr   Zdjango.contrib.auth.tokensr	   Zdjango.contrib.sites.shortcutsr
   django.core.exceptionsr   django.core.mailr   django.templater   django.utils.encodingr   django.utils.httpr   django.utils.textr   django.utils.translationr   r   rq   r   r   Widgetr   Fieldr9   rr   rB   	ModelFormrH   ru   r|   Formr   r   r   r   r   r   r   r   r   <module>   s6   	AQb,#