feat(agreement): implement user agreement update functionality with validation checks
All checks were successful
Build and Push Docker Images / Build and Push Docker Images (push) Successful in 3m4s

This commit is contained in:
2025-07-25 10:12:04 +05:00
parent fd603daaaf
commit f84f03fd5b
3 changed files with 67 additions and 0 deletions

View File

@@ -49,6 +49,15 @@ class UserUpdateSerializer(serializers.ModelSerializer):
) )
class UserAgreementSerializer(serializers.ModelSerializer):
"""serializer for the user agreement object"""
class Meta: # type: ignore
model = User
fields = ("agreement",)
extra_kwargs = {"agreement": {"required": True, "allow_null": False}}
class CustomUserSerializer(serializers.ModelSerializer): class CustomUserSerializer(serializers.ModelSerializer):
"""serializer for the user object""" """serializer for the user object"""

View File

@@ -23,6 +23,7 @@ from .views import (
UserVerifyAPIView, UserVerifyAPIView,
UserUpdateAPIView, UserUpdateAPIView,
UserRejectAPIView, UserRejectAPIView,
AgreementUpdateAPIView,
) )
@@ -45,6 +46,11 @@ urlpatterns = [
path("users/temp/filter/", filter_temporary_user, name="filter-temporary-users"), path("users/temp/filter/", filter_temporary_user, name="filter-temporary-users"),
# User verification flow # User verification flow
path("users/<int:pk>/verify/", UserVerifyAPIView.as_view(), name="user-verify"), path("users/<int:pk>/verify/", UserVerifyAPIView.as_view(), name="user-verify"),
path(
"users/<int:pk>/agreement/",
AgreementUpdateAPIView.as_view(),
name="user-agreement-update",
),
path("users/<int:pk>/reject/", UserRejectAPIView.as_view(), name="user-reject"), path("users/<int:pk>/reject/", UserRejectAPIView.as_view(), name="user-reject"),
path("healthcheck/", healthcheck, name="healthcheck"), path("healthcheck/", healthcheck, name="healthcheck"),
path("test/", test_email, name="testemail"), path("test/", test_email, name="testemail"),

View File

@@ -19,6 +19,7 @@ from api.serializers import (
OTPVerificationSerializer, OTPVerificationSerializer,
TemporaryUserSerializer, TemporaryUserSerializer,
UserUpdateSerializer, UserUpdateSerializer,
UserAgreementSerializer,
) )
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.utils import timezone from django.utils import timezone
@@ -378,6 +379,57 @@ class UserUpdateAPIView(StaffEditorPermissionMixin, generics.UpdateAPIView):
return super().update(request, *args, **kwargs) return super().update(request, *args, **kwargs)
class AgreementUpdateAPIView(StaffEditorPermissionMixin, generics.UpdateAPIView):
serializer_class = UserAgreementSerializer
queryset = User.objects.all()
lookup_field = "pk"
def update(self, request, *args, **kwargs):
user_id = kwargs.get("pk")
user = get_object_or_404(User, pk=user_id)
if user.is_superuser:
return Response(
{"message": "You cannot update a superuser."},
status=status.HTTP_403_FORBIDDEN,
)
if request.user != user and (
not request.user.is_authenticated
or not getattr(request.user, "is_admin", False)
):
return Response(
{"message": "You are not authorized to update this user."},
status=status.HTTP_403_FORBIDDEN,
)
serializer = self.get_serializer(
user,
data=request.data,
partial=True,
)
agreement = request.data.get("agreement")
if not agreement:
return Response(
{"message": "Agreement file is required."},
status=status.HTTP_400_BAD_REQUEST,
)
if agreement.size > 10 * 1024 * 1024: # 5 MB limit
return Response(
{"message": "File size exceeds 10 MB limit."},
status=status.HTTP_400_BAD_REQUEST,
)
if agreement.content_type not in [
"application/pdf",
]:
return Response(
{"message": "Invalid file type. Only PDF files are allowed."},
status=status.HTTP_400_BAD_REQUEST,
)
if agreement:
user.agreement = agreement
serializer.is_valid(raise_exception=True)
user.save()
return super().update(request, *args, **kwargs)
class KnoxTokenListApiView( class KnoxTokenListApiView(
StaffEditorPermissionMixin, StaffEditorPermissionMixin,
generics.ListAPIView, generics.ListAPIView,