o
    —¨Êh1@  ã                   @   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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   úK/var/www/html/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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_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|i |¤Ž 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   i t ƒ  |¡¥dddœ¥S )NÚnoneÚusername)ÚautocapitalizeÚautocomplete)r    Úwidget_attrs)r'   rA   r.   r   r   rH   L   s   
ÿýzUsernameField.widget_attrs)r3   r4   r5   rC   rH   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 )Ú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.ÚPasswordFrG   únew-password©r)   )r   ÚstriprA   Ú	help_textzPassword confirmationú4Enter the same password as before, for verification.©r   rA   rO   rP   c                   @   ó   e Zd ZeZdZdeiZdS )zUserCreationForm.Meta)rE   rE   N©r3   r4   r5   r   ÚmodelÚfieldsrB   Úfield_classesr   r   r   r   ÚMetaj   ó    rX   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=   Ú_metarU   ÚUSERNAME_FIELDrV   rA   r)   r>   r.   r   r   r=   o   s   þÿÿzUserCreationForm.__init__c                 C   s>   | j  d¡}| j  d¡}|r|r||krt| jd dd�‚|S ©NÚ	password1Ú	password2rJ   ©Úcode)Úcleaned_dataÚgetr   Úerror_messages©r'   r^   r_   r   r   r   Úclean_password2v   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_cleanrb   rc   r   Úvalidate_passwordÚinstancer   Ú	add_error)r'   ÚpasswordÚerrorr.   r   r   rg   €   s   
€ÿýzUserCreationForm._post_cleanTc                    s.   t ƒ jdd�}| | jd ¡ |r| ¡  |S )NF)Úcommitr^   )r    ÚsaveÚset_passwordrb   )r'   rm   Úuserr.   r   r   rn   ‹   s
   zUserCreationForm.save©T)r3   r4   r5   Ú__doc__Ú_rd   r   Ú	CharFieldÚPasswordInputr   Ú"password_validators_help_text_htmlr^   r_   rX   r=   rf   rg   rn   r8   r   r   r.   r   rI   T   s*    ÿüü
rI   c                       s>   e Zd Zeedƒedƒd�ZG dd„ dƒZ‡ fdd„Z‡  ZS )ÚUserChangeFormrL   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   rP   c                   @   rS   )zUserChangeForm.MetaÚ__all__rE   NrT   r   r   r   r   rX   �   rY   rX   c                    sV   t ƒ j|i |¤Ž | j d¡}|r|j d¡|_| j d¡}|r)|j d¡|_d S d S )Nrk   z../password/Úuser_permissionsÚcontent_type)r    r=   rV   rc   rP   ÚformatÚquerysetÚselect_related)r'   r?   r@   rk   ry   r.   r   r   r=   ¢   s   
ÿÿzUserChangeForm.__init__)	r3   r4   r5   r9   rs   rk   rX   r=   r8   r   r   r.   r   rw   “   s    ÿþ	rw   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.
    rZ   TrN   )rA   rL   FrG   úcurrent-password©r   rO   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|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éþ   rE   Ú	maxlength)ÚrequestÚ
user_cacher    r=   Ú	UserModelr[   Ú	get_fieldr\   Úusername_fieldÚ
max_lengthrV   rA   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 )NrE   rk   )rE   rk   )rb   rc   r   r…   r†   Úget_invalid_login_errorÚconfirm_login_allowed)r'   rE   rk   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   rd   )r'   rp   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   )ra   Úparams)r   rd   r‰   r‹   r‘   r   r   r   r�   ÷   s
   
ýz*AuthenticationForm.get_invalid_login_errorr0   )r3   r4   r5   rr   rB   r   Ú	TextInputrE   rt   rs   ru   rk   rd   r=   r�   rŽ   r’   r�   r8   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ƒ   rG   ÚemailrN   )r   rŠ   rA   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 r0   )Ú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Úuidrp   ÚtokenÚprotocol)r¢   N)rb   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­   rp   Ú
user_emailr*   r   r   r   rn   3  s8   


ùø
úôzPasswordResetForm.saver0   )r3   r4   r5   r   Ú
EmailFieldrs   Ú
EmailInputr—   r§   r³   r	   rn   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
    rJ   rK   zNew passwordrG   rM   rN   FrR   zNew password confirmationr€   c                    ó   || _ tƒ j|i |¤Ž d S r0   ©rp   r    r=   ©r'   rp   r?   r@   r.   r   r   r=   v  ó   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_password2rJ   r`   ©rb   rc   r   rd   r   rh   rp   re   r   r   r   Úclean_new_password2z  s   þz#SetPasswordForm.clean_new_password2Tc                 C   ó*   | j d }| j |¡ |r| j ¡  | jS )NrË   ©rb   rp   ro   rn   ©r'   rm   rk   r   r   r   rn   †  s
   

zSetPasswordForm.saverq   )r3   r4   r5   rr   rs   rd   r   rt   ru   r   rv   rË   rÌ   r=   rÎ   rn   r8   r   r   r.   r   rÅ   a  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©rG   rZ   rN   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`   )rb   rp   Úcheck_passwordr   rd   )r'   rÕ   r   r   r   Úclean_old_password¤  s   
þz%PasswordChangeForm.clean_old_passwordN)r3   r4   r5   rr   rÅ   rd   rs   r   rt   ru   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.
    rJ   rK   r:   rL   rM   TrÔ   rN   FrR   zPassword (again)rG   rQ   c                    rÆ   r0   rÇ   rÈ   r.   r   r   r=   É  rÉ   z AdminPasswordChangeForm.__init__c                 C   rÊ   r]   rÍ   re   r   r   r   rf   Í  s   þz'AdminPasswordChangeForm.clean_password2c                 C   rÏ   )zSave the new password.r^   rÐ   rÑ   r   r   r   rn   Ø  s
   

zAdminPasswordChangeForm.savec                    s*   t ƒ j}| jD ]
}||vrg   S qdgS )Nrk   )r    Úchanged_datarV   )r'   Údatar(   r.   r   r   rÚ   à  s   
ÿz$AdminPasswordChangeForm.changed_datarq   )r3   r4   r5   rr   rs   rd   Úrequired_css_classr   rt   ru   r   rv   r^   r_   r=   rf   rn   ÚpropertyrÚ   r8   r   r   r.   r   rÙ   ±  s0    ÿÿúü
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   rs   r‡   r   ÚWidgetr   ÚFieldr9   rt   rB   Ú	ModelFormrI   rw   ÚFormr~   r•   rÅ   rÒ   rÙ   r   r   r   r   Ú<module>   s6    	?Qb-#