Dynavera/apps/users/viewsets.py
2026-01-17 14:39:02 +00:00

90 lines
4.7 KiB
Python

from rest_framework.status import HTTP_200_OK, HTTP_201_CREATED, HTTP_400_BAD_REQUEST, HTTP_401_UNAUTHORIZED
from rest_framework.viewsets import ReadOnlyModelViewSet
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticatedOrReadOnly, AllowAny, IsAuthenticated
from django.contrib.auth import authenticate, login, logout
from apps.users.models import User
from apps.users.serializers import UserSerializer
class UserViewSet(ReadOnlyModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = [IsAuthenticatedOrReadOnly]
lookup_field = 'uuid'
@action(detail=False, methods=['post'], permission_classes=[AllowAny])
def login(self, request):
email_address = request.data.get('email_address')
password = request.data.get('password')
if not email_address or not password:
return Response({'error': 'Email and password are required'}, status=HTTP_400_BAD_REQUEST)
email_address = User.objects.normalize_email(email_address)
user = authenticate(request, username=email_address, password=password)
if user is None:
return Response({'error': 'Invalid credentials'}, status=HTTP_401_UNAUTHORIZED)
login(request, user)
return Response({'user': UserSerializer(user).data, 'message': 'Login successful', 'success': True}, status=HTTP_200_OK)
@action(detail=False, methods=['post'], permission_classes=[IsAuthenticated])
def logout(self, request):
logout(request)
return Response({'message': 'Logout successful', 'success': True}, status=HTTP_200_OK)
@action(detail=False, methods=['get'], permission_classes=[IsAuthenticated])
def me(self, request):
user_data = UserSerializer(request.user).data
user_data['success'] = True
return Response(user_data)
@action(detail=False, methods=['get'], permission_classes=[AllowAny])
def session(self, request):
return Response({'isAuthenticated': request.user.is_authenticated, 'isStaff': request.user.is_staff if request.user.is_authenticated else False})
@action(detail=False, methods=['post'], permission_classes=[AllowAny])
def signup(self, request):
try:
data = request.data
except:
return Response({'detail': 'Invalid data provided.', 'success': False}, status=HTTP_400_BAD_REQUEST)
email_address = data.get('email_address')
if not email_address:
return Response({'detail': 'Email address is required.', 'success': False}, status=HTTP_400_BAD_REQUEST)
email_address = User.objects.normalize_email(email_address)
if User.objects.filter(email_address=email_address).exists():
return Response({'detail': 'Email address already exists.', 'success': False}, status=HTTP_400_BAD_REQUEST)
if not data.get('first_name') or not data.get('last_name'):
return Response({'detail': 'First and last name(s) must be provided.', 'success': False}, status=HTTP_400_BAD_REQUEST)
if data.get('password') != data.get('confirm_password'):
return Response({'detail': 'Passwords do not match.', 'success': False}, status=HTTP_400_BAD_REQUEST)
try:
user = User.objects.create_user(
email_address=email_address,
password=data.get('password'),
first_name=data.get('first_name'),
last_name=data.get('last_name'),
date_of_birth=data.get('date_of_birth')
)
return Response({'detail': 'User account created successfully.', 'success': True}, status=HTTP_201_CREATED)
except Exception as e:
return Response({'detail': str(e), 'success': False}, status=HTTP_400_BAD_REQUEST)
@action(detail=False, methods=['post'], permission_classes=[IsAuthenticated])
def change_password(self, request):
data = request.data
required_fields = ['old_password', 'password', 'confirm_password']
for field in required_fields:
if not data.get(field):
return Response({'detail': f'"{field}" not provided', 'success': False}, status=HTTP_400_BAD_REQUEST)
if data.get('password') != data.get('confirm_password'):
return Response({'detail': 'Passwords do not match', 'success': False}, status=HTTP_400_BAD_REQUEST)
user = request.user
if not user.check_password(data.get('old_password')):
return Response({'detail': 'Old password is incorrect', 'success': False}, status=HTTP_401_UNAUTHORIZED)
user.set_password(data.get('password'))
user.save()
return Response({'detail': 'Password changed successfully', 'success': True}, status=HTTP_200_OK)