
v^?                 @   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 m Z e   Z d d   Z Gd d   d e j   Z! Gd d   d e j"  Z# Gd d   d e j$  Z% Gd d   d e j&  Z' Gd d   d e j&  Z( Gd d   d e j)  Z* Gd d   d e j)  Z+ Gd d   d e j)  Z, Gd  d!   d! e,  Z- Gd" d#   d# e j)  Z. d S)$    N)forms)authenticateget_user_modelpassword_validation)UNUSABLE_PASSWORD_PREFIXidentify_hasher)User)default_token_generator)get_current_site)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   ;/tmp/pip-build-8lau8j11/django/django/contrib/auth/forms.py_unicode_ci_compare   s    r   c                   s.   e  Z d  Z d Z d Z   f d d   Z   S)ReadOnlyPasswordHashWidgetz)auth/widgets/read_only_password_hash.htmlTc       	         s   t    j | | |  } g  } | s4 | j t  rP | j d t d  i  n y t |  } Wn+ t k
 r | j d t d  i  YnF XxB | j |  j	   D]+ \ } } | j d t |  d | i  q W| | d <| S)NlabelzNo password set.z5Invalid password format or unknown hashing algorithm.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    r   r   )r*   r   r       s   r   c                   s@   e  Z d  Z e Z   f d d   Z d d   Z d d   Z   S)ReadOnlyPasswordHashFieldc                s'   | j  d d  t   j | |   d  S)NrequiredF)
setdefaultr   __init__)r%   argskwargs)r*   r   r   r1   8   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%   r5   r4   r   r   r   has_changedA   s    z%ReadOnlyPasswordHashField.has_changed)r+   r,   r-   r   widgetr1   r6   r7   r   r   )r*   r   r.   5   s   r.   c                   s4   e  Z d  Z   f d d   Z   f d d   Z   S)UsernameFieldc                s   t  j d t   j |   S)Nr   )r   r   r   	to_python)r%   r   )r*   r   r   r:   F   s    zUsernameField.to_pythonc                s"   t    j |  d d d d i  S)NZautocapitalizenoneautocompleteusername)r   widget_attrs)r%   r8   )r*   r   r   r>   I   s    zUsernameField.widget_attrs)r+   r,   r-   r:   r>   r   r   )r*   r   r9   E   s   r9   c            
       s  e  Z d  Z d Z d e d  i Z e j d e d  d d d e j d	 d
 d i  d e	 j
    Z e j d e d  d e j d	 d
 d i  d d d e d   Z Gd d   d  Z   f d d   Z d d   Z   f d d   Z d   f d d  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.r   PasswordstripFr8   r'   r<   znew-password	help_textzPassword confirmationz4Enter the same password as before, for verification.c               @   s(   e  Z d  Z e Z d Z d e i Z d S)zUserCreationForm.Metar=   N)zusername)r+   r,   r-   r   modelfieldsr9   field_classesr   r   r   r   Metaf   s   rG   c                sO   t    j | |   |  j j j |  j k rK d |  j |  j j j j j d <d  S)NT	autofocus)r   r1   _metarD   USERNAME_FIELDrE   r8   r'   )r%   r2   r3   )r*   r   r   r1   k   s    zUserCreationForm.__init__c             C   s\   |  j  j d  } |  j  j d  } | rX | rX | | k rX t j |  j d d d  | S)N	password1	password2r@   code)cleaned_datagetr   ValidationErrorerror_messages)r%   rK   rL   r   r   r   clean_password2p   s    	z UserCreationForm.clean_password2c                s{   t    j   |  j j d  } | rw y t j | |  j  Wn8 t j k
 rv } z |  j	 d |  WYd  d  } ~ Xn Xd  S)NrL   )
r   _post_cleanrN   rO   r   validate_passwordinstancer   rP   Z	add_error)r%   passworderror)r*   r   r   rS   z   s    zUserCreationForm._post_cleanTc                s=   t    j d d  } | j |  j d  | r9 | j   | S)NcommitFrK   )r   saveset_passwordrN   )r%   rX   user)r*   r   r   rY      s
    
zUserCreationForm.save)r+   r,   r-   __doc___rQ   r   	CharFieldPasswordInputr   "password_validators_help_text_htmlrK   rL   rG   r1   rR   rS   rY   r   r   )r*   r   r?   Q   s"   		
r?   c                   sb   e  Z d  Z e d e d  d e d   Z Gd d   d  Z   f d d   Z d	 d
   Z   S)UserChangeFormr   rA   rC   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>.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   rD   rE   r9   rF   r   r   r   r   rG      s   rG   c                sq   t    j | |   |  j j d  } | r@ | j j d  | _ |  j j d  } | rm | j j d  | _ d  S)NrV   z../password/user_permissionscontent_type)r   r1   rE   rO   rC   formatZquerysetZselect_related)r%   r2   r3   rV   rc   )r*   r   r   r1      s    zUserChangeForm.__init__c             C   s   |  j  j d  S)NrV   )r5   rO   )r%   r   r   r   clean_password   s    zUserChangeForm.clean_password)	r+   r,   r-   r.   r]   rV   rG   r1   rf   r   r   )r*   r   ra      s   	ra   c            
       s   e  Z d  Z d Z e d e j d d d i   Z e j d e	 d  d d	 d e j
 d d
 d i   Z d e	 d  d e	 d  i Z d   f d d  Z d d   Z d d   Z d d   Z d d   Z   S)AuthenticationFormzs
    Base class for authenticating users. Extend this to get a form that accepts
    username/password logins.
    r8   r'   rH   Tr   rA   rB   Fr<   zcurrent-passwordinvalid_loginz^Please enter a correct %(username)s and password. Note that both fields may be case-sensitive.inactivezThis account is inactive.Nc                s   | |  _  d |  _ t   j | |   t j j t j  |  _ |  j j	 pL d } | |  j
 d _	 | |  j
 d j j d <|  j
 d j d k 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   r=   	maxlength)request
user_cacher   r1   	UserModelrI   	get_fieldrJ   username_field
max_lengthrE   r8   r'   r   r   verbose_name)r%   rl   r2   r3   Zusername_max_length)r*   r   r   r1      s    		zAuthenticationForm.__init__c             C   s   |  j  j d  } |  j  j d  } | d  k	 r | r t |  j d | d | |  _ |  j d  k rr |  j    n |  j |  j  |  j  S)Nr=   rV   )rN   rO   r   rl   rm   get_invalid_login_errorconfirm_login_allowed)r%   r=   rV   r   r   r   clean   s    zAuthenticationForm.cleanc             C   s)   | j  s% t j |  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
        ``forms.ValidationError``.

        If the given user may log in, this method should return None.
        ri   rM   N)	is_activer   rP   rQ   )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 |  j d d d d d |  j j i S)Nrh   rM   paramsr=   )r   rP   rQ   rp   rr   )r%   r   r   r   rs      s    z*AuthenticationForm.get_invalid_login_error)r+   r,   r-   r\   r9   r   Z	TextInputr=   r^   r]   r_   rV   rQ   r1   ru   rt   rw   rs   r   r   )r*   r   rg      s   !	rg   c               @   s   e  Z d  Z e j d e d  d d d e j d d d i   Z d	 d
 d  Z d d   Z	 d	 d d d e
 d	 d	 d	 d	 d d 	 Z d	 S)PasswordResetFormr   ZEmailrq   rj   r8   r'   r<   emailNc             C   s   t  j | |  } d j | j    } t  j | |  } t | | | | g  }	 | d k	 r t  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                sH   t  j    t  j j 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   s9   |  ]/ } | 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 }
 t j   } x |  j |
  D] } | sV t |  } | j } | j } n
 | } } t | |  } d | d | d | d t t	 | j
   d | d | j |  d | r d n d	 i |	 p i   } |  j | | | | | d
 | q) Wd S)zf
        Generate a one-use only link for resetting password and send it to the
        user.
        rz   domain	site_nameuidr[   tokenprotocolhttpshttpr   N)rN   rn   r   r   r
   r&   r   r   r   r   pkZ
make_tokenr   )r%   Zdomain_overrider   r   Z	use_httpsZtoken_generatorr   rl   r   Zextra_email_contextrz   r   r[   Zcurrent_siter   r   Z
user_emailr(   r   r   r   rY   $  s(    
	
zPasswordResetForm.save)r+   r,   r-   r   Z
EmailFieldr]   Z
EmailInputrz   r   r   r	   rY   r   r   r   r   ry      s   		ry   c            
       s   e  Z d  Z d Z d e d  i Z e j d e d  d e j d d d	 i  d
 d d e	 j
    Z e j d e d  d
 d d e j d d d	 i   Z   f d d   Z d d   Z d d d  Z   S)SetPasswordFormza
    A form that lets a user change set their password without entering the old
    password
    r@   u'   The two password fields didn’t match.r   zNew passwordr8   r'   r<   znew-passwordrB   FrC   zNew password confirmationc                s    | |  _  t   j | |   d  S)N)r[   r   r1   )r%   r[   r2   r3   )r*   r   r   r1   \  s    	zSetPasswordForm.__init__c             C   so   |  j  j d  } |  j  j d  } | rX | rX | | k rX t j |  j d d d  t j | |  j  | S)Nnew_password1new_password2r@   rM   )rN   rO   r   rP   rQ   r   rT   r[   )r%   rK   rL   r   r   r   clean_new_password2`  s    	z#SetPasswordForm.clean_new_password2Tc             C   s7   |  j  d } |  j j |  | r0 |  j j   |  j S)Nr   )rN   r[   rZ   rY   )r%   rX   rV   r   r   r   rY   l  s
    zSetPasswordForm.save)r+   r,   r-   r\   r]   rQ   r   r^   r_   r   r`   r   r   r1   r   rY   r   r   )r*   r   r   H  s   		r   c               @   s   e  Z d  Z d Z e j d e d  i  Z e j d e d  d d d e j	 d	 d
 d d d i   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.r   zOld passwordrB   Fr8   r'   r<   zcurrent-passwordrH   Told_passwordr   r   c             C   s?   |  j  d } |  j j |  s; t j |  j d d d  | S)zB
        Validate that the old_password field is correct.
        r   r   rM   )rN   r[   Zcheck_passwordr   rP   rQ   )r%   r   r   r   r   clean_old_password  s    	z%PasswordChangeForm.clean_old_passwordN)r+   r,   r-   r\   r   rQ   r]   r   r^   r_   r   Zfield_orderr   r   r   r   r   r   t  s   	!r   c            
       s   e  Z d  Z d Z d e d  i Z d Z e j d e d  d e j	 d d	 d
 d d i  d d d e
 j    Z e j d e d  d e j	 d d	 d
 i  d d d e d   Z   f d d   Z d d   Z d d d  Z e   f d d    Z   S)AdminPasswordChangeFormzN
    A form used to change the password of a user in the admin interface.
    r@   u'   The two password fields didn’t match.r/   r   rA   r8   r'   r<   znew-passwordrH   TrB   FrC   zPassword (again)z4Enter the same password as before, for verification.c                s    | |  _  t   j | |   d  S)N)r[   r   r1   )r%   r[   r2   r3   )r*   r   r   r1     s    	z AdminPasswordChangeForm.__init__c             C   so   |  j  j d  } |  j  j d  } | rX | rX | | k rX t j |  j d d d  t j | |  j  | S)NrK   rL   r@   rM   )rN   rO   r   rP   rQ   r   rT   r[   )r%   rK   rL   r   r   r   rR     s    	z'AdminPasswordChangeForm.clean_password2c             C   s7   |  j  d } |  j j |  | r0 |  j j   |  j S)zSave the new password.rK   )rN   r[   rZ   rY   )r%   rX   rV   r   r   r   rY     s
    zAdminPasswordChangeForm.savec                s7   t    j } x! |  j D] } | | k r g  Sq Wd g S)NrV   )r   changed_datarE   )r%   r4   r&   )r*   r   r   r     s
    z$AdminPasswordChangeForm.changed_data)r+   r,   r-   r\   r]   rQ   Zrequired_css_classr   r^   r_   r   r`   rK   rL   r1   rR   rY   propertyr   r   r   )r*   r   r     s"   		r   )/r   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.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Fieldr.   r^   r9   Z	ModelFormr?   ra   ZFormrg   ry   r   r   r   r   r   r   r   <module>   s0   		<NN,