o 3a"@sddlZddlZddlZddlmZddlmZddlmZddl m Z m Z m Z ddl mZddlmZmZddlmZdd lmZmZejdd d d Zd dZd!ddZd!ddZd"ddZd"ddZeeeZ GdddZ!ddZ"GdddZ#GdddZ$Gdd d Z%dS)#N)SequenceMatcher)Path)settings)FieldDoesNotExistImproperlyConfiguredValidationError)lazy) format_htmlformat_html_join) import_string)gettextngettext)maxsizecCs ttjSN)get_password_validatorsrAUTH_PASSWORD_VALIDATORSrrI/usr/lib/python3/dist-packages/django/contrib/auth/password_validation.pyget_default_password_validatorss rc Csbg}|D]*}zt|d}Wntyd}t||dw||di|diq|S)NNAMEzZThe module in NAME could not be imported: %s. Check your AUTH_PASSWORD_VALIDATORS setting.OPTIONSr)r ImportErrorrappendget)validator_config validators validatorklassmsgrrrrs rc Csjg}|dur t}|D]!}z|||Wq ty,}z ||WYd}~q d}~ww|r3t|dS)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)rvalidaterr)passworduserpassword_validatorserrorsrerrorrrrvalidate_password#sr%cCs6|durt}|D]}t|ddd}|||q dS)zy Inform all validators that have implemented a password_changed() method that the password has been changed. Npassword_changedcWsdSrr)arrr>sz"password_changed..)rgetattr)r r!r"rr&rrrr&6s  r&cCs.g}|dur t}|D] }||q |S)zG Return a list of all help texts of all configured validators. N)rr get_help_text)r" help_textsrrrrpassword_validators_help_textsBs r,cCs0t|}tdddd|D}|rtd|SdS)z` Return an HTML string with all help texts of all configured validators in an
    . z
  • {}
  • css|]}|fVqdSrr).0 help_textrrr Tsz6_password_validators_help_text_html..z
      {}
    )r,r r )r"r+ help_itemsrrr#_password_validators_help_text_htmlNsr2c@s,eZdZdZd ddZd ddZdd ZdS) MinimumLengthValidatorz? Validate whether the password is of a minimum length. cCs ||_dSr) min_length)selfr5rrr__init___s zMinimumLengthValidator.__init__NcCs0t||jkrttdd|jdd|jiddS)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.password_too_shortr5codeparams)lenr5rr r6r r!rrrrbszMinimumLengthValidator.validatecCstdd|jd|jiS)Nz=Your password must contain at least %(min_length)d character.z>Your password must contain at least %(min_length)d characters.r5)r r5r6rrrr*nsz$MinimumLengthValidator.get_help_text)r4r)__name__ __module__ __qualname____doc__r7rr*rrrrr3[s    r3cCs0t|}|d|}t|}|d|ko||kS)a Test that value is within a reasonable range of password. The following ratio calculations are based on testing SequenceMatcher like this: for i in range(0,6): print(10**i, SequenceMatcher(a='A', b='A'*(10**i)).quick_ratio()) which yields: 1 1.0 10 0.18181818181818182 100 0.019801980198019802 1000 0.001998001998001998 10000 0.00019998000199980003 100000 1.999980000199998e-05 This means a length_ratio of 10 should never yield a similarity higher than 0.2, for 100 this is down to 0.02 and for 1000 it is 0.002. This can be calculated via 2 / length_ratio. As a result we avoid the potentially expensive sequence matching.  )r<)r max_similarityvaluepwd_lenlength_bound_similarity value_lenrrrexceeds_maximum_length_ratiovs rJc@s4eZdZdZdZedfddZd ddZd d ZdS) 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_nameemailgffffff?cCs ||_|dkr td||_dS)Ng?z#max_similarity must be at least 0.1)user_attributes ValueErrorrE)r6rPrErrrr7s z)UserAttributeSimilarityValidator.__init__Nc Cs|sdS|}|jD]W}t||d}|rt|tsq |}td||g}|D]7}t||j|r4q*t ||d |jkraz t|j |j }Wn tyU|}Ynwttddd|idq*q dS)Nz\W+)r'bz4The password is too similar to the %(verbose_name)s.password_too_similar verbose_namer9)lowerrPr) isinstancestrresplitrJrEr quick_ratio_meta get_fieldrTrr_) r6r r!attribute_namerF value_lower value_parts value_partrTrrrrs4   z)UserAttributeSimilarityValidator.validatecCtdS)NuHYour password can’t be too similar to your other personal information.r]r>rrrr*z.UserAttributeSimilarityValidator.get_help_textr)r?r@rArBDEFAULT_USER_ATTRIBUTESr7rr*rrrrrKs    rKc@s@eZdZdZeejdZefddZ d ddZ dd Z dS) CommonPasswordValidatora Validate whether the password is a common password. The password is rejected if it occurs in a provided list of passwords, which may be gzipped. The list Django ships with contains 20000 common passwords (lowercased and deduplicated), created by Royce Williams: https://gist.github.com/roycewilliams/281ce539915a947a23db17137d91aeb7 The password list must be lowercased to match the comparison in validate(). zcommon-passwords.txt.gzc Csz%tj|ddd}dd|D|_WdWdS1swYWdStyMt|}dd|D|_WdYdS1sEwYYdSw)Nrtzutf-8)encodingcSh|]}|qSrstripr.xrrr z3CommonPasswordValidator.__init__..cSrirrjrlrrrrnro)gzipopen passwordsOSError)r6password_list_pathfrrrr7s&  &z CommonPasswordValidator.__init__NcCs&||jvrttddddS)NzThis password is too common.password_too_commonr:)rUrkrrrr]r=rrrrs z CommonPasswordValidator.validatecCrb)Nu2Your password can’t be a commonly used password.rcr>rrrr*rdz%CommonPasswordValidator.get_help_textr) r?r@rArBr__file__resolveparentDEFAULT_PASSWORD_LIST_PATHr7rr*rrrrrfs    rfc@s"eZdZdZdddZddZdS)NumericPasswordValidatorz8 Validate whether the password is alphanumeric. NcCs|r ttddddS)Nz"This password is entirely numeric.password_entirely_numericrw)isdigitrr]r=rrrrs z!NumericPasswordValidator.validatecCrb)Nu*Your password can’t be entirely numeric.rcr>rrrr*rdz&NumericPasswordValidator.get_help_textr)r?r@rArBrr*rrrrr|s  r|)NNr)& functoolsrprXdifflibrpathlibr django.confrdjango.core.exceptionsrrrdjango.utils.functionalrdjango.utils.htmlr r django.utils.module_loadingr django.utils.translationr r]r lru_cacherrr%r&r,r2rW"password_validators_help_text_htmlr3rJrKrfr|rrrrs0         0