From c2b6dbb989213eff4938f03a40e5453d42a4208e Mon Sep 17 00:00:00 2001 From: starnakin Date: Thu, 30 Nov 2023 14:03:38 +0100 Subject: [PATCH] api: add: edit accounts --- accounts/serializers/change_password.py | 7 ----- accounts/tests/__init__.py | 2 +- accounts/tests/change_password.py | 31 ------------------ accounts/tests/edit.py | 28 ++++++++++++++--- accounts/urls.py | 4 +-- accounts/views/change_password.py | 25 --------------- accounts/views/edit.py | 42 +++++++++++++++++++++++++ 7 files changed, 68 insertions(+), 71 deletions(-) delete mode 100644 accounts/serializers/change_password.py delete mode 100644 accounts/tests/change_password.py delete mode 100644 accounts/views/change_password.py create mode 100644 accounts/views/edit.py diff --git a/accounts/serializers/change_password.py b/accounts/serializers/change_password.py deleted file mode 100644 index 029b81c..0000000 --- a/accounts/serializers/change_password.py +++ /dev/null @@ -1,7 +0,0 @@ -from rest_framework.serializers import Serializer, CharField - -class ChangePasswordSerializer(Serializer): - - current_password = CharField() - new_password = CharField() - \ No newline at end of file diff --git a/accounts/tests/__init__.py b/accounts/tests/__init__.py index ee5d68b..4187043 100644 --- a/accounts/tests/__init__.py +++ b/accounts/tests/__init__.py @@ -1,4 +1,4 @@ from .register import * from .login import * -from .change_password import * +from .edit import * from .delete import * \ No newline at end of file diff --git a/accounts/tests/change_password.py b/accounts/tests/change_password.py deleted file mode 100644 index 4d79787..0000000 --- a/accounts/tests/change_password.py +++ /dev/null @@ -1,31 +0,0 @@ -from django.test import TestCase - -# Create your tests here. -from django.test.client import Client -from django.http import HttpResponse -from django.contrib.auth.models import User - -import uuid - -class ChangePasswordTest(TestCase): - def setUp(self): - self.client = Client() - - self.url = "/accounts/change_password" - - self.username: str = str(uuid.uuid4()) - self.password: str = str(uuid.uuid4()) - self.new_password: str = str(uuid.uuid4()) - - User.objects.create_user(username = self.username, password = self.password) - - def test_normal(self): - self.client.login(username = self.username, password = self.password) - response: HttpResponse = self.client.post(self.url, {"current_password": self.password, "new_password": self.new_password}) - response_text: str = response.content.decode('utf-8') - self.assertEqual(response_text, '"password changed"') - - def test_nologged(self): - response: HttpResponse = self.client.post(self.url, {"current_password": self.password, "new_password": self.new_password}) - errors: dict = eval(response.content) - self.assertDictEqual(errors, {'detail': 'Authentication credentials were not provided.'}) \ No newline at end of file diff --git a/accounts/tests/edit.py b/accounts/tests/edit.py index 4d79787..84ac416 100644 --- a/accounts/tests/edit.py +++ b/accounts/tests/edit.py @@ -7,11 +7,11 @@ from django.contrib.auth.models import User import uuid -class ChangePasswordTest(TestCase): +class EditTest(TestCase): def setUp(self): self.client = Client() - self.url = "/accounts/change_password" + self.url = "/api/accounts/edit" self.username: str = str(uuid.uuid4()) self.password: str = str(uuid.uuid4()) @@ -21,11 +21,29 @@ class ChangePasswordTest(TestCase): def test_normal(self): self.client.login(username = self.username, password = self.password) - response: HttpResponse = self.client.post(self.url, {"current_password": self.password, "new_password": self.new_password}) + response: HttpResponse = self.client.patch(self.url, {"current_password": self.password, "new_password": self.new_password, "username": "bozo"}, content_type='application/json') response_text: str = response.content.decode('utf-8') - self.assertEqual(response_text, '"password changed"') + self.assertEqual(response_text, '"data has been alterate"') + def test_invalid_current_password(self): + self.client.login(username = self.username, password = self.password) + response: HttpResponse = self.client.patch(self.url, {"current_password": "bozo", "new_password": self.new_password, "username": "bozo"}, content_type='application/json') + errors: dict = eval(response.content) + self.assertDictEqual(errors, {"current_password":["Password is wrong."]}) + + def test_invalid_new_username_blank(self): + self.client.login(username = self.username, password = self.password) + response: HttpResponse = self.client.patch(self.url, {"current_password": self.password, "username": " "}, content_type='application/json') + errors: dict = eval(response.content) + self.assertDictEqual(errors, {'username': ['This field may not be blank.']}) + + def test_invalid_new_username_char(self): + self.client.login(username = self.username, password = self.password) + response: HttpResponse = self.client.patch(self.url, {"current_password": self.password, "username": "*&"}, content_type='application/json') + errors: dict = eval(response.content) + self.assertDictEqual(errors, {'username': ['Enter a valid username. This value may contain only letters, numbers, and @/./+/-/_ characters.']}) + def test_nologged(self): - response: HttpResponse = self.client.post(self.url, {"current_password": self.password, "new_password": self.new_password}) + response: HttpResponse = self.client.patch(self.url, {"current_password": self.password, "new_password": self.new_password}, content_type='application/json') errors: dict = eval(response.content) self.assertDictEqual(errors, {'detail': 'Authentication credentials were not provided.'}) \ No newline at end of file diff --git a/accounts/urls.py b/accounts/urls.py index 68e777a..73ae6d7 100644 --- a/accounts/urls.py +++ b/accounts/urls.py @@ -1,6 +1,6 @@ from django.urls import path -from .views import register, login, logout, delete, change_password, logged +from .views import register, login, logout, delete, edit, logged urlpatterns = [ path("register", register.RegisterView.as_view(), name="register"), @@ -8,6 +8,6 @@ urlpatterns = [ path("logout", logout.LogoutView.as_view(), name="logout"), path("logged", logged.LoggedView.as_view(), name="logged"), path("delete", delete.DeleteView.as_view(), name="delete"), - path("change_password", change_password.ChangePasswordView.as_view(), name="change_password") + path("edit", edit.EditView.as_view(), name="change_password") ] \ No newline at end of file diff --git a/accounts/views/change_password.py b/accounts/views/change_password.py deleted file mode 100644 index cb8579b..0000000 --- a/accounts/views/change_password.py +++ /dev/null @@ -1,25 +0,0 @@ -from rest_framework.views import APIView -from rest_framework.response import Response -from rest_framework import permissions, status -from django.http import HttpRequest -from django.contrib.auth import login -from rest_framework.authentication import SessionAuthentication -from django.contrib.auth.models import User - -from ..serializers.change_password import ChangePasswordSerializer - -class ChangePasswordView(APIView): - - permission_classes = (permissions.IsAuthenticated,) - authentication_classes = (SessionAuthentication,) - - def post(self, request: HttpRequest): - data = request.data - - serializer = ChangePasswordSerializer(data=data) - if serializer.is_valid(raise_exception=True): - user: User = request.user - if (user.check_password(data['current_password']) == 0): - return Response({'current_password': "The password is not right."}, status=status.HTTP_200_OK) - user.set_password(data["new_password"]) - return Response('password changed', status=status.HTTP_200_OK) \ No newline at end of file diff --git a/accounts/views/edit.py b/accounts/views/edit.py new file mode 100644 index 0000000..8325b06 --- /dev/null +++ b/accounts/views/edit.py @@ -0,0 +1,42 @@ +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework import permissions, status +from django.http import HttpRequest +from django.contrib.auth import login +from rest_framework.authentication import SessionAuthentication +from django.contrib.auth.models import User +import re + +class EditView(APIView): + + permission_classes = (permissions.IsAuthenticated,) + authentication_classes = (SessionAuthentication,) + + def patch(self, request: HttpRequest): + data: dict = request.data + + current_password: str = data.get("current_password") + if (current_password is None): + return Response({"current_password": ["This field may not be blank."]}) + + user_object = request.user + + if (user_object.check_password(current_password) == False): + return Response({"current_password": ["Password is wrong."]}) + + new_username = data.get("username", user_object.username) + if (new_username != user_object.username): + if (User.objects.filter(username=new_username).exists()): + return Response({"username": ["A user with that username already exists."]}) + if (set(new_username) == {' '}): + return Response({"username": ["This field may not be blank."]}) + if (re.search('^([a-z]||\@||\+||\-||\_)+$', new_username) is None): + return Response({"username":["Enter a valid username. This value may contain only letters, numbers, and @/./+/-/_ characters."]}) + + new_password: str = data.get("password") + if (new_password is not None): + user_object.set_password(new_password) + + user_object.save() + + return Response("data has been alterate") \ No newline at end of file