mirror of
https://github.com/zulip/zulip.git
synced 2025-10-24 08:33:43 +00:00
exceptions: Extract json_unauths into MissingAuthenticationError.
We raise two types of json_unauthorized when MissingAuthenticationError is raised. Raising the one with www_authenticate let's the client know that user needs to be logged in to access the requested content. Sending `www_authenticate='session'` header with the response also stops modern web-browsers from showing a login form to the user and let's the client handle it completely. Structurally, this moves the handling of common authentication errors to a single shared middleware exception handler.
This commit is contained in:
@@ -7,7 +7,7 @@ from typing import Any, AnyStr, Callable, Dict, Iterable, List, MutableMapping,
|
||||
from django.conf import settings
|
||||
from django.core.handlers.wsgi import WSGIRequest
|
||||
from django.db import connection
|
||||
from django.http import HttpRequest, HttpResponse, StreamingHttpResponse
|
||||
from django.http import HttpRequest, HttpResponse, HttpResponseRedirect, StreamingHttpResponse
|
||||
from django.middleware.common import CommonMiddleware
|
||||
from django.shortcuts import render
|
||||
from django.utils.deprecation import MiddlewareMixin
|
||||
@@ -19,11 +19,11 @@ from sentry_sdk.integrations.logging import ignore_logger
|
||||
from zerver.lib.cache import get_remote_cache_requests, get_remote_cache_time
|
||||
from zerver.lib.db import reset_queries
|
||||
from zerver.lib.debug import maybe_tracemalloc_listen
|
||||
from zerver.lib.exceptions import ErrorCode, JsonableError, RateLimited
|
||||
from zerver.lib.exceptions import ErrorCode, JsonableError, MissingAuthenticationError, RateLimited
|
||||
from zerver.lib.html_to_text import get_content_description
|
||||
from zerver.lib.markdown import get_markdown_requests, get_markdown_time
|
||||
from zerver.lib.rate_limiter import RateLimitResult
|
||||
from zerver.lib.response import json_error, json_response_from_error
|
||||
from zerver.lib.response import json_error, json_response_from_error, json_unauthorized
|
||||
from zerver.lib.subdomains import get_subdomain
|
||||
from zerver.lib.types import ViewFuncT
|
||||
from zerver.lib.utils import statsd
|
||||
@@ -301,6 +301,23 @@ class JsonErrorHandler(MiddlewareMixin):
|
||||
ignore_logger("zerver.middleware.json_error_handler")
|
||||
|
||||
def process_exception(self, request: HttpRequest, exception: Exception) -> Optional[HttpResponse]:
|
||||
if isinstance(exception, MissingAuthenticationError):
|
||||
if 'text/html' in request.META.get('HTTP_ACCEPT', ''):
|
||||
# If this looks like a request from a top-level page in a
|
||||
# browser, send the user to the login page.
|
||||
#
|
||||
# TODO: The next part is a bit questionable; it will
|
||||
# execute the likely intent for intentionally visiting
|
||||
# an API endpoint without authentication in a browser,
|
||||
# but that's an unlikely to be done intentionally often.
|
||||
return HttpResponseRedirect(f'{settings.HOME_NOT_LOGGED_IN}?next={request.path}')
|
||||
if request.path.startswith("/api"):
|
||||
# For API routes, ask for HTTP basic auth (email:apiKey).
|
||||
return json_unauthorized()
|
||||
else:
|
||||
# For /json routes, ask for session authentication.
|
||||
return json_unauthorized(www_authenticate='session')
|
||||
|
||||
if isinstance(exception, JsonableError):
|
||||
return json_response_from_error(exception)
|
||||
if request.error_format == "JSON":
|
||||
|
||||
Reference in New Issue
Block a user