3
(hr                 @   sF  d dl mZ d dlZd dlZd dl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 d d
lmZ d dlmZ d dlmZmZ d dlmZmZ ejdddd Zdd Z d#ddZ!d$ddZ"d%ddZ#d&ddZ$ee$eZ%G dd de&Z'G dd de&Z(G dd  d e&Z)G d!d" d"e&Z*dS )'    )unicode_literalsN)SequenceMatcher)settings)ImproperlyConfiguredValidationError)	lru_cache)upath)
force_text)lazy)format_html)import_string)string_types	text_type)ugettext	ungettext)maxsizec               C   s
   t tjS )N)get_password_validatorsr   ZAUTH_PASSWORD_VALIDATORS r   r   K/tmp/pip-install-q3hcpn_q/Django/django/contrib/auth/password_validation.pyget_default_password_validators   s    r   c             C   sh   g }x^| D ]V}yt |d }W n( tk
rF   d}t||d  Y nX |j|f |jdi  q
W |S )NNAMEzZThe module in NAME could not be imported: %s. Check your AUTH_PASSWORD_VALIDATORS setting.OPTIONS)r   ImportErrorr   appendget)Zvalidator_configZ
validators	validatorklassmsgr   r   r   r      s    
r   c             C   sn   g }|dkrt  }xJ|D ]B}y|j| | W q tk
rX } z|j| W Y dd}~X qX qW |rjt|dS )z
    Validate whether the password meets all validator requirements.

    If the password is valid, return ``None``.
    If the password is invalid, raise ValidationError with all error messages.
    N)r   validater   r   )passworduserpassword_validatorserrorsr   errorr   r   r   validate_password&   s    
 r$   c             C   s:   |dkrt  }x&|D ]}t|ddd }|| | qW dS )zy
    Inform all validators that have implemented a password_changed() method
    that the password has been changed.
    Npassword_changedc              W   s   d S )Nr   )ar   r   r   <lambda>A   s    z"password_changed.<locals>.<lambda>)r   getattr)r   r    r!   r   r%   r   r   r   r%   9   s
    
r%   c             C   s2   g }| dkrt  } x| D ]}|j|j  qW |S )zG
    Return a list of all help texts of all configured validators.
    N)r   r   get_help_text)r!   
help_textsr   r   r   r   password_validators_help_textsE   s    
r+   c             C   s,   t | }dd |D }|r(ddj| S dS )z`
    Return an HTML string with all help texts of all configured validators
    in an <ul>.
    c             S   s   g | ]}t d |qS )z<li>{}</li>)r   ).0	help_textr   r   r   
<listcomp>W   s    z7_password_validators_help_text_html.<locals>.<listcomp>z<ul>%s</ul> )r+   join)r!   r*   Z
help_itemsr   r   r   #_password_validators_help_text_htmlQ   s    r1   c               @   s,   e Zd ZdZd
ddZdddZdd	 ZdS )MinimumLengthValidatorz?
    Validate whether the password is of a minimum length.
       c             C   s
   || _ d S )N)
min_length)selfr4   r   r   r   __init__`   s    zMinimumLengthValidator.__init__Nc             C   s0   t || jk r,ttdd| jdd| jidd S )NzNThis password is too short. It must contain at least %(min_length)d character.zOThis password is too short. It must contain at least %(min_length)d characters.Zpassword_too_shortr4   )codeparams)lenr4   r   r   )r5   r   r    r   r   r   r   c   s    zMinimumLengthValidator.validatec             C   s   t dd| jd| ji S )Nz=Your password must contain at least %(min_length)d character.z>Your password must contain at least %(min_length)d characters.r4   )r   r4   )r5   r   r   r   r)   o   s
    z$MinimumLengthValidator.get_help_text)r3   )N)__name__
__module____qualname____doc__r6   r   r)   r   r   r   r   r2   \   s   

r2   c               @   s4   e Zd ZdZdZedfddZdd
dZdd Zd	S ) UserAttributeSimilarityValidatora  
    Validate whether the password is sufficiently different from the user's
    attributes.

    If no specific attributes are provided, look at a sensible list of
    defaults. Attributes that don't exist are ignored. Comparison is made to
    not only the full attribute value, but also its components, so that, for
    example, a password is validated against either part of an email address,
    as well as the full address.
    username
first_name	last_nameemailgffffff?c             C   s   || _ || _d S )N)user_attributesmax_similarity)r5   rC   rD   r   r   r   r6      s    z)UserAttributeSimilarityValidator.__init__Nc             C   s   |sd S x| j D ]}t||d }| st|t r4qtjd||g }xR|D ]J}t|j |j dj | j	krLt
|jj|j}ttddd|idqLW qW d S )Nz\W+)r&   bz4The password is too similar to the %(verbose_name)s.Zpassword_too_similarverbose_name)r7   r8   )rC   r(   
isinstancer   resplitr   lowerZquick_ratiorD   r	   Z_meta	get_fieldrF   r   _)r5   r   r    Zattribute_namevalueZvalue_partsZ
value_partrF   r   r   r   r      s    
z)UserAttributeSimilarityValidator.validatec             C   s   t dS )NzFYour password can't be too similar to your other personal information.)rL   )r5   r   r   r   r)      s    z.UserAttributeSimilarityValidator.get_help_text)r?   r@   rA   rB   )N)r:   r;   r<   r=   ZDEFAULT_USER_ATTRIBUTESr6   r   r)   r   r   r   r   r>   w   s
   

r>   c               @   sP   e Zd ZdZejjejjejje	e
dZefddZd
ddZdd	 ZdS )CommonPasswordValidatora#  
    Validate whether the password is a common password.

    The password is rejected if it occurs in a provided list, which may be gzipped.
    The list Django ships with contains 1000 common passwords, created by Mark Burnett:
    https://xato.net/passwords/more-top-worst-passwords/
    zcommon-passwords.txt.gzc             C   sb   yt j|j jdj }W n0 tk
rL   t|}|j }W d Q R X Y nX dd |D | _d S )Nzutf-8c             S   s   h | ]}|j  qS r   )strip)r,   pr   r   r   	<setcomp>   s    z3CommonPasswordValidator.__init__.<locals>.<setcomp>)gzipopenreaddecode
splitlinesIOError	readlines	passwords)r5   Zpassword_list_pathZcommon_passwords_linesfr   r   r   r6      s    
z CommonPasswordValidator.__init__Nc             C   s&   |j  j | jkr"ttdddd S )NzThis password is too common.Zpassword_too_common)r7   )rJ   rO   rY   r   rL   )r5   r   r    r   r   r   r      s    z CommonPasswordValidator.validatec             C   s   t dS )Nz0Your password can't be a commonly used password.)rL   )r5   r   r   r   r)      s    z%CommonPasswordValidator.get_help_text)N)r:   r;   r<   r=   ospathr0   dirnamerealpathr   __file__ZDEFAULT_PASSWORD_LIST_PATHr6   r   r)   r   r   r   r   rN      s   	
rN   c               @   s"   e Zd ZdZdddZdd ZdS )NumericPasswordValidatorz8
    Validate whether the password is alphanumeric.
    Nc             C   s   |j  rttdddd S )Nz"This password is entirely numeric.Zpassword_entirely_numeric)r7   )isdigitr   rL   )r5   r   r    r   r   r   r      s    z!NumericPasswordValidator.validatec             C   s   t dS )Nz(Your password can't be entirely numeric.)rL   )r5   r   r   r   r)      s    z&NumericPasswordValidator.get_help_text)N)r:   r;   r<   r=   r   r)   r   r   r   r   r`      s   
r`   )NN)NN)N)N)+
__future__r   rR   r[   rH   difflibr   Zdjango.confr   Zdjango.core.exceptionsr   r   Zdjango.utilsr   Zdjango.utils._osr   Zdjango.utils.encodingr	   Zdjango.utils.functionalr
   Zdjango.utils.htmlr   Zdjango.utils.module_loadingr   Zdjango.utils.sixr   r   Zdjango.utils.translationr   rL   r   r   r   r$   r%   r+   r1   Z"password_validators_help_text_htmlobjectr2   r>   rN   r`   r   r   r   r   <module>   s2   




' 