Dynavera/apps/users/viewsets.py

150 lines
5.5 KiB
Python
Raw Normal View History

from rest_framework import viewsets, status
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
2025-11-19 12:55:15 +00:00
class UserViewSet(viewsets.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=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=status.HTTP_401_UNAUTHORIZED
)
login(request, user)
return Response({
'user': UserSerializer(user).data,
'message': 'Login successful',
'success': True
}, status=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=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=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=status.HTTP_400_BAD_REQUEST
)
# Normalize email
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=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=status.HTTP_400_BAD_REQUEST
)
if data.get('password') != data.get('confirm_password'):
return Response(
{'detail': 'Passwords do not match.', 'success': False},
status=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=status.HTTP_201_CREATED
)
except Exception as e:
return Response(
{'detail': str(e), 'success': False},
status=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=status.HTTP_400_BAD_REQUEST
)
if data.get('password') != data.get('confirm_password'):
return Response(
{'detail': 'Passwords do not match', 'success': False},
status=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=status.HTTP_401_UNAUTHORIZED
)
user.set_password(data.get('password'))
user.save()
return Response(
{'detail': 'Password changed successfully', 'success': True},
status=status.HTTP_200_OK
)