From b3bae6f5ad2d96da8b5d36d4e407cb53322e54b2 Mon Sep 17 00:00:00 2001 From: jedi Date: Sat, 24 Feb 2024 00:36:04 +0100 Subject: [PATCH] prevent duplicate friend requests --- backend/toolshed/api/friend.py | 12 ++++++-- backend/toolshed/tests/test_friend.py | 43 ++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/backend/toolshed/api/friend.py b/backend/toolshed/api/friend.py index a0337c5..07ee0fc 100644 --- a/backend/toolshed/api/friend.py +++ b/backend/toolshed/api/friend.py @@ -64,10 +64,18 @@ class FriendsRequests(APIView, ViewSetMixin): befriendee_username, befriendee_domain = split_userhandle_or_throw(request.data['befriendee']) if befriender_domain == befriendee_domain and befriender_username == befriendee_username: return Response(status=status.HTTP_400_BAD_REQUEST, data={'status': 'cannot befriend yourself'}) - if user := authenticate_request_against_local_users(request, raw_request): + if user := authenticate_request_against_local_users(request, raw_request): # befriender is local secret = secrets.token_hex(64) befriendee_user = ToolshedUser.objects.filter(username=befriendee_username, domain=befriendee_domain) - if befriendee_user.exists(): + if befriendee_user.exists(): # befriendee is local (both are local) + if user.friends.filter(username=befriendee_username, domain=befriendee_domain).exists(): + return Response(status=status.HTTP_208_ALREADY_REPORTED, data={'status': "exists"}) + existing_request = FriendRequestIncoming.objects.filter( + befriender_username=befriender_username, + befriender_domain=befriender_domain, + befriendee_user=befriendee_user.get()) + if existing_request.exists(): + return Response(status=status.HTTP_208_ALREADY_REPORTED, data={'status': "exists"}) FriendRequestIncoming.objects.create( befriender_username=befriender_username, befriender_domain=befriender_domain, diff --git a/backend/toolshed/tests/test_friend.py b/backend/toolshed/tests/test_friend.py index d689600..31132a3 100644 --- a/backend/toolshed/tests/test_friend.py +++ b/backend/toolshed/tests/test_friend.py @@ -130,7 +130,7 @@ class FriendRequestListTestCase(UserTestMixin, ToolshedTestCase): def test_delete_friend_request(self): reply = client.delete('/api/friendrequests/{}/'.format(self.friendrequest1.id), - self.f['local_user1']) + self.f['local_user1']) self.assertEqual(reply.status_code, 204) self.assertEqual(FriendRequestIncoming.objects.count(), 0) @@ -368,3 +368,44 @@ class FriendRequestOutgoingTestCase(UserTestMixin, ToolshedTestCase): self.assertEqual(befriendee.friends.count(), 1) self.assertEqual(befriendee.friends.first().username, befriender.username) self.assertEqual(befriendee.friends.first().domain, befriender.domain) + + +class FriendRequestCombinedTestCase(UserTestMixin, ToolshedTestCase): + + def setUp(self): + super().setUp() + self.prepare_users() + print(self.f) + + def test_friend_request_combined(self): + befriender = self.f['local_user1'] + befriendee = self.f['local_user2'] + reply1 = client.post('/api/friendrequests/', befriender, { + 'befriender': str(befriender), + 'befriendee': str(befriendee), + }) + secret = reply1.json()['secret'] + reply2 = client.post('/api/friendrequests/', befriender, { + 'befriender': str(befriender), + 'befriender_key': befriender.public_key(), + 'befriendee': str(befriendee), + 'secret': secret + }) + + self.assertEqual(reply1.status_code, 201) + self.assertEqual(reply2.status_code, 208) + self.assertEqual(reply1.json()['status'], 'pending') + self.assertEqual(reply2.json()['status'], 'exists') + self.assertEqual(FriendRequestIncoming.objects.count(), 1) + + def test_friend_request_already_friends(self): + befriender = self.f['local_user1'] + befriendee = self.f['local_user2'] + befriender.friends.add(befriendee.public_identity) + reply1 = client.post('/api/friendrequests/', befriender, { + 'befriender': str(befriender), + 'befriendee': str(befriendee), + }) + self.assertEqual(reply1.status_code, 208) + self.assertEqual(reply1.json()['status'], 'exists') + self.assertEqual(FriendRequestIncoming.objects.count(), 0)