Skip to content

Commit 00ef439

Browse files
heysamtexasclaude
andcommitted
fix: resolve all linting errors in 2FA middleware
- Replace typing.Any with proper AbstractUser type annotation (ANN401) - Use descriptive variable name for exception handling (BLE001) - Reduce return statements in sync/async methods from 7 to 3 (PLR0911) - Extract helper methods _should_enforce_2fa() and _should_enforce_2fa_async() - Add single targeted noqa for legitimate security catch-all exception handler The broad exception catch in URL resolution is intentionally kept with noqa comment as it provides secure fallback behavior for any unexpected errors during Django's URL resolution process while properly logging details. All 58 tests pass. No functional changes to middleware behavior. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent c7654e8 commit 00ef439

File tree

1 file changed

+43
-32
lines changed

1 file changed

+43
-32
lines changed

src/myapp/middleware.py

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@
88
"""
99

1010
import logging
11-
from typing import Any
11+
from typing import TYPE_CHECKING
1212

1313
from allauth.mfa.adapter import get_adapter as get_mfa_adapter
14+
15+
if TYPE_CHECKING:
16+
from django.contrib.auth.models import AbstractUser
1417
from asgiref.sync import sync_to_async
1518
from django.conf import settings
1619
from django.contrib import messages
@@ -73,7 +76,7 @@ def _is_static_request(self, request: HttpRequest) -> bool:
7376

7477
return request.path.startswith((static_url, media_url))
7578

76-
def _user_has_2fa(self, user: Any) -> bool:
79+
def _user_has_2fa(self, user: "AbstractUser") -> bool:
7780
"""Check if user has 2FA enabled."""
7881
mfa_adapter = get_mfa_adapter()
7982
return mfa_adapter.is_mfa_enabled(user)
@@ -90,9 +93,9 @@ def _is_exempt_url(self, request: HttpRequest) -> bool:
9093
# Can't resolve = probably 404 = let it through
9194
security_logger.debug("2FA: path %s doesn't resolve, allowing", request.path)
9295
return True
93-
except Exception as e:
96+
except Exception as resolution_error: # noqa: BLE001
9497
# Unexpected error during resolution - log and don't exempt
95-
security_logger.warning("2FA: error resolving path %s: %s", request.path, str(e))
98+
security_logger.warning("2FA: error resolving path %s: %s", request.path, str(resolution_error))
9699
return False
97100

98101
# Check by URL name
@@ -109,28 +112,55 @@ def _is_exempt_url(self, request: HttpRequest) -> bool:
109112

110113
return False
111114

112-
# Sync version
113-
def __call__(self, request: HttpRequest) -> HttpResponse:
114-
"""Process the request and enforce 2FA if required."""
115+
def _should_enforce_2fa(self, request: HttpRequest) -> bool:
116+
"""Check if 2FA should be enforced for this request."""
115117
# Skip static/media files
116118
if self._is_static_request(request):
117-
return self.get_response(request)
119+
return False
118120

119121
# Skip if user not authenticated
120122
if not request.user.is_authenticated:
121-
return self.get_response(request)
123+
return False
122124

123125
# Skip exempt URLs
124126
if self._is_exempt_url(request):
125-
return self.get_response(request)
127+
return False
126128

127129
# Check if 2FA is required by site configuration
128130
site_config = SiteConfiguration.objects.get()
129131
if not site_config.required_2fa:
130-
return self.get_response(request)
132+
return False
131133

132134
# Check if user has 2FA
133-
if self._user_has_2fa(request.user):
135+
return not self._user_has_2fa(request.user)
136+
137+
async def _should_enforce_2fa_async(self, request: HttpRequest) -> bool:
138+
"""Async version: Check if 2FA should be enforced for this request."""
139+
# Skip static/media files
140+
if self._is_static_request(request):
141+
return False
142+
143+
# Skip if user not authenticated
144+
if not request.user.is_authenticated:
145+
return False
146+
147+
# Skip exempt URLs
148+
if self._is_exempt_url(request):
149+
return False
150+
151+
# Check if 2FA is required by site configuration
152+
site_config = await sync_to_async(SiteConfiguration.objects.get)()
153+
if not site_config.required_2fa:
154+
return False
155+
156+
# Check if user has 2FA
157+
has_2fa = await sync_to_async(self._user_has_2fa)(request.user)
158+
return not has_2fa
159+
160+
# Sync version
161+
def __call__(self, request: HttpRequest) -> HttpResponse:
162+
"""Process the request and enforce 2FA if required."""
163+
if not self._should_enforce_2fa(request):
134164
return self.get_response(request)
135165

136166
# User needs 2FA - log and redirect
@@ -150,26 +180,7 @@ def __call__(self, request: HttpRequest) -> HttpResponse:
150180
# Async version
151181
async def __acall__(self, request: HttpRequest) -> HttpResponse:
152182
"""Process the request and enforce 2FA if required."""
153-
# Skip static/media files
154-
if self._is_static_request(request):
155-
return await self.get_response(request)
156-
157-
# Skip if user not authenticated
158-
if not request.user.is_authenticated:
159-
return await self.get_response(request)
160-
161-
# Skip exempt URLs
162-
if self._is_exempt_url(request):
163-
return await self.get_response(request)
164-
165-
# Check if 2FA is required by site configuration
166-
site_config = await sync_to_async(SiteConfiguration.objects.get)()
167-
if not site_config.required_2fa:
168-
return await self.get_response(request)
169-
170-
# Check if user has 2FA
171-
has_2fa = await sync_to_async(self._user_has_2fa)(request.user)
172-
if has_2fa:
183+
if not await self._should_enforce_2fa_async(request):
173184
return await self.get_response(request)
174185

175186
# User needs 2FA - log and redirect

0 commit comments

Comments
 (0)