diff --git a/src/apps/api/serializers/submissions.py b/src/apps/api/serializers/submissions.py index db4b91e91..8207de686 100644 --- a/src/apps/api/serializers/submissions.py +++ b/src/apps/api/serializers/submissions.py @@ -181,10 +181,16 @@ def validate(self, attrs): return data def update(self, submission, validated_data): - # TODO: Test, could you change the phase of a submission? + + # Cannot change submission if secret key is not valid if submission.secret != validated_data.get('secret'): raise PermissionDenied("Submission secret invalid") + # Task of a submission cannot be updated + if "task" in validated_data: + raise PermissionDenied("Task of a submission cannot be update") + + # Update status if it is there in validated data if "status" in validated_data: # Received a status update, let the frontend know from channels.layers import get_channel_layer diff --git a/src/apps/api/tests/test_submissions.py b/src/apps/api/tests/test_submissions.py index 0d8e54bc6..e91a64ecb 100644 --- a/src/apps/api/tests/test_submissions.py +++ b/src/apps/api/tests/test_submissions.py @@ -243,6 +243,34 @@ def test_who_can_see_detailed_result_when_visualization_is_true(self): assert resp.status_code == 403 +class SubmissionUpdateTest(APITestCase): + def setUp(self): + self.user = UserFactory(username='test') + self.task1 = TaskFactory(created_by=self.user) + self.task2 = TaskFactory(created_by=self.user) + self.competition = CompetitionFactory(created_by=self.user) + self.phase = PhaseFactory(competition=self.competition, tasks=[self.task1]) + self.secret = '7df3600c-1234-5678-bbc8-bbe91f42d875' + self.submission = SubmissionFactory( + task=self.task1, + phase=self.phase, + status=Submission.FINISHED, + secret=self.secret + ) + + def test_submission_task_update(self): + url = reverse('submission-detail', args=(self.submission.pk,)) + + # Update task + resp = self.client.patch(url, { + "task": self.task2.id, + "secret": self.secret + }) + assert resp.status_code == 403 + assert resp.data["detail"] == "Submission task cannot be updated" + assert self.submission.task.id == self.task1.id # task not updated + + class OrganizationSubmissionTests(APITestCase): def setUp(self): # Competition and creator diff --git a/src/apps/api/views/submissions.py b/src/apps/api/views/submissions.py index 896b4731e..7e6b5970f 100644 --- a/src/apps/api/views/submissions.py +++ b/src/apps/api/views/submissions.py @@ -53,6 +53,8 @@ def check_object_permissions(self, request, obj): try: if request.data.get('secret') is None or uuid.UUID(request.data.get('secret')) != obj.secret: raise PermissionDenied("Submission secrets do not match") + if request.data.get('task'): + raise PermissionDenied("Submission task cannot be updated") except TypeError: raise ValidationError(f"Secret: ({request.data.get('secret')}) not a valid UUID")