3
(h:                 @   s  d dl m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mZ d dlmZ d dlm Z  d dl!m"Z" d dl#m$Z$m%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j0Z1G dd dej0Z2G d d! d!ej0Z3G d"d# d#e3Z4G d$d% d%ej0Z5dS )&    )unicode_literalsN)forms)authenticateget_user_modelpassword_validation)UNUSABLE_PASSWORD_PREFIXidentify_hasher)User)default_token_generator)get_current_site)EmailMultiAlternatives)flatatt)loader)force_bytes)format_htmlformat_html_join)urlsafe_base64_encode)	mark_safe)capfirst)ugettextugettext_lazyc               @   s   e Zd Zdd ZdS )ReadOnlyPasswordHashWidgetc             C   s   |}| j |}| s|jtr0tdtd }nRyt|}W n$ tk
r`   tdtd }Y n"X tdddd |j|j	 D }t
dt||S )	Nz<strong>%s</strong>zNo password set.z5Invalid password format or unknown hashing algorithm. z<strong>{}</strong>: {} c             s   s   | ]\}}t ||fV  qd S )N)r   ).0keyvalue r   =/tmp/pip-install-q3hcpn_q/Django/django/contrib/auth/forms.py	<genexpr>+   s    z4ReadOnlyPasswordHashWidget.render.<locals>.<genexpr>z<div{}>{}</div>)Zbuild_attrs
startswithr   r   r   r   
ValueErrorr   Zsafe_summaryitemsr   r   )selfnamer   attrsencodedZfinal_attrssummaryZhasherr   r   r   render   s    
z!ReadOnlyPasswordHashWidget.renderN)__name__
__module____qualname__r'   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t| j|| d S )NrequiredF)
setdefaultsuperr+   __init__)r"   argskwargs)	__class__r   r   r/   4   s    z"ReadOnlyPasswordHashField.__init__c             C   s   |S )Nr   )r"   datainitialr   r   r   
bound_data8   s    z$ReadOnlyPasswordHashField.bound_datac             C   s   dS )NFr   )r"   r4   r3   r   r   r   has_changed=   s    z%ReadOnlyPasswordHashField.has_changed)	r(   r)   r*   r   widgetr/   r5   r6   __classcell__r   r   )r2   r   r+   1   s   r+   c                   s   e Zd Z fddZ  ZS )UsernameFieldc                s   t jdtt| j|S )NNFKC)unicodedata	normalizer.   r9   	to_python)r"   r   )r2   r   r   r=   B   s    zUsernameField.to_python)r(   r)   r*   r=   r8   r   r   )r2   r   r9   A   s   r9   c                   s   e Zd ZdZdediZejeddejdZ	ejedejdedd	Z
G d
d dZ fddZ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_mismatchz%The two password fields didn't match.PasswordF)labelstripr7   zPassword confirmationz4Enter the same password as before, for verification.)rA   r7   rB   	help_textc               @   s   e Zd ZeZdZdeiZdS )zUserCreationForm.MetausernameN)rD   )r(   r)   r*   r	   modelfieldsr9   field_classesr   r   r   r   MetaZ   s   rH   c                sD   t t| j|| | jjj| jkr@| j| jjj jjj	ddi d S )N	autofocusr   )
r.   r>   r/   _metarE   USERNAME_FIELDrF   r7   r$   update)r"   r0   r1   )r2   r   r   r/   _   s    zUserCreationForm.__init__c             C   sf   | j jd}| j jd}|r<|r<||kr<tj| jd dd| j jd| j_tj| j jd| j |S )N	password1	password2r?   )coderD   )	cleaned_datagetr   ValidationErrorerror_messagesinstancerD   r   validate_password)r"   rM   rN   r   r   r   clean_password2d   s    z UserCreationForm.clean_password2Tc                s2   t t| jdd}|j| jd  |r.|j  |S )NF)commitrM   )r.   r>   saveset_passwordrP   )r"   rW   user)r2   r   r   rX   p   s
    zUserCreationForm.save)T)r(   r)   r*   __doc___rS   r   	CharFieldPasswordInputrM   rN   rH   r/   rV   rX   r8   r   r   )r2   r   r>   F   s   
r>   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 )
UserChangeFormr@   zRaw passwords are not stored, so there is no way to see this user's password, but you can change the password using <a href="../password/">this form</a>.)rA   rC   c               @   s   e Zd ZeZdZdeiZdS )zUserChangeForm.Meta__all__rD   N)r(   r)   r*   r	   rE   rF   r9   rG   r   r   r   r   rH      s   rH   c                s8   t t| j|| | jjd}|d k	r4|jjd|_d S )NZuser_permissionscontent_type)r.   r_   r/   rF   rQ   ZquerysetZselect_related)r"   r0   r1   f)r2   r   r   r/      s    zUserChangeForm.__init__c             C   s
   | j d S )Npassword)r4   )r"   r   r   r   clean_password   s    zUserChangeForm.clean_password)
r(   r)   r*   r+   r\   rc   rH   r/   rd   r8   r   r   )r2   r   r_   x   s   
r_   c                   s   e Zd ZdZedejddiddZeje	ddej
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.
       rI   r   )r$   )
max_lengthr7   r@   F)rA   rB   r7   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t| j|| t }|jj|j| _	| 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.
        NrD   )request
user_cacher.   re   r/   r   rJ   	get_fieldrK   username_fieldrF   rA   r   verbose_name)r"   rj   r0   r1   Z	UserModel)r2   r   r   r/      s    zAuthenticationForm.__init__c             C   sj   | j jd}| j jd}|rd|rdt||d| _| jd krXtj| jd dd| jjidn| j	| j | j S )NrD   rc   )rD   rc   rh   )rO   params)
rP   rQ   r   rk   r   rR   rS   rm   rn   confirm_login_allowed)r"   rD   rc   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   )rO   N)	is_activer   rR   rS   )r"   rZ   r   r   r   rp      s    z(AuthenticationForm.confirm_login_allowedc             C   s   | j r| j jS d S )N)rk   id)r"   r   r   r   get_user_id   s    zAuthenticationForm.get_user_idc             C   s   | j S )N)rk   )r"   r   r   r   get_user   s    zAuthenticationForm.get_user)N)r(   r)   r*   r[   r9   r   Z	TextInputrD   r]   r\   r^   rc   rS   r/   rq   rp   rt   ru   r8   r   r   )r2   r   re      s    
re   c            	   @   sL   e Zd Zejed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Emailrf   )rA   rg   Nc             C   sb   t j||}dj|j }t j||}t||||g}	|dk	rVt j||}
|	j|
d |	j  dS )zP
        Sends a django.core.mail.EmailMultiAlternatives to `to_email`.
        r   Nz	text/html)r   Zrender_to_stringjoin
splitlinesr   Zattach_alternativesend)r"   subject_template_nameemail_template_namecontext
from_emailZto_emailhtml_email_template_namesubjectbodyZemail_messageZ
html_emailr   r   r   	send_mail   s    zPasswordResetForm.send_mailc             C   s    t  jj|dd}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.
        T)Zemail__iexactrr   c             s   s   | ]}|j  r|V  qd S )N)Zhas_usable_password)r   ur   r   r   r     s    z.PasswordResetForm.get_users.<locals>.<genexpr>)r   Z_default_managerfilter)r"   emailZ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 }
x| j|
D ]~}|s4t|}|j}|j}n| }}|j||tt|j||j	||rbdndd}|	dk	r||j
|	 | j|||||j|d qW dS )ze
        Generates a one-use only link for resetting password and sends to the
        user.
        r   httpshttp)r   domain	site_nameuidrZ   tokenprotocolN)r~   )rP   r   r   r#   r   r   r   r   pkZ
make_tokenrL   r   )r"   Zdomain_overriderz   r{   Z	use_httpsZtoken_generatorr}   rj   r~   Zextra_email_contextr   rZ   Zcurrent_siter   r   r|   r   r   r   rX     s&    


zPasswordResetForm.save)N)r(   r)   r*   r   Z
EmailFieldr\   r   r   r   r
   rX   r   r   r   r   rv      s   
rv   c                   sp   e Zd ZdZdediZejedejde	j
 dZejeddej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
    r?   z%The two password fields didn't match.zNew passwordF)rA   r7   rB   rC   zNew password confirmation)rA   rB   r7   c                s   || _ tt| j|| d S )N)rZ   r.   r   r/   )r"   rZ   r0   r1   )r2   r   r   r/   ;  s    zSetPasswordForm.__init__c             C   sN   | j jd}| j jd}|r<|r<||kr<tj| jd ddtj|| j |S )Nnew_password1new_password2r?   )rO   )rP   rQ   r   rR   rS   r   rU   rZ   )r"   rM   rN   r   r   r   clean_new_password2?  s    z#SetPasswordForm.clean_new_password2Tc             C   s*   | j d }| jj| |r$| jj  | jS )Nr   )rP   rZ   rY   rX   )r"   rW   rc   r   r   r   rX   K  s
    

zSetPasswordForm.save)T)r(   r)   r*   r[   r\   rS   r   r]   r^   r   "password_validators_help_text_htmlr   r   r/   r   rX   r8   r   r   )r2   r   r   '  s   
r   c               @   sX   e Zd ZdZeejfdediZej	eddej
ddi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 passwordFrI   r   )r$   )rA   rB   r7   old_passwordr   r   c             C   s.   | j d }| jj|s*tj| jd dd|S )zC
        Validates that the old_password field is correct.
        r   r   )rO   )rP   rZ   Zcheck_passwordr   rR   rS   )r"   r   r   r   r   clean_old_passwordc  s    
z%PasswordChangeForm.clean_old_passwordN)r(   r)   r*   r[   dictr   rS   r\   r   r]   r^   r   Zfield_orderr   r   r   r   r   r   S  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idd	e
j d
Zejedej	d	edd
Z fddZdd ZdddZ fddZeeZ  ZS )AdminPasswordChangeFormzN
    A form used to change the password of a user in the admin interface.
    r?   z%The two password fields didn't match.r,   r@   rI   r   )r$   F)rA   r7   rB   rC   zPassword (again)z4Enter the same password as before, for verification.c                s   || _ tt| j|| d S )N)rZ   r.   r   r/   )r"   rZ   r0   r1   )r2   r   r   r/     s    z AdminPasswordChangeForm.__init__c             C   sN   | j jd}| j jd}|r<|r<||kr<tj| jd ddtj|| j |S )NrM   rN   r?   )rO   )rP   rQ   r   rR   rS   r   rU   rZ   )r"   rM   rN   r   r   r   rV     s    z'AdminPasswordChangeForm.clean_password2Tc             C   s*   | j d }| jj| |r$| jj  | jS )z)
        Saves the new password.
        rM   )rP   rZ   rY   rX   )r"   rW   rc   r   r   r   rX     s
    

zAdminPasswordChangeForm.savec                s2   t t| j}x| jj D ]}||krg S qW dgS )Nrc   )r.   r   changed_datarF   keys)r"   r3   r#   )r2   r   r   _get_changed_data  s
    z)AdminPasswordChangeForm._get_changed_data)T)r(   r)   r*   r[   r\   rS   Zrequired_css_classr   r]   r^   r   r   rM   rN   r/   rV   rX   r   propertyr   r8   r   r   )r2   r   r   p  s$   

r   )6
__future__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.forms.utilsr   Zdjango.templater   Zdjango.utils.encodingr   Zdjango.utils.htmlr   r   Zdjango.utils.httpr   Zdjango.utils.safestringr   Zdjango.utils.textr   Zdjango.utils.translationr   r   r\   ZWidgetr   ZFieldr+   r]   r9   Z	ModelFormr>   r_   ZFormre   rv   r   r   r   r   r   r   r   <module>   s4   2QB,