auth.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. from datetime import timedelta
  2. from django.conf import settings
  3. from django.utils import timezone
  4. from django.utils.translation import ugettext_lazy as _
  5. from misago.banning.models import check_ban
  6. from misago.security.models import SignInAttempt
  7. from misago.sessions.models import Token
  8. from misago.users.models import User
  9. """
  10. Exception constants
  11. """
  12. CREDENTIALS = 'security/bad_credentials'
  13. ACTIVATION_USER = 'users/activation_user'
  14. ACTIVATION_ADMIN = 'users/activation_admin'
  15. BANNED = 'banned'
  16. NOT_ADMIN = 'security/not_admin'
  17. class AuthException(Exception):
  18. """
  19. Auth Exception is thrown when auth_* method finds problem with allowing user to sign-in
  20. """
  21. def __init__(self, type=None, user=None, ban=None):
  22. self.type = type
  23. self.user = user
  24. self.ban = ban
  25. def __str__(self):
  26. return self.error
  27. def get_user(email, password, admin=False):
  28. """
  29. Fetch user from DB using email/pass pair, scream if either of data is incorrect
  30. """
  31. try:
  32. user = User.objects.get_by_email(email)
  33. if not user.check_password(password):
  34. raise AuthException(CREDENTIALS, user)
  35. if not admin:
  36. if user.activation == User.ACTIVATION_ADMIN:
  37. # Only admin can activate your account.
  38. raise AuthException(ACTIVATION_ADMIN, user)
  39. if user.activation != User.ACTIVATION_NONE:
  40. # Only admin can activate your account.
  41. raise AuthException(ACTIVATION_USER, user)
  42. except User.DoesNotExist:
  43. raise AuthException(CREDENTIALS)
  44. return user;
  45. def auth_forum(request, email, password):
  46. """
  47. Forum auth - check bans and if we are in maintenance - maintenance access
  48. """
  49. user = get_user(email, password)
  50. user_ban = check_ban(username=user.username, email=user.email)
  51. if user_ban:
  52. raise AuthException(BANNED, user, user_ban)
  53. return user;
  54. def auth_remember(request, ip):
  55. """
  56. Remember-me auth - check if token is valid
  57. Dont worry about AuthException being empty, it doesnt have to have anything
  58. """
  59. if request.firewall.admin:
  60. raise AuthException()
  61. if SignInAttempt.objects.is_jammed(request.settings, ip):
  62. raise AuthException()
  63. cookie_token = settings.COOKIES_PREFIX + 'TOKEN'
  64. try:
  65. cookie_token = request.COOKIES[cookie_token]
  66. if len(cookie_token) != 42:
  67. raise AuthException()
  68. try:
  69. token_rk = Token.objects.select_related().get(pk=cookie_token)
  70. except Token.DoesNotExist:
  71. request.cookie_jar.delete('TOKEN')
  72. raise AuthException()
  73. # See if token is not expired
  74. token_expires = timezone.now() - timedelta(days=request.settings['remember_me_lifetime'])
  75. if request.settings['remember_me_extensible'] and token_rk.accessed < token_expires:
  76. # Token expired because it's last use is smaller than expiration date
  77. raise AuthException()
  78. if not request.settings['remember_me_extensible'] and token_rk.created < token_expires:
  79. # Token expired because it was created before expiration date
  80. raise AuthException()
  81. # Update token date
  82. token_rk.accessed = timezone.now()
  83. token_rk.save(force_update=True)
  84. request.cookie_jar.set('TOKEN', token_rk.id, True)
  85. except (AttributeError, KeyError):
  86. raise AuthException()
  87. return token_rk
  88. def auth_admin(request, email, password):
  89. """
  90. Admin auth - check ACP permissions
  91. """
  92. user = get_user(email, password, True)
  93. if not user.is_admin():
  94. raise AuthException(NOT_ADMIN)
  95. return user;
  96. def sign_user_in(request, user, as_hidden=False):
  97. user.set_last_visit(
  98. request.session.get_ip(request),
  99. request.META.get('HTTP_USER_AGENT', ''),
  100. as_hidden
  101. )
  102. user.save(force_update=True)
  103. request.session.set_user(user)