274 lines
8.2 KiB
Python
274 lines
8.2 KiB
Python
"""
|
|
Views for user authentication and management.
|
|
"""
|
|
from rest_framework import generics, status
|
|
from rest_framework.decorators import api_view, permission_classes
|
|
from rest_framework.permissions import IsAuthenticated, AllowAny
|
|
from rest_framework.response import Response
|
|
from rest_framework_simplejwt.tokens import RefreshToken
|
|
from django.contrib.auth import get_user_model
|
|
from django.db import transaction
|
|
from .models import User, UserProfile, APIKey
|
|
from .serializers import (
|
|
UserRegistrationSerializer, UserLoginSerializer, UserSerializer,
|
|
UserProfileSerializer, UserUpdateSerializer, PasswordChangeSerializer,
|
|
APIKeySerializer, APIKeyCreateSerializer, SubscriptionUpdateSerializer
|
|
)
|
|
|
|
User = get_user_model()
|
|
|
|
|
|
class UserRegistrationView(generics.CreateAPIView):
|
|
"""User registration endpoint."""
|
|
queryset = User.objects.all()
|
|
serializer_class = UserRegistrationSerializer
|
|
permission_classes = [AllowAny]
|
|
|
|
def create(self, request, *args, **kwargs):
|
|
serializer = self.get_serializer(data=request.data)
|
|
serializer.is_valid(raise_exception=True)
|
|
|
|
with transaction.atomic():
|
|
user = serializer.save()
|
|
# Create user profile
|
|
UserProfile.objects.create(user=user)
|
|
|
|
# Enable API access and generate API key for new users
|
|
user.is_api_enabled = True
|
|
user.api_key = user.generate_api_key()
|
|
user.save()
|
|
|
|
# Generate tokens
|
|
refresh = RefreshToken.for_user(user)
|
|
|
|
return Response({
|
|
'message': 'User created successfully',
|
|
'user': UserSerializer(user).data,
|
|
'api_key': user.api_key,
|
|
'tokens': {
|
|
'refresh': str(refresh),
|
|
'access': str(refresh.access_token),
|
|
}
|
|
}, status=status.HTTP_201_CREATED)
|
|
|
|
|
|
@api_view(['POST'])
|
|
@permission_classes([AllowAny])
|
|
def login_view(request):
|
|
"""User login endpoint."""
|
|
serializer = UserLoginSerializer(data=request.data)
|
|
serializer.is_valid(raise_exception=True)
|
|
|
|
user = serializer.validated_data['user']
|
|
refresh = RefreshToken.for_user(user)
|
|
|
|
return Response({
|
|
'message': 'Login successful',
|
|
'user': UserSerializer(user).data,
|
|
'tokens': {
|
|
'refresh': str(refresh),
|
|
'access': str(refresh.access_token),
|
|
}
|
|
})
|
|
|
|
|
|
@api_view(['POST'])
|
|
@permission_classes([AllowAny])
|
|
def refresh_token_view(request):
|
|
"""Refresh JWT token endpoint."""
|
|
try:
|
|
refresh_token = request.data.get('refresh')
|
|
if not refresh_token:
|
|
return Response({'error': 'Refresh token required'}, status=status.HTTP_400_BAD_REQUEST)
|
|
|
|
token = RefreshToken(refresh_token)
|
|
new_access_token = str(token.access_token)
|
|
|
|
return Response({
|
|
'access': new_access_token,
|
|
'refresh': str(refresh_token)
|
|
})
|
|
except Exception as e:
|
|
return Response({'error': 'Invalid refresh token'}, status=status.HTTP_401_UNAUTHORIZED)
|
|
|
|
|
|
@api_view(['POST'])
|
|
@permission_classes([IsAuthenticated])
|
|
def logout_view(request):
|
|
"""User logout endpoint."""
|
|
try:
|
|
refresh_token = request.data["refresh"]
|
|
token = RefreshToken(refresh_token)
|
|
token.blacklist()
|
|
return Response({'message': 'Logout successful'})
|
|
except Exception as e:
|
|
return Response({'error': 'Invalid token'}, status=status.HTTP_400_BAD_REQUEST)
|
|
|
|
|
|
class UserProfileView(generics.RetrieveUpdateAPIView):
|
|
"""User profile management."""
|
|
serializer_class = UserSerializer
|
|
permission_classes = [IsAuthenticated]
|
|
|
|
def get_object(self):
|
|
return self.request.user
|
|
|
|
|
|
class UserUpdateView(generics.UpdateAPIView):
|
|
"""Update user information."""
|
|
serializer_class = UserUpdateSerializer
|
|
permission_classes = [IsAuthenticated]
|
|
|
|
def get_object(self):
|
|
return self.request.user
|
|
|
|
|
|
@api_view(['POST'])
|
|
@permission_classes([IsAuthenticated])
|
|
def change_password_view(request):
|
|
"""Change user password."""
|
|
serializer = PasswordChangeSerializer(data=request.data, context={'request': request})
|
|
serializer.is_valid(raise_exception=True)
|
|
|
|
user = request.user
|
|
user.set_password(serializer.validated_data['new_password'])
|
|
user.save()
|
|
|
|
return Response({'message': 'Password changed successfully'})
|
|
|
|
|
|
class UserProfileDetailView(generics.RetrieveUpdateAPIView):
|
|
"""User profile detail management."""
|
|
serializer_class = UserProfileSerializer
|
|
permission_classes = [IsAuthenticated]
|
|
|
|
def get_object(self):
|
|
profile, created = UserProfile.objects.get_or_create(user=self.request.user)
|
|
return profile
|
|
|
|
|
|
class APIKeyListView(generics.ListCreateAPIView):
|
|
"""List and create API keys."""
|
|
permission_classes = [IsAuthenticated]
|
|
|
|
def get_serializer_class(self):
|
|
if self.request.method == 'POST':
|
|
return APIKeyCreateSerializer
|
|
return APIKeySerializer
|
|
|
|
def get_queryset(self):
|
|
return APIKey.objects.filter(user=self.request.user, is_active=True)
|
|
|
|
def perform_create(self, serializer):
|
|
serializer.save(user=self.request.user)
|
|
|
|
|
|
class APIKeyDetailView(generics.RetrieveUpdateDestroyAPIView):
|
|
"""API key detail management."""
|
|
serializer_class = APIKeySerializer
|
|
permission_classes = [IsAuthenticated]
|
|
|
|
def get_queryset(self):
|
|
return APIKey.objects.filter(user=self.request.user)
|
|
|
|
def perform_destroy(self, instance):
|
|
instance.is_active = False
|
|
instance.save()
|
|
|
|
|
|
@api_view(['POST'])
|
|
@permission_classes([IsAuthenticated])
|
|
def regenerate_api_key_view(request):
|
|
"""Regenerate user's main API key."""
|
|
user = request.user
|
|
|
|
if not user.is_api_enabled:
|
|
return Response(
|
|
{'error': 'API access is not enabled for this user'},
|
|
status=status.HTTP_400_BAD_REQUEST
|
|
)
|
|
|
|
user.api_key = user.generate_api_key()
|
|
user.save()
|
|
|
|
return Response({
|
|
'message': 'API key regenerated successfully',
|
|
'api_key': user.api_key
|
|
})
|
|
|
|
|
|
@api_view(['POST'])
|
|
@permission_classes([IsAuthenticated])
|
|
def toggle_api_access_view(request):
|
|
"""Toggle API access for user."""
|
|
user = request.user
|
|
|
|
if not user.api_key:
|
|
user.api_key = user.generate_api_key()
|
|
|
|
user.is_api_enabled = not user.is_api_enabled
|
|
user.save()
|
|
|
|
return Response({
|
|
'message': f'API access {"enabled" if user.is_api_enabled else "disabled"}',
|
|
'is_api_enabled': user.is_api_enabled,
|
|
'api_key': user.api_key if user.is_api_enabled else None
|
|
})
|
|
|
|
|
|
@api_view(['POST'])
|
|
@permission_classes([IsAuthenticated])
|
|
def update_subscription_view(request):
|
|
"""Update user subscription (admin only)."""
|
|
if not request.user.is_staff:
|
|
return Response(
|
|
{'error': 'Permission denied'},
|
|
status=status.HTTP_403_FORBIDDEN
|
|
)
|
|
|
|
serializer = SubscriptionUpdateSerializer(data=request.data, context={'request': request})
|
|
serializer.is_valid(raise_exception=True)
|
|
|
|
user_id = request.data.get('user_id')
|
|
if not user_id:
|
|
return Response(
|
|
{'error': 'user_id is required'},
|
|
status=status.HTTP_400_BAD_REQUEST
|
|
)
|
|
|
|
try:
|
|
user = User.objects.get(id=user_id)
|
|
except User.DoesNotExist:
|
|
return Response(
|
|
{'error': 'User not found'},
|
|
status=status.HTTP_404_NOT_FOUND
|
|
)
|
|
|
|
user.subscription_type = serializer.validated_data['subscription_type']
|
|
user.save()
|
|
|
|
return Response({
|
|
'message': 'Subscription updated successfully',
|
|
'user': UserSerializer(user).data
|
|
})
|
|
|
|
|
|
class UserListView(generics.ListAPIView):
|
|
"""List all users (admin only)."""
|
|
serializer_class = UserSerializer
|
|
permission_classes = [IsAuthenticated]
|
|
|
|
def get_queryset(self):
|
|
if not self.request.user.is_staff:
|
|
return User.objects.none()
|
|
return User.objects.all().order_by('-date_joined')
|
|
|
|
|
|
@api_view(['GET'])
|
|
@permission_classes([IsAuthenticated])
|
|
def get_current_user(request):
|
|
"""Get current authenticated user."""
|
|
serializer = UserSerializer(request.user)
|
|
return Response(serializer.data)
|
|
|