3
_?                 @   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 jd| j t jd|j 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/html/boatanchoryapp/myenv/lib/python3.6/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  j|||}g }| s$|jtr8|jdtdi ndyt|}W n& tk
rj   |jdtdi Y n2X x.|j|j	 D ]\}}|jt||d q|W ||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   |j dd t j|| d S )NrequiredF)
setdefaultr    __init__)r&   argskwargs)r+   r   r   r3   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&   r7   r6   r   r   r   has_changedB   s    z%ReadOnlyPasswordHashField.has_changed)	r,   r-   r.   r   widgetr3   r8   r9   r/   r   r   )r+   r   r0   6   s   r0   c                   s(   e Zd Z fddZ fddZ  ZS )UsernameFieldc                s   t jdt j|S )Nr   )r   r   r    	to_python)r&   r   )r+   r   r   r<   G   s    zUsernameField.to_pythonc                s   t  j|dddS )Nnoneusername)Zautocapitalizeautocomplete)r    widget_attrs)r&   r:   )r+   r   r   r@   J   s    
zUsernameField.widget_attrs)r,   r-   r.   r<   r@   r/   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	j
 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_mismatchu'   The two password fields didn’t match.PasswordFr?   znew-password)r(   )r   stripr:   	help_textzPassword confirmationz4Enter the same password as before, for verification.)r   r:   rD   rE   c               @   s   e Zd ZeZdZdeiZdS )zUserCreationForm.Metar>   N)r>   )r,   r-   r.   r   modelfieldsr;   field_classesr   r   r   r   Metag   s   rI   c                s:   t  j|| | jjj| jkr6d| j| jjj jjd< d S )NT	autofocus)r    r3   _metarF   USERNAME_FIELDrG   r:   r(   )r&   r4   r5   )r+   r   r   r3   l   s    zUserCreationForm.__init__c             C   s>   | j jd}| j jd}|r:|r:||kr:t| jd dd|S )N	password1	password2rB   )code)cleaned_datagetr   error_messages)r&   rM   rN   r   r   r   clean_password2q   s    z UserCreationForm.clean_password2c                s`   t  j  | jjd}|r\ytj|| j W n. tk
rZ } z| jd| W Y d d }~X nX d S )NrN   )	r    _post_cleanrP   rQ   r   validate_passwordinstancer   Z	add_error)r&   passworderror)r+   r   r   rT   {   s    
zUserCreationForm._post_cleanTc                s.   t  jdd}|j| jd  |r*|j  |S )NF)commitrM   )r    saveset_passwordrP   )r&   rY   user)r+   r   r   rZ      s
    zUserCreationForm.save)T)r,   r-   r.   __doc___rR   r   	CharFieldPasswordInputr   "password_validators_help_text_htmlrM   rN   rI   r3   rS   rT   rZ   r/   r   r   )r+   r   rA   R   s"   
rA   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 )
UserChangeFormrC   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   rE   c               @   s   e Zd ZeZdZdeiZdS )zUserChangeForm.Meta__all__r>   N)r,   r-   r.   r   rF   rG   r;   rH   r   r   r   r   rI      s   rI   c                sN   t  j|| | jjd}|r,|jjd|_| jjd}|rJ|jjd|_d S )NrW   z../password/user_permissionscontent_type)r    r3   rG   rQ   rE   formatZquerysetZselect_related)r&   r4   r5   rW   rd   )r+   r   r   r3      s    zUserChangeForm.__init__c             C   s   | j jdS )NrW   )r7   rQ   )r&   r   r   r   clean_password   s    zUserChangeForm.clean_password)
r,   r-   r.   r0   r^   rW   rI   r3   rg   r/   r   r   )r+   r   rb      s   
	rb   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.
    rJ   T)r(   )r:   rC   Fr?   zcurrent-password)r   rD   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|| tj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   r>   Z	maxlength)request
user_cacher    r3   	UserModelrK   	get_fieldrL   username_field
max_lengthrG   r:   r(   r   r   verbose_name)r&   rl   r4   r5   Zusername_max_length)r+   r   r   r3      s    zAuthenticationForm.__init__c             C   s\   | j jd}| j jd}|d k	rV|rVt| j||d| _| jd krJ| j n| j| j | j S )Nr>   rW   )r>   rW   )rP   rQ   r   rl   rm   get_invalid_login_errorconfirm_login_allowed)r&   r>   rW   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.
        rj   )rO   N)	is_activer   rR   )r&   r\   r   r   r   rt      s    z(AuthenticationForm.confirm_login_allowedc             C   s   | j S )N)rm   )r&   r   r   r   get_user   s    zAuthenticationForm.get_userc             C   s   t | jd dd| jjidS )Nri   r>   )rO   params)r   rR   rp   rr   )r&   r   r   r   rs      s    z*AuthenticationForm.get_invalid_login_error)N)r,   r-   r.   r]   r;   r   Z	TextInputr>   r_   r^   r`   rW   rR   r3   ru   rt   rw   rs   r/   r   r   )r+   r   rh      s   rh   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Emailrk   r?   email)r(   )r   rq   r:   Nc             C   sb   t j||}dj|j }t j||}t||||g}	|dk	rVt j||}
|	j|
d |	j  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                s6   t j 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__iexactrv   Tc             3   s*   | ]"}|j  rt t|r|V  qd S )N)Zhas_usable_passwordr   getattr).0u)rz   email_field_namer   r   	<genexpr>   s    z.PasswordResetForm.get_users.<locals>.<genexpr>)rn   get_email_field_nameZ_default_managerfilter)r&   rz   Zactive_usersr   )rz   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j }xf| j|
D ]X}t||}|||tt	|j
||j||rrdndd|	p~i }| j||||||d q@W dS )zf
        Generate a one-use only link for resetting password and send it to the
        user.
        rz   httpshttp)rz   domain	site_nameuidr\   tokenprotocol)r   N)rP   r
   r'   r   rn   r   r   r   r   r   pkZ
make_tokenr   )r&   Zdomain_overrider   r   Z	use_httpsZtoken_generatorr   rl   r   Zextra_email_contextrz   Zcurrent_siter   r   r   r\   Z
user_emailr)   r   r   r   rZ   %  s(    



zPasswordResetForm.save)N)r,   r-   r.   r   Z
EmailFieldr^   Z
EmailInputrz   r   r   r	   rZ   r   r   r   r   ry      s   
ry   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	j
 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
    rB   u'   The two password fields didn’t match.zNew passwordr?   znew-password)r(   F)r   r:   rD   rE   zNew password confirmation)r   rD   r:   c                s   || _ t j|| d S )N)r\   r    r3   )r&   r\   r4   r5   )r+   r   r   r3   ]  s    zSetPasswordForm.__init__c             C   sL   | j jd}| j jd}|r:|r:||kr:t| jd ddtj|| j |S )Nnew_password1new_password2rB   )rO   )rP   rQ   r   rR   r   rU   r\   )r&   rM   rN   r   r   r   clean_new_password2a  s    z#SetPasswordForm.clean_new_password2Tc             C   s*   | j d }| jj| |r$| jj  | jS )Nr   )rP   r\   r[   rZ   )r&   rY   rW   r   r   r   rZ   m  s
    

zSetPasswordForm.save)T)r,   r-   r.   r]   r^   rR   r   r_   r`   r   ra   r   r   r3   r   rZ   r/   r   r   )r+   r   r   I  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 passwordFzcurrent-passwordT)r?   rJ   )r(   )r   rD   r:   old_passwordr   r   c             C   s,   | j d }| jj|s(t| jd dd|S )zB
        Validate that the old_password field is correct.
        r   r   )rO   )rP   r\   Zcheck_passwordr   rR   )r&   r   r   r   r   clean_old_password  s    
z%PasswordChangeForm.clean_old_passwordN)r,   r-   r.   r]   r   rR   r^   r   r_   r`   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
j 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.
    rB   u'   The two password fields didn’t match.r1   rC   znew-passwordT)r?   rJ   )r(   F)r   r:   rD   rE   zPassword (again)r?   z4Enter the same password as before, for verification.c                s   || _ t j|| d S )N)r\   r    r3   )r&   r\   r4   r5   )r+   r   r   r3     s    z AdminPasswordChangeForm.__init__c             C   sL   | j jd}| j jd}|r:|r:||kr:t| jd ddtj|| j |S )NrM   rN   rB   )rO   )rP   rQ   r   rR   r   rU   r\   )r&   rM   rN   r   r   r   rS     s    z'AdminPasswordChangeForm.clean_password2c             C   s*   | j d }| jj| |r$| jj  | jS )zSave the new password.rM   )rP   r\   r[   rZ   )r&   rY   rW   r   r   r   rZ     s
    

zAdminPasswordChangeForm.savec                s*   t  j}x| jD ]}||krg S qW dgS )NrW   )r    changed_datarG   )r&   r6   r'   )r+   r   r   r     s
    z$AdminPasswordChangeForm.changed_data)T)r,   r-   r.   r]   r^   rR   Zrequired_css_classr   r_   r`   r   ra   rM   rN   r3   rS   rZ   propertyr   r/   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   r^   rn   r   ZWidgetr   ZFieldr0   r_   r;   Z	ModelFormrA   rb   ZFormrh   ry   r   r   r   r   r   r   r   <module>   s2   	<NN,