refactor-upto-phase 6
This commit is contained in:
@@ -4,6 +4,7 @@ Extracts account from JWT token and injects into request context
|
||||
"""
|
||||
from django.utils.deprecation import MiddlewareMixin
|
||||
from django.http import JsonResponse
|
||||
from django.contrib.auth import logout
|
||||
from rest_framework import status
|
||||
|
||||
try:
|
||||
@@ -41,14 +42,19 @@ class AccountContextMiddleware(MiddlewareMixin):
|
||||
request.user = user
|
||||
# Get account from refreshed user
|
||||
user_account = getattr(user, 'account', None)
|
||||
if user_account:
|
||||
request.account = user_account
|
||||
return None
|
||||
validation_error = self._validate_account_and_plan(request, user)
|
||||
if validation_error:
|
||||
return validation_error
|
||||
request.account = getattr(user, 'account', None)
|
||||
return None
|
||||
except (AttributeError, UserModel.DoesNotExist, Exception):
|
||||
# If refresh fails, fallback to cached account
|
||||
try:
|
||||
user_account = getattr(request.user, 'account', None)
|
||||
if user_account:
|
||||
validation_error = self._validate_account_and_plan(request, request.user)
|
||||
if validation_error:
|
||||
return validation_error
|
||||
request.account = user_account
|
||||
return None
|
||||
except (AttributeError, Exception):
|
||||
@@ -96,6 +102,9 @@ class AccountContextMiddleware(MiddlewareMixin):
|
||||
# Get user from DB (but don't set request.user - let DRF authentication handle that)
|
||||
# Only set request.account for account context
|
||||
user = User.objects.select_related('account', 'account__plan').get(id=user_id)
|
||||
validation_error = self._validate_account_and_plan(request, user)
|
||||
if validation_error:
|
||||
return validation_error
|
||||
if account_id:
|
||||
# Verify account still exists
|
||||
try:
|
||||
@@ -119,4 +128,47 @@ class AccountContextMiddleware(MiddlewareMixin):
|
||||
request.account = None
|
||||
|
||||
return None
|
||||
|
||||
def _validate_account_and_plan(self, request, user):
|
||||
"""
|
||||
Ensure the authenticated user has an account and an active plan.
|
||||
If not, logout the user (for session auth) and block the request.
|
||||
"""
|
||||
try:
|
||||
account = getattr(user, 'account', None)
|
||||
except Exception:
|
||||
account = None
|
||||
|
||||
if not account:
|
||||
return self._deny_request(
|
||||
request,
|
||||
error='Account not configured for this user. Please contact support.',
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
)
|
||||
|
||||
plan = getattr(account, 'plan', None)
|
||||
if plan is None or getattr(plan, 'is_active', False) is False:
|
||||
return self._deny_request(
|
||||
request,
|
||||
error='Active subscription required. Visit igny8.com/pricing to subscribe.',
|
||||
status_code=status.HTTP_402_PAYMENT_REQUIRED,
|
||||
)
|
||||
|
||||
return None
|
||||
|
||||
def _deny_request(self, request, error, status_code):
|
||||
"""Logout session users (if any) and return a consistent JSON error."""
|
||||
try:
|
||||
if hasattr(request, 'user') and request.user and request.user.is_authenticated:
|
||||
logout(request)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return JsonResponse(
|
||||
{
|
||||
'success': False,
|
||||
'error': error,
|
||||
},
|
||||
status=status_code,
|
||||
)
|
||||
|
||||
|
||||
@@ -926,13 +926,28 @@ class AuthViewSet(viewsets.GenericViewSet):
|
||||
)
|
||||
|
||||
if user.check_password(password):
|
||||
# Ensure user has an account
|
||||
account = getattr(user, 'account', None)
|
||||
if account is None:
|
||||
return error_response(
|
||||
error='Account not configured for this user. Please contact support.',
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
request=request,
|
||||
)
|
||||
|
||||
# Ensure account has an active plan
|
||||
plan = getattr(account, 'plan', None)
|
||||
if plan is None or getattr(plan, 'is_active', False) is False:
|
||||
return error_response(
|
||||
error='Active subscription required. Visit igny8.com/pricing to subscribe.',
|
||||
status_code=status.HTTP_402_PAYMENT_REQUIRED,
|
||||
request=request,
|
||||
)
|
||||
|
||||
# Log the user in (create session for session authentication)
|
||||
from django.contrib.auth import login
|
||||
login(request, user)
|
||||
|
||||
# Get account from user
|
||||
account = getattr(user, 'account', None)
|
||||
|
||||
# Generate JWT tokens
|
||||
access_token = generate_access_token(user, account)
|
||||
refresh_token = generate_refresh_token(user, account)
|
||||
|
||||
Reference in New Issue
Block a user