fix(demo): block external account actions
This commit is contained in:
@@ -212,10 +212,12 @@ class UserProfileSerializer(BaseModelSerializer):
|
|||||||
"profile_picture",
|
"profile_picture",
|
||||||
"birth_date",
|
"birth_date",
|
||||||
"is_verified",
|
"is_verified",
|
||||||
|
"is_demo",
|
||||||
|
"demo_expires_at",
|
||||||
"full_name",
|
"full_name",
|
||||||
"age",
|
"age",
|
||||||
)
|
)
|
||||||
read_only_fields = BaseModelSerializer.Meta.fields + ("mobile", "is_verified")
|
read_only_fields = BaseModelSerializer.Meta.fields + ("mobile", "is_verified", "is_demo", "demo_expires_at")
|
||||||
|
|
||||||
|
|
||||||
class UserSearchSerializer(serializers.ModelSerializer):
|
class UserSearchSerializer(serializers.ModelSerializer):
|
||||||
|
|||||||
@@ -293,6 +293,11 @@ class ChangePasswordView(APIView):
|
|||||||
|
|
||||||
@extend_schema(request=ChangePasswordSerializer)
|
@extend_schema(request=ChangePasswordSerializer)
|
||||||
def patch(self, request, *args, **kwargs):
|
def patch(self, request, *args, **kwargs):
|
||||||
|
if getattr(request.user, "is_demo", False):
|
||||||
|
return Response(
|
||||||
|
{"detail": "Demo accounts cannot change passwords."},
|
||||||
|
status=status.HTTP_403_FORBIDDEN,
|
||||||
|
)
|
||||||
serializer = ChangePasswordSerializer(data=request.data, context={"request": request})
|
serializer = ChangePasswordSerializer(data=request.data, context={"request": request})
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
|
|
||||||
@@ -327,6 +332,11 @@ class SetPasswordView(UpdateAPIView):
|
|||||||
|
|
||||||
@extend_schema(request=ChangePasswordSerializer, responses=None)
|
@extend_schema(request=ChangePasswordSerializer, responses=None)
|
||||||
def patch(self, request, *args, **kwargs):
|
def patch(self, request, *args, **kwargs):
|
||||||
|
if getattr(request.user, "is_demo", False):
|
||||||
|
return Response(
|
||||||
|
{"detail": "Demo accounts cannot change passwords."},
|
||||||
|
status=status.HTTP_403_FORBIDDEN,
|
||||||
|
)
|
||||||
return super().patch(request, *args, **kwargs)
|
return super().patch(request, *args, **kwargs)
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
@@ -347,6 +357,11 @@ class ProfilePictureView(APIView):
|
|||||||
operation_id="users_profile_picture_self_create",
|
operation_id="users_profile_picture_self_create",
|
||||||
)
|
)
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
|
if getattr(request.user, "is_demo", False):
|
||||||
|
return Response(
|
||||||
|
{"detail": "Demo accounts cannot upload profile pictures."},
|
||||||
|
status=status.HTTP_403_FORBIDDEN,
|
||||||
|
)
|
||||||
serializer = UserProfilePictureSerializer(
|
serializer = UserProfilePictureSerializer(
|
||||||
instance=request.user,
|
instance=request.user,
|
||||||
data=request.data,
|
data=request.data,
|
||||||
@@ -362,6 +377,11 @@ class ProfilePictureView(APIView):
|
|||||||
operation_id="users_profile_picture_self_delete",
|
operation_id="users_profile_picture_self_delete",
|
||||||
)
|
)
|
||||||
def delete(self, request):
|
def delete(self, request):
|
||||||
|
if getattr(request.user, "is_demo", False):
|
||||||
|
return Response(
|
||||||
|
{"detail": "Demo accounts cannot remove profile pictures."},
|
||||||
|
status=status.HTTP_403_FORBIDDEN,
|
||||||
|
)
|
||||||
request.user.profile_picture.delete(save=False)
|
request.user.profile_picture.delete(save=False)
|
||||||
request.user.profile_picture = None
|
request.user.profile_picture = None
|
||||||
request.user.save(update_fields=["profile_picture", "updated_at"])
|
request.user.save(update_fields=["profile_picture", "updated_at"])
|
||||||
@@ -401,6 +421,11 @@ class UserSearchAPIView(APIView):
|
|||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
|
if getattr(request.user, "is_demo", False):
|
||||||
|
return Response(
|
||||||
|
{"detail": "Demo accounts cannot search external users."},
|
||||||
|
status=status.HTTP_403_FORBIDDEN,
|
||||||
|
)
|
||||||
mobile = request.query_params.get('mobile')
|
mobile = request.query_params.get('mobile')
|
||||||
if not mobile:
|
if not mobile:
|
||||||
return Response(
|
return Response(
|
||||||
|
|||||||
@@ -81,7 +81,11 @@ def register_user_with_otp(mobile, code, password, first_name="", last_name=""):
|
|||||||
|
|
||||||
def generate_and_send_otp(mobile, mode):
|
def generate_and_send_otp(mobile, mode):
|
||||||
"""Business logic for generating OTP, checking existence rules, and sending SMS."""
|
"""Business logic for generating OTP, checking existence rules, and sending SMS."""
|
||||||
user_exists = User.objects.filter(mobile=mobile).exists()
|
user = User.objects.filter(mobile=mobile).only("is_demo").first()
|
||||||
|
user_exists = user is not None
|
||||||
|
|
||||||
|
if user and user.is_demo:
|
||||||
|
raise ValidationError({"mobile": "Demo accounts cannot use SMS verification."})
|
||||||
|
|
||||||
if mode == "register" and user_exists:
|
if mode == "register" and user_exists:
|
||||||
raise ValidationError({"mobile": "این شماره قبلاً ثبتنام شده است."})
|
raise ValidationError({"mobile": "این شماره قبلاً ثبتنام شده است."})
|
||||||
|
|||||||
@@ -94,6 +94,14 @@ class WorkspaceViewSet(ModelViewSet):
|
|||||||
def perform_create(self, serializer):
|
def perform_create(self, serializer):
|
||||||
serializer.save(owner=self.request.user)
|
serializer.save(owner=self.request.user)
|
||||||
|
|
||||||
|
def create(self, request, *args, **kwargs):
|
||||||
|
if getattr(request.user, "is_demo", False):
|
||||||
|
return Response(
|
||||||
|
{"detail": "Demo accounts cannot create additional workspaces."},
|
||||||
|
status=status.HTTP_403_FORBIDDEN,
|
||||||
|
)
|
||||||
|
return super().create(request, *args, **kwargs)
|
||||||
|
|
||||||
@action(detail=True, methods=["get"], url_path="my-rates")
|
@action(detail=True, methods=["get"], url_path="my-rates")
|
||||||
def my_rates(self, request, pk=None):
|
def my_rates(self, request, pk=None):
|
||||||
workspace = self.get_object()
|
workspace = self.get_object()
|
||||||
@@ -247,6 +255,11 @@ class WorkspaceMembershipViewSet(ModelViewSet):
|
|||||||
)
|
)
|
||||||
|
|
||||||
workspace = get_object_or_404(Workspace, id=workspace_id)
|
workspace = get_object_or_404(Workspace, id=workspace_id)
|
||||||
|
if getattr(request.user, "is_demo", False):
|
||||||
|
return Response(
|
||||||
|
{"detail": "Demo accounts cannot add workspace members."},
|
||||||
|
status=status.HTTP_403_FORBIDDEN,
|
||||||
|
)
|
||||||
|
|
||||||
permission = IsWorkspaceAdmin()
|
permission = IsWorkspaceAdmin()
|
||||||
if not permission.has_object_permission(request, self, workspace):
|
if not permission.has_object_permission(request, self, workspace):
|
||||||
|
|||||||
Reference in New Issue
Block a user