From e888b19c9107a3ebb914e9818b8255e8c316d7e4 Mon Sep 17 00:00:00 2001 From: Grollicus <cccvgitlab.db5c7b60@grollmann.eu> Date: Fri, 29 Dec 2023 22:59:27 +0100 Subject: [PATCH] api: delete message --- src/api/tests/messages.py | 51 +++++++++++++++++++++++++++++++++++++++ src/api/urls.py | 1 + src/api/views/messages.py | 38 +++++++++++++++++++++++++++-- 3 files changed, 88 insertions(+), 2 deletions(-) diff --git a/src/api/tests/messages.py b/src/api/tests/messages.py index 77b9649dc..fdde3af34 100644 --- a/src/api/tests/messages.py +++ b/src/api/tests/messages.py @@ -318,3 +318,54 @@ class MessagesTestCase(TestCase): self.assertEqual(DirectMessage.objects.all().count(), 3) dm3 = DirectMessage.objects.get(pk=resp.json()['id']) self.assertTrue(dm3.deleted_by_recipient) + + def test_DirectMessageDelete(self): + c = Client() + resp = c.delete(reverse('api:my-delete-message', kwargs={'pk': str(uuid.uuid4())})) + self.assertEqual(resp.status_code, 403) + c.force_login(self.human_user1) + + dm = DirectMessage( + conference=self.conference1, + sender=self.human_user1, + recipient=self.human_user2, + timestamp=datetime(2020, 5, 4, 3, 2, 1, tzinfo=UTC), + subject='Test Message', + body='Message Body', + ) + dm.save() + + resp = c.delete(reverse('api:my-delete-message', kwargs={'pk': str(dm.pk)})) + self.assertEqual(resp.status_code, 204) + dm.refresh_from_db() + self.assertTrue(dm.deleted_by_sender) + self.assertFalse(dm.deleted_by_recipient) + + dm = DirectMessage( + conference=self.conference1, + sender=self.human_user2, + recipient=self.human_user1, + timestamp=datetime(2020, 1, 2, 3, 4, 5, tzinfo=UTC), + subject='Test Message2', + body='Message Body2', + ) + dm.save() + resp = c.delete(reverse('api:my-delete-message', kwargs={'pk': str(dm.pk)})) + self.assertEqual(resp.status_code, 204) + dm.refresh_from_db() + self.assertFalse(dm.deleted_by_sender) + self.assertTrue(dm.deleted_by_recipient) + + dm = DirectMessage( + conference=self.conference1, + sender=self.human_user2, + recipient=self.human_user1, + timestamp=datetime(2020, 2, 2, 2, 2, 2, tzinfo=UTC), + deleted_by_sender=True, + subject='Test Message3', + body='Message Body3', + ) + dm.save() + resp = c.delete(reverse('api:my-delete-message', kwargs={'pk': str(dm.pk)})) + self.assertEqual(resp.status_code, 204) + self.assertEqual(DirectMessage.objects.filter(pk=dm.pk).count(), 0) diff --git a/src/api/urls.py b/src/api/urls.py index b92ea88dc..8b618b974 100644 --- a/src/api/urls.py +++ b/src/api/urls.py @@ -20,6 +20,7 @@ urlpatterns = [ path('me/received-messages/<uuid:pk>', messages.DirectMessageReceived.as_view(), name='my-message-received'), path('me/sent-messages/<uuid:pk>', messages.DirectMessageSent.as_view(), name='my-message-sent'), path('me/send-message', messages.DirectMessageSend.as_view(), name='my-send-message'), + path('me/delete-message/<uuid:pk>', messages.DirectMessageDelete.as_view(), name='my-delete-message'), path('me/friends', users.friends, name='friends'), path('me/timeline', users.UserTimelineList.as_view(), name='timeline-list'), # conference-specific views diff --git a/src/api/views/messages.py b/src/api/views/messages.py index 1e9adb817..01a3ecf32 100644 --- a/src/api/views/messages.py +++ b/src/api/views/messages.py @@ -1,9 +1,16 @@ -from django.conf import settings from rest_framework import generics, permissions +from django.db.models import Q + from core.models.messages import DirectMessage -from ..serializers import DirectMessageSerializerReceived, DirectMessageSerializerReceivedShort, DirectMessageSerializerSent, DirectMessageSerializerSentShort, DirectMessageSendSerializer +from ..serializers import ( + DirectMessageSendSerializer, + DirectMessageSerializerReceived, + DirectMessageSerializerReceivedShort, + DirectMessageSerializerSent, + DirectMessageSerializerSentShort, +) from .mixins import ConferenceSlugMixin @@ -65,3 +72,30 @@ class DirectMessageSend(ConferenceSlugMixin, generics.CreateAPIView): sender=self.request.user, deleted_by_recipient=self.request.user != serializer.validated_data['recipient'] and self.request.user.shadow_banned, ) + + +class DirectMessageDelete(ConferenceSlugMixin, generics.DestroyAPIView): + permission_classes = [permissions.IsAuthenticated] + + def get_queryset(self): + return DirectMessage.objects.filter( + Q(conference=self.conference, recipient=self.request.user, deleted_by_recipient=False) + | Q(conference=self.conference, sender=self.request.user, deleted_by_sender=False) + ) + + def perform_destroy(self, instance: DirectMessage): + if instance.sender == self.request.user: + if instance.deleted_by_recipient: + instance.delete() + return + + instance.deleted_by_sender = True + instance.save(update_fields=['deleted_by_sender']) + + elif instance.recipient == self.request.user: + if instance.deleted_by_sender: + instance.delete() + return + + instance.deleted_by_recipient = True + instance.save(update_fields=['deleted_by_recipient']) -- GitLab