a
    xd?                     @   sx  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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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+Z0d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   Q/var/www/html/Ranjet/env/lib/python3.9/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  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yf   |dtdi Y n.0 ||	 D ]\}}|t||d qv||d< |S )NlabelzNo password set.z5Invalid password format or unknown hashing algorithm.)r   valuesummary)
superget_context
startswithr   appendr   r   
ValueErrorZsafe_summaryitems)	selfnamer   attrscontextr   ZhasherkeyZvalue_	__class__r   r   r!   %   s    z&ReadOnlyPasswordHashWidget.get_context)__name__
__module____qualname__Ztemplate_nameZ	read_onlyr!   __classcell__r   r   r+   r   r   !   s   r   c                       s0   e Zd ZeZ fddZdd Zdd Z  ZS )ReadOnlyPasswordHashFieldc                    s"   | dd t j|i | d S )NrequiredF)
setdefaultr    __init__r&   argskwargsr+   r   r   r4   9   s    z"ReadOnlyPasswordHashField.__init__c                 C   s   |S Nr   )r&   datainitialr   r   r   
bound_data=   s    z$ReadOnlyPasswordHashField.bound_datac                 C   s   dS )NFr   )r&   r:   r9   r   r   r   has_changedB   s    z%ReadOnlyPasswordHashField.has_changed)	r-   r.   r/   r   widgetr4   r;   r<   r0   r   r   r+   r   r1   6   s   r1   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   r?   G   s    zUsernameField.to_pythonc                    s   i t  |dddS )Nnoneusername)Zautocapitalizeautocomplete)r    widget_attrs)r&   r=   r+   r   r   rC   J   s    
zUsernameField.widget_attrs)r-   r.   r/   r?   rC   r0   r   r   r+   r   r>   F   s   r>   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 )UserCreationFormzc
    A form that creates a user, with no privileges, from the given username and
    password.
    password_mismatch'   The two password fields didn’t match.PasswordFrB   new-passwordr(   )r   stripr=   	help_textzPassword confirmation4Enter the same password as before, for verification.r   r=   rJ   rK   c                   @   s   e Zd ZeZdZdeiZdS )zUserCreationForm.Meta)rA   rA   Nr-   r.   r/   r   modelfieldsr>   Zfield_classesr   r   r   r   Metag   s   rQ   c                    s>   t  j|i | | jjj| jv r:d| j| jjj jjd< d S )NT	autofocus)r    r4   _metarO   USERNAME_FIELDrP   r=   r(   r5   r+   r   r   r4   l   s    zUserCreationForm.__init__c                 C   s>   | j d}| j d}|r:|r:||kr:t| jd dd|S N	password1	password2rE   code)cleaned_datagetr   error_messagesr&   rV   rW   r   r   r   clean_password2q   s    z UserCreationForm.clean_password2c              
      sb   t    | jd}|r^zt|| j W n0 ty\ } z| d| W Y d }~n
d }~0 0 d S )NrW   )	r    _post_cleanrZ   r[   r   validate_passwordinstancer   Z	add_error)r&   passworderrorr+   r   r   r_   {   s    
zUserCreationForm._post_cleanTc                    s.   t  jdd}|| jd  |r*|  |S )NF)commitrV   )r    saveset_passwordrZ   )r&   rd   userr+   r   r   re      s
    zUserCreationForm.save)T)r-   r.   r/   __doc___r\   r   	CharFieldPasswordInputr   "password_validators_help_text_htmlrV   rW   rQ   r4   r^   r_   re   r0   r   r   r+   r   rD   R   s(   
rD   c                       sF   e Zd ZeededdZG dd dZ fddZdd	 Z  Z	S )
UserChangeFormrG   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   rK   c                   @   s   e Zd ZeZdZdeiZdS )zUserChangeForm.Meta__all__rA   NrN   r   r   r   r   rQ      s   rQ   c                    sR   t  j|i | | jd}|r0|jd|_| jd}|rN|jd|_d S )Nrb   z../password/user_permissionscontent_type)r    r4   rP   r[   rK   formatZquerysetZselect_related)r&   r6   r7   rb   ro   r+   r   r   r4      s    zUserChangeForm.__init__c                 C   s   | j dS Nrb   )r:   r[   r&   r   r   r   clean_password   s    zUserChangeForm.clean_password)
r-   r.   r/   r1   ri   rb   rQ   r4   rt   r0   r   r   r+   r   rm      s   		rm   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.
    rR   TrI   )r=   rG   FrB   current-passwordr   rJ   r=   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|i | tjtj| _| jj	p8d}|| j
d _	|| j
d jjd< | j
d jdu r|t| 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   rA   Z	maxlength)request
user_cacher    r4   	UserModelrS   	get_fieldrT   username_field
max_lengthrP   r=   r(   r   r   verbose_name)r&   r{   r6   r7   Zusername_max_lengthr+   r   r   r4      s    zAuthenticationForm.__init__c                 C   s\   | j d}| j d}|d urV|rVt| j||d| _| jd u rJ|  n| | j | j S )NrA   rb   )rA   rb   )rZ   r[   r   r{   r|   get_invalid_login_errorconfirm_login_allowed)r&   rA   rb   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.
        ry   rX   N)	is_activer   r\   )r&   rg   r   r   r   r      s
    z(AuthenticationForm.confirm_login_allowedc                 C   s   | j S r8   )r|   rs   r   r   r   get_user   s    zAuthenticationForm.get_userc                 C   s   t | jd dd| jjidS )Nrx   rA   )rY   params)r   r\   r   r   rs   r   r   r   r      s
    
z*AuthenticationForm.get_invalid_login_error)N)r-   r.   r/   rh   r>   r   Z	TextInputrA   rj   ri   rk   rb   r\   r4   r   r   r   r   r0   r   r   r+   r   ru      s"   ru   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Emailrz   rB   emailrI   )r   r   r=   Nc                 C   sb   t ||}d| }t ||}t||||g}	|durVt ||}
|	|
d |	  dS )zO
        Send a django.core.mail.EmailMultiAlternatives to `to_email`.
         Nz	text/html)r   Zrender_to_stringjoin
splitlinesr   Z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                    s:   t  t jjf i 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 r8   )Zhas_usable_passwordr   getattr).0ur   email_field_namer   r   	<genexpr>  s   z.PasswordResetForm.get_users.<locals>.<genexpr>)r}   get_email_field_nameZ_default_managerfilter)r&   r   Zactive_usersr   r   r   	get_users  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uidrg   tokenprotocol)r   N)rZ   r
   r'   r   r}   r   r   r   r   r   pkZ
make_tokenr   )r&   Zdomain_overrider   r   Z	use_httpsZtoken_generatorr   r{   r   Zextra_email_contextr   Zcurrent_siter   r   r   rg   Z
user_emailr)   r   r   r   re   %  s.    




zPasswordResetForm.save)N)r-   r.   r/   r   Z
EmailFieldri   Z
EmailInputr   r   r   r	   re   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 )SetPasswordFormza
    A form that lets a user change set their password without entering the old
    password
    rE   rF   zNew passwordrB   rH   rI   FrM   zNew password confirmationrw   c                    s   || _ t j|i | d S r8   rg   r    r4   r&   rg   r6   r7   r+   r   r   r4   ]  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_password2rE   rX   rZ   r[   r   r\   r   r`   rg   r]   r   r   r   clean_new_password2a  s    z#SetPasswordForm.clean_new_password2Tc                 C   s*   | j d }| j| |r$| j  | jS )Nr   rZ   rg   rf   re   r&   rd   rb   r   r   r   re   m  s
    

zSetPasswordForm.save)T)r-   r.   r/   rh   ri   r\   r   rj   rk   r   rl   r   r   r4   r   re   r0   r   r   r+   r   r   I  s"   r   c                   @   sX   e Zd ZdZi ejdediZejeddej	dddd	d
Z
g d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 passwordFrv   TrB   rR   rI   rw   )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   rX   )rZ   rg   Zcheck_passwordr   r\   )r&   r   r   r   r   clean_old_password  s    
z%PasswordChangeForm.clean_old_passwordN)r-   r.   r/   rh   r   r\   ri   r   rj   rk   r   Zfield_orderr   r   r   r   r   r   u  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.
    rE   rF   r2   rG   rH   Tr   rI   FrM   zPassword (again)rB   rL   c                    s   || _ t j|i | d S r8   r   r   r+   r   r   r4     s    z AdminPasswordChangeForm.__init__c                 C   sL   | j d}| j d}|r:|r:||kr:t| jd ddt|| j |S rU   r   r]   r   r   r   r^     s    z'AdminPasswordChangeForm.clean_password2c                 C   s*   | j d }| j| |r$| j  | jS )zSave the new password.rV   r   r   r   r   r   re     s
    

zAdminPasswordChangeForm.savec                    s*   t  j}| jD ]}||vrg   S qdgS rr   )r    changed_datarP   )r&   r9   r'   r+   r   r   r     s
    

z$AdminPasswordChangeForm.changed_data)T)r-   r.   r/   rh   ri   r\   Zrequired_css_classr   rj   rk   r   rl   rV   rW   r4   r^   re   propertyr   r0   r   r   r+   r   r     s*   
r   )1r   Zdjangor   Zdjango.contrib.authr   r   r   Zdjango.contrib.auth.hashersr   r   Zdjango.contrib.auth.modelsr   Zdjango.contrib.auth.tokensr	   Zdjango.contrib.sites.shortcutsr
   Zdjango.core.exceptionsr   Zdjango.core.mailr   Zdjango.templater   Zdjango.utils.encodingr   Zdjango.utils.httpr   Zdjango.utils.textr   Zdjango.utils.translationr   r   ri   r}   r   ZWidgetr   ZFieldr1   rj   r>   Z	ModelFormrD   rm   ZFormru   r   r   r   r   r   r   r   r   <module>   s2   	<NN,