We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN 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

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `InvenTree/InvenTree/middleware.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 
3 from django.conf import settings
4 from django.contrib.auth.middleware import PersistentRemoteUserMiddleware
5 from django.http import HttpResponse
6 from django.shortcuts import HttpResponseRedirect
7 from django.shortcuts import redirect
8 from django.urls import reverse_lazy, Resolver404
9 from django.urls import include, re_path
10 
11 import logging
12 
13 from rest_framework.authtoken.models import Token
14 from allauth_2fa.middleware import BaseRequire2FAMiddleware, AllauthTwoFactorMiddleware
15 
16 from InvenTree.urls import frontendpatterns
17 from common.models import InvenTreeSetting
18 
19 
20 logger = logging.getLogger("inventree")
21 
22 
23 class AuthRequiredMiddleware(object):
24     def __init__(self, get_response):
25         self.get_response = get_response
26 
27     def __call__(self, request):
28         # Code to be executed for each request before
29         # the view (and later middleware) are called.
30 
31         assert hasattr(request, 'user')
32 
33         # API requests are handled by the DRF library
34         if request.path_info.startswith('/api/'):
35             return self.get_response(request)
36 
37         if not request.user.is_authenticated:
38             """
39             Normally, a web-based session would use csrftoken based authentication.
40             However when running an external application (e.g. the InvenTree app or Python library),
41             we must validate the user token manually.
42             """
43 
44             authorized = False
45 
46             # Allow static files to be accessed without auth
47             # Important for e.g. login page
48             if request.path_info.startswith('/static/'):
49                 authorized = True
50 
51             # Unauthorized users can access the login page
52             elif request.path_info.startswith('/accounts/'):
53                 authorized = True
54 
55             elif 'Authorization' in request.headers.keys() or 'authorization' in request.headers.keys():
56                 auth = request.headers.get('Authorization', request.headers.get('authorization')).strip()
57 
58                 if auth.lower().startswith('token') and len(auth.split()) == 2:
59                     token_key = auth.split()[1]
60 
61                     # Does the provided token match a valid user?
62                     try:
63                         token = Token.objects.get(key=token_key)
64 
65                         # Provide the user information to the request
66                         request.user = token.user
67                         authorized = True
68 
69                     except Token.DoesNotExist:
70                         logger.warning(f"Access denied for unknown token {token_key}")
71 
72             # No authorization was found for the request
73             if not authorized:
74                 # A logout request will redirect the user to the login screen
75                 if request.path_info == reverse_lazy('account_logout'):
76                     return HttpResponseRedirect(reverse_lazy('account_login'))
77 
78                 path = request.path_info
79 
80                 # List of URL endpoints we *do not* want to redirect to
81                 urls = [
82                     reverse_lazy('account_login'),
83                     reverse_lazy('account_logout'),
84                     reverse_lazy('admin:login'),
85                     reverse_lazy('admin:logout'),
86                 ]
87 
88                 # Do not redirect requests to any of these paths
89                 paths_ignore = [
90                     '/api/',
91                     '/js/',
92                     '/media/',
93                     '/static/',
94                 ]
95 
96                 if path not in urls and not any([path.startswith(p) for p in paths_ignore]):
97                     # Save the 'next' parameter to pass through to the login view
98 
99                     return redirect('{}?next={}'.format(reverse_lazy('account_login'), request.path))
100 
101                 else:
102                     # Return a 401 (Unauthorized) response code for this request
103                     return HttpResponse('Unauthorized', status=401)
104 
105         response = self.get_response(request)
106 
107         return response
108 
109 
110 url_matcher = re_path('', include(frontendpatterns))
111 
112 
113 class Check2FAMiddleware(BaseRequire2FAMiddleware):
114     """check if user is required to have MFA enabled"""
115     def require_2fa(self, request):
116         # Superusers are require to have 2FA.
117         try:
118             if url_matcher.resolve(request.path[1:]):
119                 return InvenTreeSetting.get_setting('LOGIN_ENFORCE_MFA')
120         except Resolver404:
121             pass
122         return False
123 
124 
125 class CustomAllauthTwoFactorMiddleware(AllauthTwoFactorMiddleware):
126     """This function ensures only frontend code triggers the MFA auth cycle"""
127     def process_request(self, request):
128         try:
129             if not url_matcher.resolve(request.path[1:]):
130                 super().process_request(request)
131         except Resolver404:
132             pass
133 
134 
135 class InvenTreeRemoteUserMiddleware(PersistentRemoteUserMiddleware):
136     """
137     Middleware to check if HTTP-header based auth is enabled and to set it up
138     """
139     header = settings.REMOTE_LOGIN_HEADER
140 
141     def process_request(self, request):
142         if not settings.REMOTE_LOGIN:
143             return
144 
145         return super().process_request(request)
146
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

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 @@
 
             # 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

{"golden_diff": "diff --git a/InvenTree/InvenTree/middleware.py b/InvenTree/InvenTree/middleware.py\n--- a/InvenTree/InvenTree/middleware.py\n+++ b/InvenTree/InvenTree/middleware.py\n@@ -3,7 +3,6 @@\n from django.conf import settings\n from django.contrib.auth.middleware import PersistentRemoteUserMiddleware\n from django.http import HttpResponse\n-from django.shortcuts import HttpResponseRedirect\n from django.shortcuts import redirect\n from django.urls import reverse_lazy, Resolver404\n from django.urls import include, re_path\n@@ -71,10 +70,6 @@\n \n             # No authorization was found for the request\n             if not authorized:\n-                # A logout request will redirect the user to the login screen\n-                if request.path_info == reverse_lazy('account_logout'):\n-                    return HttpResponseRedirect(reverse_lazy('account_login'))\n-\n                 path = request.path_info\n \n                 # List of URL endpoints we *do not* want to redirect to\n", "issue": "Add unittests for auth stack\nAdd full coverage for https://github.com/inventree/InvenTree/pull/2976\r\nAnd the full auth stack in the middleware\nAdd unittests for auth stack\nAdd full coverage for https://github.com/inventree/InvenTree/pull/2976\r\nAnd the full auth stack in the middleware\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\nfrom django.conf import settings\nfrom django.contrib.auth.middleware import PersistentRemoteUserMiddleware\nfrom django.http import HttpResponse\nfrom django.shortcuts import HttpResponseRedirect\nfrom django.shortcuts import redirect\nfrom django.urls import reverse_lazy, Resolver404\nfrom django.urls import include, re_path\n\nimport logging\n\nfrom rest_framework.authtoken.models import Token\nfrom allauth_2fa.middleware import BaseRequire2FAMiddleware, AllauthTwoFactorMiddleware\n\nfrom InvenTree.urls import frontendpatterns\nfrom common.models import InvenTreeSetting\n\n\nlogger = logging.getLogger(\"inventree\")\n\n\nclass AuthRequiredMiddleware(object):\n    def __init__(self, get_response):\n        self.get_response = get_response\n\n    def __call__(self, request):\n        # Code to be executed for each request before\n        # the view (and later middleware) are called.\n\n        assert hasattr(request, 'user')\n\n        # API requests are handled by the DRF library\n        if request.path_info.startswith('/api/'):\n            return self.get_response(request)\n\n        if not request.user.is_authenticated:\n            \"\"\"\n            Normally, a web-based session would use csrftoken based authentication.\n            However when running an external application (e.g. the InvenTree app or Python library),\n            we must validate the user token manually.\n            \"\"\"\n\n            authorized = False\n\n            # Allow static files to be accessed without auth\n            # Important for e.g. login page\n            if request.path_info.startswith('/static/'):\n                authorized = True\n\n            # Unauthorized users can access the login page\n            elif request.path_info.startswith('/accounts/'):\n                authorized = True\n\n            elif 'Authorization' in request.headers.keys() or 'authorization' in request.headers.keys():\n                auth = request.headers.get('Authorization', request.headers.get('authorization')).strip()\n\n                if auth.lower().startswith('token') and len(auth.split()) == 2:\n                    token_key = auth.split()[1]\n\n                    # Does the provided token match a valid user?\n                    try:\n                        token = Token.objects.get(key=token_key)\n\n                        # Provide the user information to the request\n                        request.user = token.user\n                        authorized = True\n\n                    except Token.DoesNotExist:\n                        logger.warning(f\"Access denied for unknown token {token_key}\")\n\n            # No authorization was found for the request\n            if not authorized:\n                # A logout request will redirect the user to the login screen\n                if request.path_info == reverse_lazy('account_logout'):\n                    return HttpResponseRedirect(reverse_lazy('account_login'))\n\n                path = request.path_info\n\n                # List of URL endpoints we *do not* want to redirect to\n                urls = [\n                    reverse_lazy('account_login'),\n                    reverse_lazy('account_logout'),\n                    reverse_lazy('admin:login'),\n                    reverse_lazy('admin:logout'),\n                ]\n\n                # Do not redirect requests to any of these paths\n                paths_ignore = [\n                    '/api/',\n                    '/js/',\n                    '/media/',\n                    '/static/',\n                ]\n\n                if path not in urls and not any([path.startswith(p) for p in paths_ignore]):\n                    # Save the 'next' parameter to pass through to the login view\n\n                    return redirect('{}?next={}'.format(reverse_lazy('account_login'), request.path))\n\n                else:\n                    # Return a 401 (Unauthorized) response code for this request\n                    return HttpResponse('Unauthorized', status=401)\n\n        response = self.get_response(request)\n\n        return response\n\n\nurl_matcher = re_path('', include(frontendpatterns))\n\n\nclass Check2FAMiddleware(BaseRequire2FAMiddleware):\n    \"\"\"check if user is required to have MFA enabled\"\"\"\n    def require_2fa(self, request):\n        # Superusers are require to have 2FA.\n        try:\n            if url_matcher.resolve(request.path[1:]):\n                return InvenTreeSetting.get_setting('LOGIN_ENFORCE_MFA')\n        except Resolver404:\n            pass\n        return False\n\n\nclass CustomAllauthTwoFactorMiddleware(AllauthTwoFactorMiddleware):\n    \"\"\"This function ensures only frontend code triggers the MFA auth cycle\"\"\"\n    def process_request(self, request):\n        try:\n            if not url_matcher.resolve(request.path[1:]):\n                super().process_request(request)\n        except Resolver404:\n            pass\n\n\nclass InvenTreeRemoteUserMiddleware(PersistentRemoteUserMiddleware):\n    \"\"\"\n    Middleware to check if HTTP-header based auth is enabled and to set it up\n    \"\"\"\n    header = settings.REMOTE_LOGIN_HEADER\n\n    def process_request(self, request):\n        if not settings.REMOTE_LOGIN:\n            return\n\n        return super().process_request(request)\n", "path": "InvenTree/InvenTree/middleware.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\nfrom django.conf import settings\nfrom django.contrib.auth.middleware import PersistentRemoteUserMiddleware\nfrom django.http import HttpResponse\nfrom django.shortcuts import redirect\nfrom django.urls import reverse_lazy, Resolver404\nfrom django.urls import include, re_path\n\nimport logging\n\nfrom rest_framework.authtoken.models import Token\nfrom allauth_2fa.middleware import BaseRequire2FAMiddleware, AllauthTwoFactorMiddleware\n\nfrom InvenTree.urls import frontendpatterns\nfrom common.models import InvenTreeSetting\n\n\nlogger = logging.getLogger(\"inventree\")\n\n\nclass AuthRequiredMiddleware(object):\n    def __init__(self, get_response):\n        self.get_response = get_response\n\n    def __call__(self, request):\n        # Code to be executed for each request before\n        # the view (and later middleware) are called.\n\n        assert hasattr(request, 'user')\n\n        # API requests are handled by the DRF library\n        if request.path_info.startswith('/api/'):\n            return self.get_response(request)\n\n        if not request.user.is_authenticated:\n            \"\"\"\n            Normally, a web-based session would use csrftoken based authentication.\n            However when running an external application (e.g. the InvenTree app or Python library),\n            we must validate the user token manually.\n            \"\"\"\n\n            authorized = False\n\n            # Allow static files to be accessed without auth\n            # Important for e.g. login page\n            if request.path_info.startswith('/static/'):\n                authorized = True\n\n            # Unauthorized users can access the login page\n            elif request.path_info.startswith('/accounts/'):\n                authorized = True\n\n            elif 'Authorization' in request.headers.keys() or 'authorization' in request.headers.keys():\n                auth = request.headers.get('Authorization', request.headers.get('authorization')).strip()\n\n                if auth.lower().startswith('token') and len(auth.split()) == 2:\n                    token_key = auth.split()[1]\n\n                    # Does the provided token match a valid user?\n                    try:\n                        token = Token.objects.get(key=token_key)\n\n                        # Provide the user information to the request\n                        request.user = token.user\n                        authorized = True\n\n                    except Token.DoesNotExist:\n                        logger.warning(f\"Access denied for unknown token {token_key}\")\n\n            # No authorization was found for the request\n            if not authorized:\n                path = request.path_info\n\n                # List of URL endpoints we *do not* want to redirect to\n                urls = [\n                    reverse_lazy('account_login'),\n                    reverse_lazy('account_logout'),\n                    reverse_lazy('admin:login'),\n                    reverse_lazy('admin:logout'),\n                ]\n\n                # Do not redirect requests to any of these paths\n                paths_ignore = [\n                    '/api/',\n                    '/js/',\n                    '/media/',\n                    '/static/',\n                ]\n\n                if path not in urls and not any([path.startswith(p) for p in paths_ignore]):\n                    # Save the 'next' parameter to pass through to the login view\n\n                    return redirect('{}?next={}'.format(reverse_lazy('account_login'), request.path))\n\n                else:\n                    # Return a 401 (Unauthorized) response code for this request\n                    return HttpResponse('Unauthorized', status=401)\n\n        response = self.get_response(request)\n\n        return response\n\n\nurl_matcher = re_path('', include(frontendpatterns))\n\n\nclass Check2FAMiddleware(BaseRequire2FAMiddleware):\n    \"\"\"check if user is required to have MFA enabled\"\"\"\n    def require_2fa(self, request):\n        # Superusers are require to have 2FA.\n        try:\n            if url_matcher.resolve(request.path[1:]):\n                return InvenTreeSetting.get_setting('LOGIN_ENFORCE_MFA')\n        except Resolver404:\n            pass\n        return False\n\n\nclass CustomAllauthTwoFactorMiddleware(AllauthTwoFactorMiddleware):\n    \"\"\"This function ensures only frontend code triggers the MFA auth cycle\"\"\"\n    def process_request(self, request):\n        try:\n            if not url_matcher.resolve(request.path[1:]):\n                super().process_request(request)\n        except Resolver404:\n            pass\n\n\nclass InvenTreeRemoteUserMiddleware(PersistentRemoteUserMiddleware):\n    \"\"\"\n    Middleware to check if HTTP-header based auth is enabled and to set it up\n    \"\"\"\n    header = settings.REMOTE_LOGIN_HEADER\n\n    def process_request(self, request):\n        if not settings.REMOTE_LOGIN:\n            return\n\n        return super().process_request(request)\n", "path": "InvenTree/InvenTree/middleware.py"}]}