Guest User

Untitled

a guest
Jun 25th, 2018
271
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.21 KB | None | 0 0
  1. import re
  2. from functools import partial
  3.  
  4. from django.contrib.auth.hashers import check_password
  5. from django.core.exceptions import ValidationError
  6. from django.template.defaultfilters import pluralize
  7. from django.utils.translation import ugettext_lazy as _
  8.  
  9. from users.models import PasswordHistory
  10.  
  11.  
  12. class LastPasswordValidator(object):
  13. """
  14. Validate whether the password is not equal last passwords.
  15. """
  16. def __init__(self, last_password_compare_count=12):
  17. self.last_password_compare_count = last_password_compare_count
  18.  
  19. def validate(self, password, user=None):
  20. if user:
  21. last_passwords = PasswordHistory.objects.filter(user=user)\
  22. .order_by('-created_at').values_list('password', flat=True)
  23. last_passwords = last_passwords[:self.last_password_compare_count]
  24. check_last_password = partial(check_password, password)
  25. equal_passwords = filter(check_last_password, last_passwords)
  26. if list(equal_passwords):
  27. raise ValidationError(
  28. _('This password repeats your previous %(value)s password%(plural)s.'),
  29. code='password_repeat',
  30. params={
  31. 'value': self.last_password_compare_count,
  32. 'plural': pluralize(self.last_password_compare_count),
  33. }
  34. )
  35.  
  36. def get_help_text(self):
  37. return _("Your password can't repeat your previous passwords.")
  38.  
  39.  
  40. class NumberSequenceValidator(object):
  41. """
  42. Validate whether the password is not contain number sequence such as '456'.
  43. """
  44. sequence = '0123456789'
  45. reversed_sequence = sequence[::-1]
  46.  
  47. def __init__(self, sequence_length=3):
  48. self.sequence_length = sequence_length
  49.  
  50. def _get_sequence_pieces(self, sequence):
  51. origin_sequence = sequence[:]
  52. sequence = (origin_sequence[num:num + self.sequence_length]
  53. for num, i in enumerate(sequence))
  54. return filter(lambda x: len(x) == self.sequence_length, sequence)
  55.  
  56. def _get_validation_regex(self):
  57. pieces = self._get_sequence_pieces(self.sequence)
  58. reversed_pieces = self._get_sequence_pieces(self.reversed_sequence)
  59. simple_pieces = (x*self.sequence_length for x in self.sequence)
  60. pieces = tuple(pieces) + tuple(reversed_pieces) + tuple(simple_pieces)
  61. pieces = '|'.join(pieces)
  62.  
  63. return f'({pieces})'
  64.  
  65. def validate(self, password, user=None):
  66. if user:
  67. validation_regex = self._get_validation_regex()
  68. if re.search(validation_regex, password):
  69. raise ValidationError(
  70. _('This password contains digit sequence.'),
  71. code='password_contain_digit_sequence',
  72. )
  73.  
  74. def get_help_text(self):
  75. return _("Your password can't contain digit sequence.")
  76.  
  77.  
  78. class ComplexityValidator(object):
  79. """
  80. Password must contains characters from at least three of the bellow groups:
  81. * English uppercase characters (A-Z)
  82. * English lowercase characters (a-z)
  83. * Numerals (0-9)
  84. * Non-alphabetic characters (! $ # %)
  85. """
  86. UPPERCASE_REGEX = r'[A-Z]'
  87. LOWERCASE_REGEX = r'[a-z]'
  88. NUMERALS_REGEX = r'[0-9]'
  89. SPECIAL_CHARS_REGEX = r'[\!\$\*\?\[\]\(\)\/\\#%&@]'
  90. VALIDATION_REGEX = (UPPERCASE_REGEX, LOWERCASE_REGEX,
  91. NUMERALS_REGEX, SPECIAL_CHARS_REGEX)
  92.  
  93. def __init__(self, min_group_count=3):
  94. self.min_group_count = min_group_count
  95.  
  96. def validate(self, password, user=None):
  97. if user:
  98. contain_symbol_group = 0
  99. for regex in self.VALIDATION_REGEX:
  100. if re.search(regex, password):
  101. contain_symbol_group += 1
  102.  
  103. if contain_symbol_group < self.min_group_count:
  104. raise ValidationError(
  105. _('This password must contains english upper and lower '
  106. 'case characters and numerals or special characters.'),
  107. code='password_is_simple',
  108. )
  109.  
  110. def get_help_text(self):
  111. return _("Your password must contains english upper and lower case "
  112. "characters and numerals or special characters.")
Add Comment
Please, Sign In to add comment