Repository: inventree/InvenTree

Issue:
Add unittests for auth stack
Add full coverage for https://github.com/inventree/InvenTree/pull/2976
And the full auth stack in the middleware
Add unittests for auth stack
Add full coverage for https://github.com/inventree/InvenTree/pull/2976
And the full auth stack in the middleware


Discussion:

Resolving patch:
diff --git a/InvenTree/InvenTree/middleware.py b/InvenTree/InvenTree/middleware.py
--- a/InvenTree/InvenTree/middleware.py
+++ b/InvenTree/InvenTree/middleware.py
@@ -3,7 +3,6 @@
 from django.conf import settings
 from django.contrib.auth.middleware import PersistentRemoteUserMiddleware
 from django.http import HttpResponse
-from django.shortcuts import HttpResponseRedirect
 from django.shortcuts import redirect
 from django.urls import reverse_lazy, Resolver404
 from django.urls import include, re_path
@@ -71,10 +70,6 @@ def __call__(self, request):
 
             # No authorization was found for the request
             if not authorized:
-                # A logout request will redirect the user to the login screen
-                if request.path_info == reverse_lazy('account_logout'):
-                    return HttpResponseRedirect(reverse_lazy('account_login'))
-
                 path = request.path_info
 
                 # List of URL endpoints we *do not* want to redirect to


Test patch:
diff --git a/InvenTree/InvenTree/test_middleware.py b/InvenTree/InvenTree/test_middleware.py
new file mode 100644
--- /dev/null
+++ b/InvenTree/InvenTree/test_middleware.py
@@ -0,0 +1,66 @@
+"""Tests for middleware functions"""
+
+from django.test import TestCase
+
+from django.contrib.auth import get_user_model
+from django.urls import reverse
+
+
+class MiddlewareTests(TestCase):
+    """Test for middleware functions"""
+
+    def check_path(self, url, code=200, **kwargs):
+        response = self.client.get(url, HTTP_ACCEPT='application/json', **kwargs)
+        self.assertEqual(response.status_code, code)
+        return response
+
+    def setUp(self):
+        super().setUp()
+
+        # Create a user
+        user = get_user_model()
+
+        self.user = user.objects.create_user(username='username', email='user@email.com', password='password')
+        self.client.login(username='username', password='password')
+
+    def test_AuthRequiredMiddleware(self):
+        """Test the auth middleware"""
+
+        # test that /api/ routes go through
+        self.check_path(reverse('api-inventree-info'))
+
+        # logout
+        self.client.logout()
+
+        # check that account things go through
+        self.check_path(reverse('account_login'))
+
+        # logout goes diretly to login
+        self.check_path(reverse('account_logout'))
+
+        # check that frontend code is redirected to login
+        response = self.check_path(reverse('stats'), 302)
+        self.assertEqual(response.url, '/accounts/login/?next=/stats/')
+
+        # check that a 401 is raised
+        self.check_path(reverse('settings.js'), 401)
+
+    def test_token_auth(self):
+        """Test auth with token auth"""
+        # get token
+        response = self.client.get(reverse('api-token'), format='json', data={})
+        token = response.data['token']
+
+        # logout
+        self.client.logout()
+        # this should raise a 401
+        self.check_path(reverse('settings.js'), 401)
+
+        # request with token
+        self.check_path(reverse('settings.js'), HTTP_Authorization=f'Token {token}')
+
+        # Request with broken token
+        self.check_path(reverse('settings.js'), 401, HTTP_Authorization='Token abcd123')
+
+        # should still fail without token
+        self.check_path(reverse('settings.js'), 401)