7 changed files with 296 additions and 11 deletions
-
37apps/account/management/commands/test_guest_token.py
-
4apps/hadis/admin/transmitter.py
-
48config/debug_authentication.py
-
4config/settings/base.py
-
0templates/admin/includes/fieldset.html.backup
-
200utils/admin.py
-
14utils/permissions.py
@ -0,0 +1,37 @@ |
|||
from django.core.management.base import BaseCommand |
|||
from rest_framework.test import APIClient |
|||
from apps.account.models import User # Your user model |
|||
import json |
|||
|
|||
class Command(BaseCommand): |
|||
def handle(self, *args, **options): |
|||
client = APIClient() |
|||
|
|||
# Step 1: Create guest token |
|||
print("\n📝 Step 1: Creating guest token...") |
|||
response = client.post('/api/account/web/guest/', |
|||
data=json.dumps({"timezone": "UTC", "user_agent": "test"}), |
|||
content_type='application/json' |
|||
) |
|||
print(f"Status: {response.status_code}") |
|||
if response.status_code == 200: |
|||
print(f"Response: {response.json()}") |
|||
token = response.json()['token'] |
|||
else: |
|||
print(f"Error Response: {response.content.decode('utf-8')}") |
|||
print("❌ Failed to create token!") |
|||
return |
|||
print(f"✅ Token created: {token[:20]}...") |
|||
|
|||
# Step 2: Test authentication with token |
|||
print("\n🔐 Step 2: Testing token authentication...") |
|||
client.credentials(HTTP_AUTHORIZATION=f'Token {token}') |
|||
|
|||
response = client.get('/api/library/books/') |
|||
print(f"Status: {response.status_code}") |
|||
if response.status_code == 200: |
|||
print(f"Response: {response.json()}") |
|||
print("✅ Token authentication works!") |
|||
else: |
|||
print(f"Error Response: {response.content.decode('utf-8')}") |
|||
print("❌ Token authentication failed!") |
|||
@ -0,0 +1,48 @@ |
|||
from rest_framework.authentication import TokenAuthentication |
|||
from rest_framework.exceptions import AuthenticationFailed |
|||
import logging |
|||
|
|||
logger = logging.getLogger(__name__) |
|||
|
|||
class DebugTokenAuthentication(TokenAuthentication): |
|||
""" |
|||
Extended TokenAuthentication with detailed logging for debugging |
|||
""" |
|||
def authenticate(self, request): |
|||
auth_header = request.META.get('HTTP_AUTHORIZATION', '') |
|||
logger.info(f"🔍 AUTH DEBUG - Header: {auth_header}") |
|||
|
|||
# Check if header exists |
|||
if not auth_header: |
|||
logger.warning("🔴 AUTH DEBUG - No Authorization header found") |
|||
return None |
|||
|
|||
# Extract token |
|||
parts = auth_header.split() |
|||
if len(parts) != 2 or parts[0].lower() != 'token': |
|||
logger.warning(f"🔴 AUTH DEBUG - Invalid header format: {parts}") |
|||
return None |
|||
|
|||
token_key = parts[1] |
|||
logger.info(f"🔍 AUTH DEBUG - Token key extracted: {token_key[:10]}...") |
|||
|
|||
try: |
|||
# Try to get token from database |
|||
from rest_framework.authtoken.models import Token |
|||
token = Token.objects.select_related('user').get(key=token_key) |
|||
logger.info(f"✅ AUTH DEBUG - Token found in DB") |
|||
logger.info(f"✅ AUTH DEBUG - User: {token.user}") |
|||
logger.info(f"✅ AUTH DEBUG - User ID: {token.user.id}") |
|||
logger.info(f"✅ AUTH DEBUG - User is_active: {token.user.is_active}") |
|||
logger.info(f"✅ AUTH DEBUG - User is_authenticated: {token.user.is_authenticated}") |
|||
|
|||
if not token.user.is_active: |
|||
logger.error("🔴 AUTH DEBUG - User is not active") |
|||
raise AuthenticationFailed('User inactive or deleted.') |
|||
|
|||
logger.info("✅ AUTH DEBUG - Authentication SUCCESSFUL") |
|||
return (token.user, token) |
|||
|
|||
except Exception as e: |
|||
logger.error(f"🔴 AUTH DEBUG - Token lookup failed: {str(e)}") |
|||
raise AuthenticationFailed('Invalid token.') |
|||
@ -0,0 +1,14 @@ |
|||
from rest_framework.permissions import BasePermission |
|||
|
|||
class IsTokenAuthenticatedOrAnonymous(BasePermission): |
|||
""" |
|||
Allow access to token-authenticated users OR anonymous users. |
|||
Useful for guest token endpoints. |
|||
""" |
|||
def has_permission(self, request, view): |
|||
# Allow if user is authenticated (including token users) |
|||
if request.user and request.user.is_authenticated: |
|||
return True |
|||
|
|||
# Allow anonymous access |
|||
return True |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue