Skip to content

Commit f414696

Browse files
authored
fix username logging in uwsgi for requests with TokenAuthentication (#14322)
* fix username logging in uwsgi for requests with TokenAuthentication * added unit test * missed fixture versioning
1 parent 0770034 commit f414696

2 files changed

Lines changed: 72 additions & 5 deletions

File tree

dojo/middleware.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,17 +64,19 @@ def __call__(self, request):
6464
fullURL = f"{settings.LOGIN_URL}?next={quote(request.get_full_path())}"
6565
return HttpResponseRedirect(fullURL)
6666

67+
if request.user.is_authenticated:
68+
path = request.path_info.lstrip("/")
69+
if Dojo_User.force_password_reset(request.user) and path != "change_password":
70+
return HttpResponseRedirect(reverse("change_password"))
71+
72+
response = self.get_response(request)
6773
if request.user.is_authenticated:
6874
logger.debug("Authenticated user: %s", request.user)
6975
with suppress(ModuleNotFoundError): # to avoid unittests to fail
7076
uwsgi = __import__("uwsgi", globals(), locals(), ["set_logvar"], 0)
7177
# this populates dd_user log var, so can appear in the uwsgi logs
7278
uwsgi.set_logvar("dd_user", str(request.user))
73-
path = request.path_info.lstrip("/")
74-
if Dojo_User.force_password_reset(request.user) and path != "change_password":
75-
return HttpResponseRedirect(reverse("change_password"))
76-
77-
return self.get_response(request)
79+
return response
7880

7981

8082
class CustomSocialAuthExceptionMiddleware(SocialAuthExceptionMiddleware):
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
from types import SimpleNamespace
2+
from unittest.mock import Mock, patch
3+
4+
from django.contrib.auth.models import AnonymousUser
5+
from django.http import HttpResponse
6+
from django.test import RequestFactory
7+
from rest_framework.authentication import TokenAuthentication
8+
from rest_framework.authtoken.models import Token
9+
from rest_framework.permissions import IsAuthenticated
10+
from rest_framework.response import Response
11+
from rest_framework.views import APIView
12+
13+
from dojo.middleware import LoginRequiredMiddleware
14+
from dojo.models import User
15+
16+
from .dojo_test_case import DojoTestCase, versioned_fixtures
17+
18+
19+
class TokenAuthenticatedView(APIView):
20+
authentication_classes = (TokenAuthentication,)
21+
permission_classes = (IsAuthenticated,)
22+
23+
def get(self, request):
24+
return Response({"username": request.user.username})
25+
26+
27+
@versioned_fixtures
28+
class TestLoginRequiredMiddlewareDdUser(DojoTestCase):
29+
fixtures = ["dojo_testdata.json"]
30+
31+
def setUp(self):
32+
super().setUp()
33+
self.factory = RequestFactory()
34+
self.admin = User.objects.get(username="admin")
35+
36+
def test_sets_dd_user_for_session_authenticated_request(self):
37+
request = self.factory.get("/dashboard")
38+
request.user = self.admin
39+
40+
middleware = LoginRequiredMiddleware(lambda _request: HttpResponse("OK"))
41+
fake_uwsgi = SimpleNamespace(set_logvar=Mock())
42+
43+
with patch.dict("sys.modules", {"uwsgi": fake_uwsgi}):
44+
response = middleware(request)
45+
46+
self.assertEqual(200, response.status_code)
47+
fake_uwsgi.set_logvar.assert_called_once_with("dd_user", str(self.admin))
48+
49+
def test_sets_dd_user_for_drf_token_authenticated_request(self):
50+
token, _ = Token.objects.get_or_create(user=self.admin)
51+
52+
request = self.factory.get(
53+
"/api/v2/mock-endpoint/",
54+
HTTP_AUTHORIZATION=f"Token {token.key}",
55+
)
56+
request.user = AnonymousUser()
57+
58+
middleware = LoginRequiredMiddleware(TokenAuthenticatedView.as_view())
59+
fake_uwsgi = SimpleNamespace(set_logvar=Mock())
60+
61+
with patch.dict("sys.modules", {"uwsgi": fake_uwsgi}):
62+
response = middleware(request)
63+
64+
self.assertEqual(200, response.status_code)
65+
fake_uwsgi.set_logvar.assert_called_once_with("dd_user", str(self.admin))

0 commit comments

Comments
 (0)