You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

126 lines
4.5 KiB

import logging
from django.contrib.auth import get_user_model
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from rest_framework import status
from rest_framework.authtoken.models import Token
from rest_framework.generics import GenericAPIView
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from apps.account.serializers import ExchangeTokenSerializer
from utils import absolute_url
from utils.redis import OnlineClassTokenManager
logger = logging.getLogger(__name__)
UserModel = get_user_model()
class ExchangeTokenAPIView(GenericAPIView):
"""
تبدیل temporary token به اطلاعات کاربر برای ورود از اپ موبایل
"""
permission_classes = [AllowAny]
serializer_class = ExchangeTokenSerializer
@swagger_auto_schema(
operation_description="Exchange temporary token for user information and authentication token.",
request_body=ExchangeTokenSerializer,
responses={
status.HTTP_200_OK: openapi.Response(
description="Token exchanged successfully.",
examples={
"application/json": {
"success": True,
"message": "ورود موفق",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": 123,
"fullname": "علی احمدی",
"email": "user@example.com",
"avatar": "https://cdn.example.com/avatar.jpg"
}
}
}
),
status.HTTP_400_BAD_REQUEST: openapi.Response(
description="Invalid request.",
examples={
"application/json": {
"success": False,
"message": "توکن ارسال نشده است"
}
}
),
status.HTTP_404_NOT_FOUND: openapi.Response(
description="Token not found or expired.",
examples={
"application/json": {
"success": False,
"message": "توکن نامعتبر یا منقضی شده است"
}
}
),
}
)
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
temp_token = serializer.validated_data['temp_token']
# دریافت اطلاعات از Redis/Cache
manager = OnlineClassTokenManager()
try:
token_data = manager.get_payload(temp_token)
except Exception:
return Response({
'success': False,
'message': 'توکن نامعتبر یا منقضی شده است'
}, status=status.HTTP_404_NOT_FOUND)
user_id = token_data.get('user_id')
if not user_id:
return Response({
'success': False,
'message': 'توکن نامعتبر است'
}, status=status.HTTP_400_BAD_REQUEST)
# دریافت کاربر
try:
user = UserModel.objects.get(id=user_id)
except UserModel.DoesNotExist:
return Response({
'success': False,
'message': 'کاربر یافت نشد'
}, status=status.HTTP_404_NOT_FOUND)
# حذف توکن موقت (one-time use)
manager.delete_token(temp_token)
# دریافت یا تولید Token واقعی کاربر
auth_token, _ = Token.objects.get_or_create(user=user)
# دریافت avatar URL
avatar_url = None
if hasattr(user, 'avatar') and user.avatar:
try:
avatar_url = absolute_url(user.avatar.url)
except Exception:
avatar_url = None
# برگرداندن اطلاعات کاربر با token واقعی
return Response({
'success': True,
'message': 'ورود موفق',
'token': auth_token.key,
'user': {
'id': user.id,
'fullname': user.get_full_name() or user.username or '',
'email': user.email or '',
'avatar': avatar_url
}
}, status=status.HTTP_200_OK)