U
    ¸ßŽi¼E  ã                   @   s¢  d dl Z 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!e  "d¡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/ƒZ0G d!d"„ d"ej/ƒZ1G d#d$„ d$ej/ƒZ2G d%d&„ d&e2ƒZ3G d'd(„ d(ej/ƒZ4d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_lazyzdjango.contrib.authc                 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   úW/var/www/html/IITS/school/venv/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=   D   s    z"ReadOnlyPasswordHashField.__init__)r3   r4   r5   r   Úwidgetr=   r8   r   r   r.   r   r9   A   s   r9   c                       s(   e Zd Z‡ fdd„Z‡ fdd„Z‡  ZS )ÚUsernameFieldc                    s4   t ƒ  |¡}| jd k	r(t|ƒ| jkr(|S t d|¡S )Nr   )r    Ú	to_pythonÚ
max_lengthÚlenr   r   )r'   r   r.   r   r   rC   K   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   rI   V   s    
ýzUsernameField.widget_attrs)r3   r4   r5   rC   rI   r8   r   r   r.   r   rB   J   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.ÚPasswordFrH   únew-password©r)   )r   ÚstriprA   Ú	help_textzPassword confirmationú4Enter the same password as before, for verification.©r   rA   rP   rQ   c                   @   s   e Zd ZeZdZdeiZdS )zBaseUserCreationForm.Meta)rG   rG   N©r3   r4   r5   r   ÚmodelÚfieldsrB   Úfield_classesr   r   r   r   ÚMetat   s   rX   c                    s:   t ƒ j||Ž | jjj| jkr6d| j| jjj jjd< d S )NTÚ	autofocus)r    r=   Ú_metarU   ÚUSERNAME_FIELDrV   rA   r)   r>   r.   r   r   r=   y   s    þÿzBaseUserCreationForm.__init__c                 C   s>   | j  d¡}| j  d¡}|r:|r:||kr:t| jd dd�‚|S ©NÚ	password1Ú	password2rK   ©Úcode)Úcleaned_dataÚgetr   Úerror_messages©r'   r]   r^   r   r   r   Úclean_password2€   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_cleanra   rb   r   Úvalidate_passwordÚinstancer   Ú	add_error)r'   ÚpasswordÚerrorr.   r   r   rf   Š   s    
z BaseUserCreationForm._post_cleanTc                    s@   t ƒ jdd�}| | jd ¡ |r<| ¡  t| dƒr<|  ¡  |S )NF)Úcommitr]   Úsave_m2m)r    ÚsaveÚset_passwordra   Úhasattrrm   )r'   rl   Úuserr.   r   r   rn   •   s    
zBaseUserCreationForm.save)T)r3   r4   r5   Ú__doc__Ú_rc   r   Ú	CharFieldÚPasswordInputr   Ú"password_validators_help_text_htmlr]   r^   rX   r=   re   rf   rn   r8   r   r   r.   r   rJ   ^   s*    ÿüü
rJ   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.rG   )Zusername__iexactN)ra   rb   rZ   rU   ÚobjectsÚfilterÚexistsÚ_update_errorsr   rh   Úunique_error_message)r'   rG   r   r   r   Úclean_username    s     ÿþ  ÿÿÿÿ
zUserCreationForm.clean_usernameN)r3   r4   r5   r}   r   r   r   r   rw   Ÿ   s   rw   c                       s>   e Zd Zeedƒedƒd�ZG dd„ dƒZ‡ fdd„Z‡  ZS )ÚUserChangeFormrM   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   rQ   c                   @   s   e Zd ZeZdZdeiZdS )zUserChangeForm.MetaÚ__all__rG   NrT   r   r   r   r   rX   ¾   s   rX   c                    sZ   t ƒ j||Ž | j d¡}|r8|j d| jj› d�¡|_| j d¡}|rV|j 	d¡|_d S )Nrj   z../../z
/password/Úuser_permissionsÚcontent_type)
r    r=   rV   rb   rQ   Úformatrh   ÚpkÚquerysetÚselect_related)r'   r?   r@   rj   r€   r.   r   r   r=   Ã   s    ÿÿzUserChangeForm.__init__)	r3   r4   r5   r9   rs   rj   rX   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.
    rY   TrO   )rA   rM   FrH   úcurrent-password©r   rP   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éþ   rG   Ú	maxlength)ÚrequestÚ
user_cacher    r=   Ú	UserModelrZ   Ú	get_fieldr[   Úusername_fieldrD   rV   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 )NrG   rj   )rG   rj   )ra   rb   r   r�   rŽ   Úget_invalid_login_errorÚconfirm_login_allowed)r'   rG   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'   rq   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‰   rG   )r`   Úparams)r   rc   r‘   r’   r—   r   r   r   r“     s
    
ýz*AuthenticationForm.get_invalid_login_error)N)r3   r4   r5   rr   rB   r   Ú	TextInputrG   rt   rs   ru   rj   rc   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‹   rH   ÚemailrO   )r   rD   rA   Nc                 C   sŽ   t  ||¡}d | ¡ ¡}t  ||¡}t||||gƒ}	|dk	rVt  ||¡}
|	 |
d¡ z|	 ¡  W n& tk
rˆ   t 	d|d j
¡ Y nX dS )zO
        Send a django.core.mail.EmailMultiAlternatives to `to_email`.
        Ú Nz	text/htmlz)Failed to send password reset email to %srq   )r   Úrender_to_stringÚjoinÚ
splitlinesr   Úattach_alternativeÚsendÚ	ExceptionÚloggerÚ	exceptionrƒ   )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>T  s   ýz.PasswordResetForm.get_users.<locals>.<genexpr>)r�   Úget_email_field_nameÚ_default_managerry   )r'   rœ   Zactive_usersr   r±   r   Ú	get_usersF  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Úuidrq   ÚtokenÚprotocol)r©   N)ra   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²   rq   Z
user_emailr*   r   r   r   rn   [  s6    


ùø
úzPasswordResetForm.save)N)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 )ÚSetPasswordFormzZ
    A form that lets a user set their password without entering the old
    password
    rK   rL   zNew passwordrH   rN   rO   FrS   zNew password confirmationrˆ   c                    s   || _ tƒ j||Ž d S r0   ©rq   r    r=   ©r'   rq   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_password2rK   r_   ©ra   rb   r   rc   r   rg   rq   rd   r   r   r   Úclean_new_password2¢  s    þz#SetPasswordForm.clean_new_password2Tc                 C   s*   | j d }| j |¡ |r$| j ¡  | jS )NrÃ   ©ra   rq   ro   rn   ©r'   rl   rj   r   r   r   rn   ­  s
    

zSetPasswordForm.save)T)r3   r4   r5   rr   rs   rc   r   rt   ru   r   rv   rÃ   rÄ   r=   rÆ   rn   r8   r   r   r.   r   rÀ   ‰  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©rH   rY   rO   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   rq   Úcheck_passwordr   rc   )r'   rÌ   r   r   r   Úclean_old_passwordË  s    
þz%PasswordChangeForm.clean_old_passwordN)r3   r4   r5   rr   rÀ   rc   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.
    rK   rL   r:   rM   rN   TrË   rO   FrS   zPassword (again)rH   rR   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 r\   rÅ   rd   r   r   r   re   ô  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   rn   ÿ  s
    

zAdminPasswordChangeForm.savec                    s*   t ƒ j}| jD ]}||krg   S qdgS )Nrj   )r    Úchanged_datarV   )r'   Údatar(   r.   r   r   rÑ     s
    

z$AdminPasswordChangeForm.changed_data)T)r3   r4   r5   rr   rs   rc   Úrequired_css_classr   rt   ru   r   rv   r]   r^   r=   re   rn   ÚpropertyrÑ   r8   r   r   r.   r   rÐ   Ø  s0    ÿÿúü
rÐ   )5Úloggingr   Ú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   rs   r�   Ú	getLoggerr¤   r   ÚWidgetr   ÚFieldr9   rt   rB   Ú	ModelFormrJ   rw   r~   ÚFormr†   r›   rÀ   rÉ   rÐ   r   r   r   r   Ú<module>   s:   
	AQg,#