127 lines
4.0 KiB
Python
Raw Permalink Normal View History

2024-07-22 21:34:03 +02:00
"""all user api views"""
2025-02-12 17:31:59 +07:00
from common.serializers import ErrorResponseSerializer
2024-07-22 22:37:49 +02:00
from common.views import ApiBaseView
2025-01-01 15:26:23 +07:00
from django.contrib.auth import authenticate, login, logout
2024-08-10 17:18:00 +02:00
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
2025-02-12 17:31:59 +07:00
from drf_spectacular.utils import OpenApiResponse, extend_schema
2024-08-10 18:19:58 +02:00
from rest_framework.permissions import AllowAny
2024-07-22 21:34:03 +02:00
from rest_framework.response import Response
2024-08-10 18:19:58 +02:00
from rest_framework.views import APIView
2024-07-22 21:34:03 +02:00
from user.models import Account
2025-02-12 17:31:59 +07:00
from user.serializers import (
AccountSerializer,
LoginSerializer,
UserMeConfigSerializer,
)
2024-07-22 21:34:03 +02:00
from user.src.user_config import UserConfig
2025-02-12 17:31:59 +07:00
class UserAccountView(ApiBaseView):
"""resolves to /api/user/account/
GET: return current user account
2024-07-22 21:34:03 +02:00
"""
2025-02-12 17:31:59 +07:00
@extend_schema(
responses=AccountSerializer(),
)
2024-07-22 21:34:03 +02:00
def get(self, request):
2025-02-12 17:31:59 +07:00
"""get user account"""
2024-07-22 21:34:03 +02:00
user_id = request.user.id
account = Account.objects.get(id=user_id)
2025-02-12 17:31:59 +07:00
account_serializer = AccountSerializer(account)
return Response(account_serializer.data)
2024-07-22 21:34:03 +02:00
2025-02-12 17:31:59 +07:00
class UserConfigView(ApiBaseView):
"""resolves to /api/user/me/
GET: return current user config
POST: update user config
"""
2024-07-22 21:34:03 +02:00
2025-02-12 17:31:59 +07:00
@extend_schema(responses=UserMeConfigSerializer())
def get(self, request):
"""get user config"""
config = UserConfig(request.user.id).get_config()
serializer = UserMeConfigSerializer(config)
return Response(serializer.data)
@extend_schema(
request=UserMeConfigSerializer(required=False),
responses={
200: UserMeConfigSerializer(),
400: OpenApiResponse(
ErrorResponseSerializer(), description="Bad request"
),
},
)
2024-07-22 21:34:03 +02:00
def post(self, request):
2025-02-12 17:31:59 +07:00
"""update config, allows partial update"""
2024-07-22 21:34:03 +02:00
2025-02-12 17:31:59 +07:00
data_serializer = UserMeConfigSerializer(
2025-02-14 16:31:12 +07:00
data=request.data, partial=True
2025-02-12 17:31:59 +07:00
)
data_serializer.is_valid(raise_exception=True)
validated_data = data_serializer.validated_data
UserConfig(request.user.id).update_config(to_update=validated_data)
config = UserConfig(request.user.id).get_config()
serializer = UserMeConfigSerializer(config)
2024-08-10 18:55:50 +02:00
2025-02-12 17:31:59 +07:00
return Response(serializer.data)
2024-07-22 21:34:03 +02:00
2024-08-10 18:19:58 +02:00
@method_decorator(csrf_exempt, name="dispatch")
class LoginApiView(APIView):
2024-08-02 15:34:08 +02:00
"""resolves to /api/user/login/
2024-07-22 21:34:03 +02:00
POST: return token and username after successful login
"""
2024-08-10 18:19:58 +02:00
permission_classes = [AllowAny]
2025-02-12 17:31:59 +07:00
SEC_IN_DAY = 60 * 60 * 24
2024-08-10 18:19:58 +02:00
2025-02-12 17:31:59 +07:00
@extend_schema(
request=LoginSerializer(),
responses={204: OpenApiResponse(description="login successful")},
)
2024-07-22 21:34:03 +02:00
def post(self, request, *args, **kwargs):
2025-02-12 17:31:59 +07:00
"""login with username and password"""
2024-07-22 21:34:03 +02:00
# pylint: disable=no-member
2025-02-12 17:31:59 +07:00
data_serializer = LoginSerializer(data=request.data)
data_serializer.is_valid(raise_exception=True)
validated_data = data_serializer.validated_data
2024-08-10 18:19:58 +02:00
2025-02-12 17:31:59 +07:00
username = validated_data["username"]
password = validated_data["password"]
remember_me = validated_data.get("remember_me")
2024-08-10 18:19:58 +02:00
user = authenticate(request, username=username, password=password)
2025-02-12 17:31:59 +07:00
if user is None:
error = ErrorResponseSerializer({"error": "Invalid credentials"})
return Response(error.data, status=400)
if remember_me == "on":
request.session.set_expiry(self.SEC_IN_DAY * 365)
else:
request.session.set_expiry(self.SEC_IN_DAY * 2)
2024-08-10 18:19:58 +02:00
2025-02-12 17:31:59 +07:00
print(f"expire session in {request.session.get_expiry_age()} secs")
2024-08-10 18:19:58 +02:00
2025-02-12 17:31:59 +07:00
login(request, user) # Creates a session for the user
return Response(status=204)
2025-01-01 15:26:23 +07:00
class LogoutApiView(ApiBaseView):
"""resolves to /api/user/logout/
POST: handle logout
"""
2025-02-12 17:31:59 +07:00
@extend_schema(
responses={204: OpenApiResponse(description="logout successful")}
)
2025-01-01 15:26:23 +07:00
def post(self, request, *args, **kwargs):
2025-02-12 17:31:59 +07:00
"""logout user from session"""
2025-01-01 15:26:23 +07:00
logout(request)
2025-02-12 17:31:59 +07:00
return Response(status=204)