o
    6i?                     @   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   ^/var/www/hoanhtaovolam_webdjango/env/lib/python3.10/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r|dtdi n/zt|}W n ty3   |dtdi Y nw ||	 D ]\}}|t||d q;||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_context)__name__
__module____qualname__template_name	read_onlyr!   __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|i | d S )NrequiredFdisabledT)
setdefaultr    __init__r'   argskwargsr.   r   r   r:   9   s   z"ReadOnlyPasswordHashField.__init__)r0   r1   r2   r   widgetr:   r5   r   r   r.   r   r6   6   s    r6   c                       s(   e Zd Z fddZ fddZ  ZS )UsernameFieldc                    s4   t  |}| jd urt|| jkr|S td|S )Nr   )r    	to_python
max_lengthlenr   r   )r'   r   r.   r   r   r@   @   s   zUsernameField.to_pythonc                    s   i t  |dddS )Nnoneusername)autocapitalizeautocomplete)r    widget_attrs)r'   r>   r.   r   r   rG   K   s   
zUsernameField.widget_attrs)r0   r1   r2   r@   rG   r5   r   r   r.   r   r?   ?   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.PasswordFrF   new-passwordr)   )r   stripr>   	help_textzPassword confirmation4Enter the same password as before, for verification.r   r>   rN   rO   c                   @      e Zd ZeZdZdeiZdS )zUserCreationForm.Meta)rD   rD   Nr0   r1   r2   r   modelfieldsr?   field_classesr   r   r   r   Metah       rW   c                    sB   t  j|i | | jjj| jv rd| j| jjj jjd< d S d S )NT	autofocus)r    r:   _metarT   USERNAME_FIELDrU   r>   r)   r;   r.   r   r   r:   m   s   zUserCreationForm.__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_password2r   s   z UserCreationForm.clean_password2c              
      sf   t    | jd}|r1z
t|| j W d S  ty0 } z| d| W Y d }~d S d }~ww d S )Nr^   )	r    _post_cleanra   rb   r   validate_passwordinstancer   	add_error)r'   passworderrorr.   r   r   rf   |   s   
zUserCreationForm._post_cleanTc                    s.   t  jdd}|| jd  |r|  |S )NF)commitr]   )r    saveset_passwordra   )r'   rl   userr.   r   r   rm      s
   zUserCreationForm.saveT)r0   r1   r2   __doc___rc   r   	CharFieldPasswordInputr   "password_validators_help_text_htmlr]   r^   rW   r:   re   rf   rm   r5   r   r   r.   r   rH   S   s*    
rH   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                   @   rR   )zUserChangeForm.Meta__all__rD   NrS   r   r   r   r   rW      rX   rW   c                    sV   t  j|i | | jd}|r|jd|_| jd}|r)|jd|_d S d S )Nrj   z../password/user_permissionscontent_type)r    r:   rU   rb   rO   formatquerysetselect_related)r'   r<   r=   rj   rx   r.   r   r   r:      s   zUserChangeForm.__init__)	r0   r1   r2   r6   rr   rj   rW   r:   r5   r   r   r.   r   rv      s    	rv   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.
    rY   TrM   )r>   rK   FrF   current-passwordr   rN   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	pd}|| j
d _	|| j
d jjd< | j
d jdu r@t| jj| j
d _dS 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   rD   	maxlength)request
user_cacher    r:   	UserModelrZ   	get_fieldr[   username_fieldrA   rU   r>   r)   r   r   verbose_name)r'   r   r<   r=   username_max_lengthr.   r   r   r:      s   zAuthenticationForm.__init__c                 C   sZ   | j d}| j d}|d ur*|r*t| j||d| _| jd u r$|  | | j | j S )NrD   rj   )rD   rj   )ra   rb   r   r   r   get_invalid_login_errorconfirm_login_allowed)r'   rD   rj   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   rc   )r'   ro   r   r   r   r      s   z(AuthenticationForm.confirm_login_allowedc                 C   s   | j S N)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   rD   )r`   params)r   rc   r   r   r   r   r   r   r      s
   
z*AuthenticationForm.get_invalid_login_errorr   )r0   r1   r2   rq   r?   r   	TextInputrD   rs   rr   rt   rj   rc   r:   r   r   r   r   r5   r   r   r.   r   r}      s$    r}   c                	   @   s\   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 )PasswordResetFormEmailr   rF   emailrM   )r   rA   r>   Nc                 C   sb   t ||}d| }t ||}t||||g}	|dur+t ||}
|	|
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_emailto_emailhtml_email_template_namesubjectbodyemail_message
html_emailr   r   r   	send_mail   s   zPasswordResetForm.send_mailc                    s:   t  t jjd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 r   )has_usable_passwordr   getattr).0ur   email_field_namer   r   	<genexpr>  s    
z.PasswordResetForm.get_users.<locals>.<genexpr>Nr   )r   get_email_field_name_default_managerfilter)r'   r   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 ],}t||}|||tt	|j
||||r8d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)ra   r
   r(   r   r   r   r   r   r   r   pk
make_tokenr   )r'   domain_overrider   r   	use_httpstoken_generatorr   r   r   extra_email_contextr   current_siter   r   r   ro   
user_emailr*   r   r   r   rm      s0   




zPasswordResetForm.saver   )r0   r1   r2   r   
EmailFieldrr   
EmailInputr   r   r   r	   rm   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
    rI   rJ   zNew passwordrF   rL   rM   FrQ   zNew password confirmationr   c                       || _ t j|i | d S r   ro   r    r:   r'   ro   r<   r=   r.   r   r   r:   X     zSetPasswordForm.__init__c                 C   L   | j d}| j d}|r|r||krt| jd ddt|| j |S )Nnew_password1new_password2rI   r_   ra   rb   r   rc   r   rg   ro   rd   r   r   r   clean_new_password2\  s   z#SetPasswordForm.clean_new_password2Tc                 C   *   | j d }| j| |r| j  | jS )Nr   ra   ro   rn   rm   r'   rl   rj   r   r   r   rm   h  s
   

zSetPasswordForm.saverp   )r0   r1   r2   rq   rr   rc   r   rs   rt   r   ru   r   r   r:   r   rm   r5   r   r   r.   r   r   D  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 passwordFr~   TrF   rY   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_   )ra   ro   check_passwordr   rc   )r'   r   r   r   r   clean_old_password  s   
z%PasswordChangeForm.clean_old_passwordN)r0   r1   r2   rq   r   rc   rr   r   rs   rt   r   field_orderr   r   r   r   r   r   p  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   r7   rK   rL   Tr   rM   FrQ   zPassword (again)rF   rP   c                    r   r   r   r   r.   r   r   r:     r   z AdminPasswordChangeForm.__init__c                 C   r   r\   r   rd   r   r   r   re     s   z'AdminPasswordChangeForm.clean_password2c                 C   r   )zSave the new password.r]   r   r   r   r   r   rm     s
   

zAdminPasswordChangeForm.savec                    s*   t  j}| jD ]
}||vrg   S qdgS )Nrj   )r    changed_datarU   )r'   datar(   r.   r   r   r     s   
z$AdminPasswordChangeForm.changed_datarp   )r0   r1   r2   rq   rr   rc   required_css_classr   rs   rt   r   ru   r]   r^   r:   re   rm   propertyr   r5   r   r   r.   r   r     s,    
r   )1r   djangor   django.contrib.authr   r   r   django.contrib.auth.hashersr   r   django.contrib.auth.modelsr   django.contrib.auth.tokensr	   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   rr   r   r   Widgetr   Fieldr6   rs   r?   	ModelFormrH   rv   Formr}   r   r   r   r   r   r   r   r   <module>   s4    		<NN,