From bcd9e6f67986c23694abd82a2572317ef91e64af Mon Sep 17 00:00:00 2001 From: Lvyshnevska Date: Thu, 12 Oct 2023 16:59:49 +0200 Subject: [PATCH 1/8] check password improved --- profiles/serializers.py | 9 +++++++++ profiles/views.py | 18 +++++------------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/profiles/serializers.py b/profiles/serializers.py index bee537e61..2346920a4 100644 --- a/profiles/serializers.py +++ b/profiles/serializers.py @@ -204,6 +204,15 @@ class Meta: ) read_only_fields = ("person",) + def validate_for_delete(self, data): + password = data.get("password") + if not password: + raise serializers.ValidationError("Password is required") + request_user = self.context["request"].user + if not request_user.check_password(password): + raise serializers.ValidationError("Invalid password") + return data + class ProfileSensitiveDataROSerializer(serializers.ModelSerializer): email = serializers.ReadOnlyField(source="person.email") diff --git a/profiles/views.py b/profiles/views.py index 9500bb21e..2ed3cf8d2 100644 --- a/profiles/views.py +++ b/profiles/views.py @@ -1,6 +1,5 @@ import django_filters from django.shortcuts import get_object_or_404 -from django.contrib.auth.hashers import check_password from rest_framework import status from rest_framework.generics import ( CreateAPIView, @@ -175,19 +174,12 @@ def get_serializer_class(self): else: return ProfileOwnerDetailEditSerializer - def destroy(self, request, *args, **kwargs): - instance = self.get_object() - user = self.request.user - password = self.request.data.get("password") - if not password or not check_password(password, user.password): - return Response(status=status.HTTP_400_BAD_REQUEST) - else: - self.perform_destroy(instance) - return Response(status=status.HTTP_204_NO_CONTENT) - def perform_destroy(self, instance): - instance.is_deleted = True - instance.save() + request_data = {"password": self.request.data.get("password")} + serializer = self.get_serializer(instance) + if serializer.validate_for_delete(request_data): + instance.is_deleted = True + instance.save() class ViewedCompanyList(ListCreateAPIView): From 79bf2eb6da8d296366b4867ac68384baa60f6915 Mon Sep 17 00:00:00 2001 From: Lvyshnevska Date: Thu, 12 Oct 2023 17:01:02 +0200 Subject: [PATCH 2/8] redundant imports removed --- authentication/serializers.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/authentication/serializers.py b/authentication/serializers.py index 728ca1151..c656c5ad2 100644 --- a/authentication/serializers.py +++ b/authentication/serializers.py @@ -1,12 +1,10 @@ from collections import defaultdict -from django.conf import settings -from django.contrib.auth import authenticate, get_user_model +from django.contrib.auth import get_user_model from django.core.exceptions import ValidationError from djoser.serializers import ( UserCreatePasswordRetypeSerializer, UserSerializer, - TokenCreateSerializer, ) from rest_framework import serializers from rest_framework.validators import UniqueValidator From 362ada31a84cae1a6a6adecd3f5e3a57a5dab00a Mon Sep 17 00:00:00 2001 From: Lvyshnevska Date: Thu, 12 Oct 2023 17:12:13 +0200 Subject: [PATCH 3/8] variable renamed --- profiles/serializers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/profiles/serializers.py b/profiles/serializers.py index 2346920a4..74f5f1b1f 100644 --- a/profiles/serializers.py +++ b/profiles/serializers.py @@ -208,8 +208,8 @@ def validate_for_delete(self, data): password = data.get("password") if not password: raise serializers.ValidationError("Password is required") - request_user = self.context["request"].user - if not request_user.check_password(password): + user = self.context["request"].user + if not user.check_password(password): raise serializers.ValidationError("Invalid password") return data From 19c3e84a44e469854aad3b1019d2e9b2f5e8b7f9 Mon Sep 17 00:00:00 2001 From: Lvyshnevska Date: Thu, 12 Oct 2023 19:55:16 +0200 Subject: [PATCH 4/8] password check updated --- profiles/serializers.py | 13 +++++++++---- profiles/views.py | 8 +++++--- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/profiles/serializers.py b/profiles/serializers.py index 74f5f1b1f..25978cae8 100644 --- a/profiles/serializers.py +++ b/profiles/serializers.py @@ -204,13 +204,18 @@ class Meta: ) read_only_fields = ("person",) - def validate_for_delete(self, data): + +class ProfileDeleteSerializer(serializers.Serializer): + password = serializers.CharField(write_only=True, required=True) + + # class Meta: + # fields = ("password",) + + def validate(self, data): password = data.get("password") - if not password: - raise serializers.ValidationError("Password is required") user = self.context["request"].user if not user.check_password(password): - raise serializers.ValidationError("Invalid password") + raise serializers.ValidationError({"password": "Invalid password"}) return data diff --git a/profiles/views.py b/profiles/views.py index 2ed3cf8d2..27bbb8487 100644 --- a/profiles/views.py +++ b/profiles/views.py @@ -33,6 +33,7 @@ ProfileDetailSerializer, ProfileOwnerDetailViewSerializer, ProfileOwnerDetailEditSerializer, + ProfileDeleteSerializer, CategorySerializer, ActivitySerializer, RegionSerializer, @@ -171,13 +172,14 @@ def get_serializer_class(self): if get_contacts else ProfileDetailSerializer ) + elif self.request.method == "DELETE": + return ProfileDeleteSerializer else: return ProfileOwnerDetailEditSerializer def perform_destroy(self, instance): - request_data = {"password": self.request.data.get("password")} - serializer = self.get_serializer(instance) - if serializer.validate_for_delete(request_data): + serializer = self.get_serializer(data=self.request.data) + if serializer.is_valid(raise_exception=True): instance.is_deleted = True instance.save() From 5eb105ef7532838ea74614f016e897985f52f709 Mon Sep 17 00:00:00 2001 From: Lvyshnevska Date: Thu, 12 Oct 2023 19:55:46 +0200 Subject: [PATCH 5/8] delete tests updated --- profiles/tests/test_crud_profile.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/profiles/tests/test_crud_profile.py b/profiles/tests/test_crud_profile.py index 5ffb1cc95..f268ff88b 100644 --- a/profiles/tests/test_crud_profile.py +++ b/profiles/tests/test_crud_profile.py @@ -397,6 +397,10 @@ def test_delete_profile_authorized_with_wrong_password(self): data={"password": "Test5678"}, ) self.assertEqual(status.HTTP_400_BAD_REQUEST, response.status_code) + self.assertEqual( + {"password": ["Invalid password"]}, + response.json(), + ) def test_delete_profile_authorized_without_password(self): self.client.force_authenticate(self.user) @@ -408,6 +412,10 @@ def test_delete_profile_authorized_without_password(self): ) ) self.assertEqual(status.HTTP_400_BAD_REQUEST, response.status_code) + self.assertEqual( + {"password": ["This field is required."]}, + response.json(), + ) def test_delete_profile_of_other_user_authorized(self): self.user.set_password("Test1234") From 54350d0db6b62b057cac37412126d6387092da87 Mon Sep 17 00:00:00 2001 From: Lvyshnevska Date: Thu, 12 Oct 2023 20:31:52 +0200 Subject: [PATCH 6/8] comment deleted --- profiles/serializers.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/profiles/serializers.py b/profiles/serializers.py index 25978cae8..a7d741ab4 100644 --- a/profiles/serializers.py +++ b/profiles/serializers.py @@ -208,9 +208,6 @@ class Meta: class ProfileDeleteSerializer(serializers.Serializer): password = serializers.CharField(write_only=True, required=True) - # class Meta: - # fields = ("password",) - def validate(self, data): password = data.get("password") user = self.context["request"].user From 06135177c2883889e38eb9a19a2b3fca443fe263 Mon Sep 17 00:00:00 2001 From: Lvyshnevska Date: Fri, 13 Oct 2023 10:04:50 +0200 Subject: [PATCH 7/8] if removed --- profiles/views.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/profiles/views.py b/profiles/views.py index 27bbb8487..6b68d1b6d 100644 --- a/profiles/views.py +++ b/profiles/views.py @@ -179,9 +179,9 @@ def get_serializer_class(self): def perform_destroy(self, instance): serializer = self.get_serializer(data=self.request.data) - if serializer.is_valid(raise_exception=True): - instance.is_deleted = True - instance.save() + serializer.is_valid(raise_exception=True) + instance.is_deleted = True + instance.save() class ViewedCompanyList(ListCreateAPIView): From cb27ec616a8ea531659b0a2476c191745b2ed5a0 Mon Sep 17 00:00:00 2001 From: Lvyshnevska Date: Fri, 13 Oct 2023 12:18:08 +0200 Subject: [PATCH 8/8] validate replaced with field validation --- profiles/serializers.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/profiles/serializers.py b/profiles/serializers.py index a7d741ab4..1f20af3aa 100644 --- a/profiles/serializers.py +++ b/profiles/serializers.py @@ -208,11 +208,10 @@ class Meta: class ProfileDeleteSerializer(serializers.Serializer): password = serializers.CharField(write_only=True, required=True) - def validate(self, data): - password = data.get("password") + def validate_password(self, data): user = self.context["request"].user - if not user.check_password(password): - raise serializers.ValidationError({"password": "Invalid password"}) + if not user.check_password(data): + raise serializers.ValidationError("Invalid password") return data