saas-market-analysis-dubai/apps/users/views.py

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)