/kai/model/validators.py

https://bitbucket.org/bbangert/kai/ · Python · 115 lines · 91 code · 22 blank · 2 comment · 23 complexity · ee392fb3500e6943321a49fbb892ea2f MD5 · raw file

  1. """Custom validators"""
  2. import re
  3. from datetime import datetime
  4. import formencode
  5. import pylons
  6. from kai.model import Human, Snippet
  7. class ExistingSnippetTitle(formencode.FancyValidator):
  8. def _to_python(self, value, state):
  9. if Snippet.exists(value):
  10. route_data = pylons.request.environ['pylons.routes_dict']
  11. slug = value.replace(" ", "_")
  12. slug = slug.lower()
  13. slug = re.sub('[^A-Za-z0-9_]+', '', slug)
  14. if route_data['action'] == 'update' and slug == route_data['id']:
  15. return value
  16. raise formencode.Invalid('Title already exists', value, state)
  17. return value
  18. class ExistingEmail(formencode.FancyValidator):
  19. def _to_python(self, value, state):
  20. if not isinstance(value, basestring):
  21. raise formencode.Invalid('Invalid e-mail address type')
  22. users = list(Human.by_email(pylons.tmpl_context.db)[value])
  23. if not users:
  24. raise formencode.Invalid('No such e-mail address was found',
  25. value, state)
  26. user = users[0]
  27. # Check to see if the user has recently asked for an email token
  28. if user.password_token_issue:
  29. diff = datetime.utcnow() - user.password_token_issue
  30. if diff.days < 1 and diff.seconds < 3600:
  31. raise formencode.Invalid(
  32. "You've already requested a password recently. Please "
  33. "wait and try later.", value, state)
  34. return value
  35. class UniqueDisplayname(formencode.FancyValidator):
  36. def _to_python(self, value, state):
  37. if list(Human.by_displayname(pylons.tmpl_context.db)[value]):
  38. raise formencode.Invalid('Display name already exists',
  39. value, state)
  40. else:
  41. return value
  42. class UniqueEmail(formencode.FancyValidator):
  43. def _to_python(self, value, state):
  44. if list(Human.by_email(pylons.tmpl_context.db)[value]):
  45. raise formencode.Invalid('Email address already exists', value,
  46. state)
  47. else:
  48. return value
  49. class ValidPassword(formencode.FancyValidator):
  50. def _to_python(self, value, state):
  51. if len(value) < 6:
  52. raise formencode.Invalid('Password is too short, must be at least'
  53. ' 6 characters', value, state)
  54. return value
  55. class ValidLogin(formencode.FancyValidator):
  56. field_names = None
  57. validate_partial_form = False
  58. email = None
  59. answer = None
  60. password = None
  61. messages = {
  62. 'badlogin': "Invalid email and/or password",
  63. }
  64. def is_empty(self, value):
  65. return False
  66. def validate_python(self, field_dict, state):
  67. errors = {}
  68. email = field_dict[self.email]
  69. password = field_dict[self.password]
  70. if isinstance(email, basestring):
  71. users = list(Human.by_email(pylons.tmpl_context.db)[email])
  72. else:
  73. users = None
  74. if users:
  75. user = users[0]
  76. else:
  77. user = None
  78. if not user:
  79. errors[self.email] = self.message('badlogin', state)
  80. if not errors:
  81. valid_password = user.verify_password(password)
  82. if valid_password:
  83. field_dict['user'] = user
  84. else:
  85. errors[self.email] = self.message('badlogin', state)
  86. if errors:
  87. error_list = errors.items()
  88. error_list.sort()
  89. error_message = '<br>\n'.join(
  90. ['%s: %s' % (name, value) for name, value in error_list])
  91. raise formencode.Invalid(error_message,
  92. field_dict, state,
  93. error_dict=errors)