Handle next parameter on the token auth page to correctly redirect to the initiating page

This commit is contained in:
Oliver Falk
2025-09-08 12:52:24 +02:00
parent 13f13f7443
commit 4abbfeaa36

View File

@@ -7,6 +7,7 @@ import secrets
from typing import Optional from typing import Optional
from django.views.generic.base import View from django.views.generic.base import View
from django.http import JsonResponse, HttpRequest, HttpResponseRedirect from django.http import JsonResponse, HttpRequest, HttpResponseRedirect
from urllib.parse import urlencode, urlparse, urlunparse, parse_qs, quote
from ipware import get_client_ip from ipware import get_client_ip
from .auth_models import AuthToken, BruteForceAttempt from .auth_models import AuthToken, BruteForceAttempt
@@ -29,7 +30,9 @@ class ExternalAuthView(View):
if not request.user.is_authenticated: if not request.user.is_authenticated:
# Redirect to login page with next parameter # Redirect to login page with next parameter
current_path = request.get_full_path() current_path = request.get_full_path()
redirect_url = f"/accounts/login/?next={current_path}" # URL-encode the current path to preserve query parameters
encoded_path = quote(current_path, safe="")
redirect_url = f"/accounts/login/?next={encoded_path}"
return HttpResponseRedirect(redirect_url) return HttpResponseRedirect(redirect_url)
# Determine identifier for brute force tracking (only for authenticated users) # Determine identifier for brute force tracking (only for authenticated users)
@@ -90,6 +93,30 @@ class ExternalAuthView(View):
brute_force_attempt.is_blocked = False brute_force_attempt.is_blocked = False
brute_force_attempt.save() brute_force_attempt.save()
# Check if there's a 'next' parameter for redirect
next_url = request.GET.get("next")
if next_url:
# Parse the next URL and add the token as a parameter
parsed_url = urlparse(next_url)
query_params = parse_qs(parsed_url.query)
query_params["token"] = [token]
# Rebuild the URL with the token parameter
new_query = urlencode(query_params, doseq=True)
redirect_url = urlunparse(
(
parsed_url.scheme,
parsed_url.netloc,
parsed_url.path,
parsed_url.params,
new_query,
parsed_url.fragment,
)
)
return HttpResponseRedirect(redirect_url)
# If no next parameter, return JSON response as before
return JsonResponse( return JsonResponse(
{ {
"authenticated": True, "authenticated": True,