From ab623f7ea28ca35a0baaea6bd19e72c7cb438129 Mon Sep 17 00:00:00 2001 From: Adivhaho Mavhungu <68546111+mavhungutrezzy@users.noreply.github.com> Date: Sun, 4 Feb 2024 15:40:10 +0200 Subject: [PATCH 1/2] Validate email syntax on user email update This commit implements email syntax validation when processing user email update requests. It ensures that the provided email address is in the correct format, preventing invalid data from being saved. Closes #17 --- seven23/api/users/views.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/seven23/api/users/views.py b/seven23/api/users/views.py index d5d170e..43047b4 100644 --- a/seven23/api/users/views.py +++ b/seven23/api/users/views.py @@ -10,6 +10,7 @@ from rest_framework.authtoken.models import Token from allauth.account.models import EmailAddress from django.contrib.auth import authenticate +from django.core.validators import validate_email from seven23.models.rest_auth.serializers import UserSerializer @api_view(['POST']) @@ -19,7 +20,9 @@ def email(request): """ try: email = EmailAddress.objects.get(user=request.user) - email.email = request.data['email'] + new_email = request.data.get("email", "") + validate_email(new_email) # Raises a ValidationError if the email is invalid + email.email = new_email email.primary = True email.save() @@ -61,4 +64,4 @@ def delete_user(request): request.user.delete() return HttpResponse(status=200) else: - return HttpResponse(status=400) \ No newline at end of file + return HttpResponse(status=400) From 6cd247bffcecfcd8d96ee09c4b0264c2b02e5a85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Barbier?= Date: Sun, 4 Feb 2024 17:34:31 +0100 Subject: [PATCH 2/2] Add Test regarding email validation on POST request Related to #17 --- CHANGELOG.md | 4 ++++ seven23/api/users/tests_users.py | 31 ++++++++++++++++++++++++++++++- seven23/api/users/views.py | 4 +++- seven23/settings.py | 2 +- 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 35978b9..5a7d2eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). See for sample https://raw.githubusercontent.com/favoloso/conventional-changelog-emoji/master/CHANGELOG.md --> +## [1.5.1] - 2024-02-04 +### 🐛 Bug Fixes +- Check **email syntax** on update request (#17) + ## [1.5.0] - 2024-01-02 ### ✨ Feature - Make **trial period** customizable (#98) diff --git a/seven23/api/users/tests_users.py b/seven23/api/users/tests_users.py index 3b12e17..1a92409 100644 --- a/seven23/api/users/tests_users.py +++ b/seven23/api/users/tests_users.py @@ -21,6 +21,7 @@ class ApiUsersTest(TransactionTestCase): def setUp(self): self.client = APIClient() + self.user = User.objects.create_user(username='foo', email='test2@sebastienbarbier.com') def test_registration_new_user(self): """ @@ -45,10 +46,38 @@ def test_registration_new_user(self): # Test if response data key is define, a string, and not empty or blank self.assertTrue('username' in data) self.assertEqual(data['username'], 'test') + self.assertTrue('email' in data) self.assertTrue('profile' in data) self.assertTrue('avatar' in data['profile']) self.assertTrue('auto_sync' in data['profile']) self.assertTrue('key_verified' in data['profile']) self.assertTrue('social_networks' in data['profile']) self.assertTrue(data['profile']['auto_sync']) - self.assertFalse(data['profile']['key_verified']) \ No newline at end of file + self.assertFalse(data['profile']['key_verified']) + + + def test_wrong_email_syntax(self): + """ + Create a user using rest-auth and get auth key in response. + """ + self.client.force_authenticate(user=self.user) + # Fetch newly created profile and verify if email is valid + response = self.client.get('/api/v1/rest-auth/user/') + self.assertEqual(response.status_code, status.HTTP_200_OK) + data = response.json() + self.assertEqual(data['email'], 'test2@sebastienbarbier.com') + # Update email with valid email return 200 + response = self.client.post('/api/v1/users/email', { + 'email': 'test2@sebastienbarbier.com', + }, format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + + response = self.client.get('/api/v1/rest-auth/user/') + data = response.json() + self.assertEqual(data['email'], 'test2@sebastienbarbier.com') + + # Update email with vunalid email return 400 + response = self.client.post('/api/v1/users/email', { + 'email': 'ThisIsNotAnEmail', + }, format='json') + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) \ No newline at end of file diff --git a/seven23/api/users/views.py b/seven23/api/users/views.py index 43047b4..7cdfd77 100644 --- a/seven23/api/users/views.py +++ b/seven23/api/users/views.py @@ -36,6 +36,8 @@ def email(request): request.user.email = request.data['email'] request.user.save() + except: + return HttpResponse(status=400) # Return json format string. j = json.dumps(UserSerializer(request.user).data, separators=(',', ':')) @@ -64,4 +66,4 @@ def delete_user(request): request.user.delete() return HttpResponse(status=200) else: - return HttpResponse(status=400) + return HttpResponse(status=400) \ No newline at end of file diff --git a/seven23/settings.py b/seven23/settings.py index 5bd1f97..c34f11f 100644 --- a/seven23/settings.py +++ b/seven23/settings.py @@ -30,7 +30,7 @@ integrations=[DjangoIntegration()] ) -VERSION = [1, 5, 0] +VERSION = [1, 5, 1] API_VERSION = [1, 1, 0] BASE_DIR = os.path.dirname(os.path.dirname(__file__))