File size: 6,924 Bytes
e657e99
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.permissions import AllowAny
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from api.utils.auth import ThirdPartyAuth, ThirdPartyUserManager
from django.contrib.auth.models import User
import logging

logger = logging.getLogger(__name__)


@method_decorator(csrf_exempt, name='dispatch')
class TokenValidateView(APIView):
    """
    Token验证接口
    用户可以通过此接口验证Token是否有效,并获取用户信息
    """
    permission_classes = [AllowAny]  # 允许任何人访问此接口
    
    def post(self, request):
        """
        验证Token
        
        支持的参数传递方式:
        1. JSON: {"token": "your_token"}
        2. Form data: token=your_token
        3. URL参数: ?token=your_token
        4. Header: Authorization: Token your_token
        """
        # 获取Token
        token = self.get_token_from_request(request)
        
        if not token:
            return Response({
                'valid': False,
                'error': 'Token参数缺失',
                'message': '请提供Token参数。支持的方式:1) JSON: {"token": "your_token"} 2) Form data: token=your_token 3) URL参数: ?token=your_token 4) Header: Authorization: Token your_token',
                'example': {
                    'curl_header': 'curl -H "Authorization: Token 0c47b3d5b1aa561a5032f50e95bf069afa9a9e55" http://your-domain/api/token/validate/',
                    'curl_param': 'curl -X POST http://your-domain/api/token/validate/?token=0c47b3d5b1aa561a5032f50e95bf069afa9a9e55',
                    'curl_json': 'curl -X POST -H "Content-Type: application/json" -d \'{"token":"0c47b3d5b1aa561a5032f50e95bf069afa9a9e55"}\' http://your-domain/api/token/validate/'
                }
            }, status=status.HTTP_400_BAD_REQUEST)
        
        # 验证Token
        validation_result = ThirdPartyAuth.validate_token(token)
        
        if not validation_result['valid']:
            return Response({
                'valid': False,
                'error': 'Token验证失败',
                'message': validation_result.get('message', 'Token无效或已过期'),
                'token_preview': f"{token[:8]}..." if len(token) > 8 else token
            }, status=status.HTTP_401_UNAUTHORIZED)
        
        # Token有效,获取用户信息
        user_name = validation_result.get('user_name')
        
        if not user_name:
            return Response({
                'valid': False,
                'error': '用户信息获取失败',
                'message': '第三方API返回的数据中没有用户名信息'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        
        # 检查本地是否已有用户
        local_user = ThirdPartyUserManager.get_user_by_third_party_username(user_name)
        local_user_exists = local_user is not None
        
        return Response({
            'valid': True,
            'message': 'Token验证成功',
            'user_info': {
                'third_party_username': user_name,
                'local_user_exists': local_user_exists,
                'local_username': local_user.username if local_user else None,
                'local_user_id': local_user.id if local_user else None
            },
            'token_info': {
                'token_preview': f"{token[:8]}..." if len(token) > 8 else token,
                'token_length': len(token)
            },
            'next_steps': {
                'message': '现在您可以使用此Token访问其他API接口',
                'note': '如果local_user_exists为false,系统将在您首次使用其他API时自动创建本地用户账户和数据目录'
            }
        }, status=status.HTTP_200_OK)
    
    def get(self, request):
        """
        GET方法也支持Token验证(通过URL参数)
        """
        return self.post(request)
    
    def get_token_from_request(self, request):
        """
        从请求中获取Token
        """
        # 1. 从JSON数据获取
        if hasattr(request, 'data') and 'token' in request.data:
            return request.data.get('token')
        
        # 2. 从Authorization header获取
        auth_header = request.META.get('HTTP_AUTHORIZATION', '')
        if auth_header.startswith('Token '):
            return auth_header[6:]
        if auth_header.startswith('Bearer '):
            return auth_header[7:]
        
        # 3. 从URL参数获取
        token = request.GET.get('token')
        if token:
            return token
        
        # 4. 从POST form data获取
        if hasattr(request, 'POST') and 'token' in request.POST:
            return request.POST.get('token')
        
        return None


@method_decorator(csrf_exempt, name='dispatch')
class UserInfoView(APIView):
    """
    获取当前用户信息的接口
    需要有效的Token
    """
    
    def get(self, request):
        """
        获取当前用户信息
        """
        # 通过认证系统已经验证了Token,用户信息在request.user中
        user = request.user
        
        if not user or not user.is_authenticated:
            return Response({
                'error': '用户未认证',
                'message': '请提供有效的Token'
            }, status=status.HTTP_401_UNAUTHORIZED)
        
        # 获取第三方用户映射信息
        try:
            from api.models import ThirdPartyUserMapping
            mapping = ThirdPartyUserMapping.objects.get(user=user)
            third_party_info = {
                'third_party_user_id': mapping.third_party_user_id,
                'third_party_username': mapping.third_party_username,
                'created_at': mapping.created_at,
                'updated_at': mapping.updated_at
            }
        except ThirdPartyUserMapping.DoesNotExist:
            third_party_info = None
        
        # 获取用户的项目信息
        projects_count = user.projects.count()
        
        return Response({
            'user_info': {
                'local_user_id': user.id,
                'local_username': user.username,
                'email': user.email,
                'first_name': user.first_name,
                'last_name': user.last_name,
                'date_joined': user.date_joined,
                'last_login': user.last_login
            },
            'third_party_info': third_party_info,
            'statistics': {
                'projects_count': projects_count
            },
            'data_directories': {
                'user_base_dir': f'/media/users/{user.id}/',
                'projects_dir': f'/media/users/{user.id}/projects/'
            }
        }, status=status.HTTP_200_OK)