Przeglądaj źródła

Fixes #20915: Ensure preferred language is applied during SSO login (#21590)

Jeremy Stretch 21 godzin temu
rodzic
commit
8ea33df148
2 zmienionych plików z 31 dodań i 10 usunięć
  1. 18 9
      netbox/netbox/middleware.py
  2. 13 1
      netbox/users/signals.py

+ 18 - 9
netbox/netbox/middleware.py

@@ -40,15 +40,24 @@ class CoreMiddleware:
         with apply_request_processors(request):
             response = self.get_response(request)
 
-        # Check if language cookie should be renewed
-        if request.user.is_authenticated and settings.SESSION_SAVE_EVERY_REQUEST:
-            if language := request.user.config.get('locale.language'):
-                response.set_cookie(
-                    key=settings.LANGUAGE_COOKIE_NAME,
-                    value=language,
-                    max_age=request.session.get_expiry_age(),
-                    secure=settings.SESSION_COOKIE_SECURE,
-                )
+        # Set or renew the language cookie based on the user's preference. This handles two cases:
+        # 1. The user just logged in (via any auth backend): the user_logged_in signal stores the preferred language on
+        #    the request so we set the cookie here on the login response.
+        # 2. SESSION_SAVE_EVERY_REQUEST is enabled: renew the language cookie on every request to keep it in sync with
+        #    the session expiry.
+        if hasattr(request, '_language_cookie'):
+            language = request._language_cookie
+        elif request.user.is_authenticated and settings.SESSION_SAVE_EVERY_REQUEST:
+            language = request.user.config.get('locale.language')
+        else:
+            language = None
+        if language:
+            response.set_cookie(
+                key=settings.LANGUAGE_COOKIE_NAME,
+                value=language,
+                max_age=request.session.get_expiry_age(),
+                secure=settings.SESSION_COOKIE_SECURE,
+            )
 
         # Attach the unique request ID as an HTTP header.
         response['X-Request-ID'] = request.id

+ 13 - 1
netbox/users/signals.py

@@ -1,6 +1,6 @@
 import logging
 
-from django.contrib.auth.signals import user_login_failed
+from django.contrib.auth.signals import user_logged_in, user_login_failed
 from django.db.models.signals import post_save
 from django.dispatch import receiver
 
@@ -23,6 +23,18 @@ def log_user_login_failed(sender, credentials, request, **kwargs):
         logger.info(f"Failed login attempt for username: {username}")
 
 
+@receiver(user_logged_in)
+def set_language_on_login(sender, user, request, **kwargs):
+    """
+    Store the user's preferred language on the request so that middleware can set the language cookie. This ensures the
+    language preference is applied even when logging in via an external auth provider (e.g. social-app-django) that
+    does not go through NetBox's LoginView.
+    """
+    if hasattr(user, 'config'):
+        if language := user.config.get('locale.language'):
+            request._language_cookie = language
+
+
 @receiver(post_save, sender=User)
 def create_userconfig(instance, created, raw=False, **kwargs):
     """