auth.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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 = 0
  13. ACTIVATION_USER = 1
  14. ACTIVATION_ADMIN = 2
  15. BANNED = 3
  16. NOT_ADMIN = 4
  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, error=None, password=False, activation=False, ban=False):
  22. self.type = type
  23. self.error = error
  24. self.password = password
  25. self.activation = activation
  26. self.ban = ban
  27. def __str__(self):
  28. return self.error
  29. def get_user(email, password, admin=False):
  30. """
  31. Fetch user from DB using email/pass pair, scream if either of data is incorrect
  32. """
  33. try:
  34. user = User.objects.get_by_email(email)
  35. if not user.check_password(password):
  36. raise AuthException(CREDENTIALS, _("Your e-mail address or password is incorrect. Please try again."), password=True)
  37. if not admin:
  38. if user.activation == User.ACTIVATION_ADMIN:
  39. # Only admin can activate your account.
  40. raise AuthException(ACTIVATION_ADMIN, _("Board Administrator has not yet accepted your account."))
  41. if user.activation != User.ACTIVATION_NONE:
  42. # You have to activate your account - new member
  43. raise AuthException(ACTIVATION_USER, _("You have to activate your account before you will be able to sign-in."), activation=True)
  44. except User.DoesNotExist:
  45. raise AuthException(CREDENTIALS, _("Your e-mail address or password is incorrect. Please try again."), password=True)
  46. return user;
  47. def auth_forum(request, email, password):
  48. """
  49. Forum auth - check bans and if we are in maintenance - maintenance access
  50. """
  51. user = get_user(email, password)
  52. user_ban = check_ban(username=user.username, email=user.email)
  53. if user_ban:
  54. if user_ban.reason_user:
  55. raise AuthException(BANNED, _("Your account has been banned for following reason:"), ban=user_ban)
  56. raise AuthException(BANNED, _("Your account has been banned."), ban=user_ban)
  57. return user;
  58. def auth_remember(request, ip):
  59. """
  60. Remember-me auth - check if token is valid
  61. Dont worry about AuthException being empty, it doesnt have to have anything
  62. """
  63. if request.firewall.admin:
  64. raise AuthException()
  65. if SignInAttempt.objects.is_jammed(request.settings, ip):
  66. raise AuthException()
  67. cookie_token = settings.COOKIES_PREFIX + 'TOKEN'
  68. try:
  69. cookie_token = request.COOKIES[cookie_token]
  70. if len(cookie_token) != 42:
  71. raise AuthException()
  72. try:
  73. token_rk = Token.objects.select_related().get(pk=cookie_token)
  74. except Token.DoesNotExist:
  75. request.cookie_jar.delete('TOKEN')
  76. raise AuthException()
  77. # See if token is not expired
  78. token_expires = timezone.now() - timedelta(days=request.settings['remember_me_lifetime'])
  79. if request.settings['remember_me_extensible'] and token_rk.accessed < token_expires:
  80. # Token expired because it's last use is smaller than expiration date
  81. raise AuthException()
  82. if not request.settings['remember_me_extensible'] and token_rk.created < token_expires:
  83. # Token expired because it was created before expiration date
  84. raise AuthException()
  85. # Update token date
  86. token_rk.accessed = timezone.now()
  87. token_rk.save(force_update=True)
  88. request.cookie_jar.set('TOKEN', token_rk.id, True)
  89. except (AttributeError, KeyError):
  90. raise AuthException()
  91. return token_rk
  92. def auth_admin(request, email, password):
  93. """
  94. Admin auth - check ACP permissions
  95. """
  96. user = get_user(email, password, True)
  97. if not user.is_admin():
  98. raise AuthException(NOT_ADMIN, _("Your account does not have admin privileges."))
  99. return user;
  100. def sign_user_in(request, user):
  101. user.set_last_visit(
  102. request.session.get_ip(request),
  103. request.META.get('HTTP_USER_AGENT', ''),
  104. )
  105. user.save(force_update=True)
  106. request.session.set_user(user)
  107. if request.settings['sessions_hidden']:
  108. request.session.set_hidden(user.hide_activity > 0)