91 lines
4.7 KiB
Python
91 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)
|