errorpages.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. from django.http import JsonResponse
  2. from django.shortcuts import render
  3. from django.utils.translation import gettext as _
  4. from social_core import exceptions as social_exceptions
  5. from ..admin.views.errorpages import admin_csrf_failure, admin_error_page
  6. from ..socialauth.providers import providers
  7. from .exceptions import SocialAuthBanned, SocialAuthFailed
  8. from .utils import get_exception_message, is_request_to_misago
  9. def _is_ajax(request):
  10. # Request is AJAX when done with XMLHttpRequest
  11. if request.headers.get("x-requested-with") == "XMLHttpRequest":
  12. return True
  13. # Assume that request is AJAX when it has JSON payload
  14. return "application/json" in request.headers.get("content-type", "")
  15. def _ajax_error(code, exception=None, default_message=None):
  16. return JsonResponse(
  17. {"detail": get_exception_message(exception, default_message)}, status=code
  18. )
  19. @admin_error_page
  20. def _error_page(request, code, exception=None, default_message=None):
  21. request.frontend_context.update({"CURRENT_LINK": "misago:error-%s" % code})
  22. return render(
  23. request,
  24. "misago/errorpages/%s.html" % code,
  25. {"message": get_exception_message(exception, default_message)},
  26. status=code,
  27. )
  28. def banned(request, exception):
  29. ban = exception.ban
  30. request.frontend_context.update(
  31. {"MESSAGE": ban.get_serialized_message(), "CURRENT_LINK": "misago:error-banned"}
  32. )
  33. return render(request, "misago/errorpages/banned.html", {"ban": ban}, status=403)
  34. def permission_denied(request, exception):
  35. if _is_ajax(request):
  36. return _ajax_error(403, exception, _("Permission denied."))
  37. return _error_page(request, 403, exception)
  38. def page_not_found(request, exception):
  39. if _is_ajax(request):
  40. return _ajax_error(404, exception, "Not found.")
  41. return _error_page(request, 404, exception)
  42. def social_auth_failed(request, exception):
  43. backend_name = None
  44. ban = None
  45. help_text = None
  46. message = None
  47. try:
  48. backend_name = exception.backend_name
  49. except AttributeError:
  50. pass
  51. try:
  52. exception_backend = exception.backend
  53. backend_name = providers.get_name(exception_backend.name)
  54. except AttributeError:
  55. pass
  56. if isinstance(exception, social_exceptions.NotAllowedToDisconnect):
  57. message = _(
  58. "A problem was encountered when disconnecting your account "
  59. "from the remote site."
  60. )
  61. help_text = _(
  62. "You are not allowed to disconnect your account from the other site, "
  63. "because currently it's the only way to sign in to your account."
  64. )
  65. elif backend_name:
  66. message = _(
  67. "A problem was encountered when signing you in using %(backend)s."
  68. ) % {"backend": backend_name}
  69. if isinstance(exception, social_exceptions.AuthCanceled):
  70. help_text = _("The sign in process has been canceled by user.")
  71. if isinstance(exception, social_exceptions.AuthUnreachableProvider):
  72. help_text = _("The other service could not be reached.")
  73. if isinstance(exception, SocialAuthFailed):
  74. help_text = exception.message
  75. if isinstance(exception, SocialAuthBanned):
  76. ban = exception.ban
  77. else:
  78. message = _("Unexpected problem has been encountered during sign in process.")
  79. return render(
  80. request,
  81. "misago/errorpages/social.html",
  82. {
  83. "backend_name": backend_name,
  84. "ban": ban,
  85. "message": message,
  86. "help_text": help_text,
  87. },
  88. status=403,
  89. )
  90. @admin_csrf_failure
  91. def csrf_failure(request, reason=""):
  92. if _is_ajax(request):
  93. return JsonResponse(
  94. {
  95. "detail": _(
  96. "Your request was rejected because your browser didn't "
  97. "send the CSRF cookie, or the cookie sent was invalid."
  98. )
  99. },
  100. status=403,
  101. )
  102. return render(request, "misago/errorpages/csrf_failure.html", status=403)
  103. def not_allowed(request):
  104. return _error_page(request, 405)
  105. # Decorators for custom error page handlers
  106. def shared_403_exception_handler(f):
  107. def page_decorator(request, *args, **kwargs):
  108. if is_request_to_misago(request):
  109. return permission_denied(request, *args, **kwargs)
  110. return f(request, *args, **kwargs)
  111. return page_decorator
  112. def shared_404_exception_handler(f):
  113. def page_decorator(request, *args, **kwargs):
  114. if is_request_to_misago(request):
  115. return page_not_found(request, *args, **kwargs)
  116. return f(request, *args, **kwargs)
  117. return page_decorator