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.
131 lines
4.6 KiB
131 lines
4.6 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 apps.account.utils import get_localized_msg
|
|
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:
|
|
msg = get_localized_msg('token_invalid_expired', request)
|
|
return Response({
|
|
'success': False,
|
|
'message': msg
|
|
}, status=status.HTTP_404_NOT_FOUND)
|
|
|
|
user_id = token_data.get('user_id')
|
|
if not user_id:
|
|
msg = get_localized_msg('token_invalid', request)
|
|
return Response({
|
|
'success': False,
|
|
'message': msg
|
|
}, status=status.HTTP_400_BAD_REQUEST)
|
|
|
|
# دریافت کاربر
|
|
try:
|
|
user = UserModel.objects.get(id=user_id)
|
|
except UserModel.DoesNotExist:
|
|
msg = get_localized_msg('user_not_found', request)
|
|
return Response({
|
|
'success': False,
|
|
'message': msg
|
|
}, 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 واقعی
|
|
msg = get_localized_msg('login_success', request)
|
|
return Response({
|
|
'success': True,
|
|
'message': msg,
|
|
'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)
|