diff --git a/backend/letters/serializers.py b/backend/letters/serializers.py index aad04c1..127002d 100644 --- a/backend/letters/serializers.py +++ b/backend/letters/serializers.py @@ -47,6 +47,12 @@ class LetterSerializer(serializers.ModelSerializer): fields["encrypted_dek"] = None except (ValueError, TypeError): pass + + if fields["status"] == Letter.Status.BURNED: + fields["encrypted_content"] = None + fields["images"] = None + fields["encrypted_dek"] = None + return fields def validate(self, data): diff --git a/backend/letters/tests.py b/backend/letters/tests.py index 431095f..26405dc 100644 --- a/backend/letters/tests.py +++ b/backend/letters/tests.py @@ -248,6 +248,38 @@ class LetterAPITest(APITestCase): self.assertEqual(response.data["encrypted_metadata"], "enc_meta==") self.assertEqual(response.data["encrypted_dek"], "enc_dek==") + def test_burn_letter(self): + """ + Test that a sealed letter can only be burned but not updated. + """ + letter = Letter.objects.create( + user=self.user, + type="KEPT", + status="SEALED", + public_id="4281edcc-5459-4ff2-bb5e-669fb44e0757", + encrypted_content="enc_content==", + encrypted_metadata="enc_meta==", + encrypted_dek="enc_dek==", + ) + + response_update_content = self.client.patch( + self.url + letter.public_id + "/", + { + "encrypted_content": "enc_content_new==", + "encrypted_metadata": "enc_meta_new==", + "encrypted_dek": "enc_dek_new==", + }, + ) + response_burn = self.client.patch(self.url + letter.public_id + "/", {"status": "BURNED"}) + + self.assertEqual(response_update_content.status_code, 400) + self.assertEqual(response_update_content.data["error"], "Sealed letters can only be burned.") + self.assertEqual(Letter.objects.get().encrypted_content, "enc_content==") + + self.assertEqual(response_burn.status_code, 200) + self.assertEqual(Letter.objects.count(), 1) + self.assertEqual(Letter.objects.get().status, "BURNED") + class LetterImageModelTest(TestCase): def setUp(self): diff --git a/backend/letters/views.py b/backend/letters/views.py index 371a103..ea6354e 100644 --- a/backend/letters/views.py +++ b/backend/letters/views.py @@ -62,3 +62,20 @@ class LetterDetailView(generics.RetrieveUpdateDestroyAPIView): response_serializer = self.get_serializer(letter) return Response(response_serializer.data, status=201 if created else 200) + + def patch(self, request, public_id): + """ + Updates an existing letter. + """ + letter = Letter.objects.get(public_id=public_id, user=request.user) + + if letter.status == Letter.Status.SEALED and ( + len(request.data) > 1 or request.data.get("status") != Letter.Status.BURNED + ): + return Response({"error": "Sealed letters can only be burned."}, status=400) + + write_serializer = self.get_serializer(letter, data=request.data, partial=True) + write_serializer.is_valid(raise_exception=True) + write_serializer.save() + response_serializer = self.get_serializer(letter) + return Response(response_serializer.data, status=200)