middleware.py 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. # -*- coding: utf-8 -*-
  2. import six
  3. from django.apps import apps
  4. from django.conf import settings
  5. from django.contrib import messages
  6. from django.contrib.messages.api import MessageFailure
  7. from django.shortcuts import redirect
  8. from django.utils.http import urlquote
  9. from social_core.exceptions import SocialAuthBaseException
  10. from social_core.utils import social_logger
  11. from .compat import MiddlewareMixin
  12. class SocialAuthExceptionMiddleware(MiddlewareMixin):
  13. """Middleware that handles Social Auth AuthExceptions by providing the user
  14. with a message, logging an error, and redirecting to some next location.
  15. By default, the exception message itself is sent to the user and they are
  16. redirected to the location specified in the SOCIAL_AUTH_LOGIN_ERROR_URL
  17. setting.
  18. This middleware can be extended by overriding the get_message or
  19. get_redirect_uri methods, which each accept request and exception.
  20. """
  21. def process_exception(self, request, exception):
  22. strategy = getattr(request, 'social_strategy', None)
  23. if strategy is None or self.raise_exception(request, exception):
  24. return
  25. if isinstance(exception, SocialAuthBaseException):
  26. backend = getattr(request, 'backend', None)
  27. backend_name = getattr(backend, 'name', 'unknown-backend')
  28. message = self.get_message(request, exception)
  29. url = self.get_redirect_uri(request, exception)
  30. if apps.is_installed('django.contrib.messages'):
  31. social_logger.info(message)
  32. try:
  33. messages.error(request, message,
  34. extra_tags='social-auth ' + backend_name)
  35. except MessageFailure:
  36. if url:
  37. url += ('?' in url and '&' or '?') + \
  38. 'message={0}&backend={1}'.format(urlquote(message),
  39. backend_name)
  40. else:
  41. social_logger.error(message)
  42. if url:
  43. return redirect(url)
  44. def raise_exception(self, request, exception):
  45. strategy = getattr(request, 'social_strategy', None)
  46. if strategy is not None:
  47. return strategy.setting('RAISE_EXCEPTIONS') or settings.DEBUG
  48. def get_message(self, request, exception):
  49. return six.text_type(exception)
  50. def get_redirect_uri(self, request, exception):
  51. strategy = getattr(request, 'social_strategy', None)
  52. return strategy.setting('LOGIN_ERROR_URL')