Skip to content

Commit 8d9b59c

Browse files
authored
Merge pull request #1900 from codalab/submission_deletion
Submission delete API bug fixed. More restrictions added
2 parents c0d66d9 + f1c9ddd commit 8d9b59c

File tree

2 files changed

+49
-12
lines changed

2 files changed

+49
-12
lines changed

src/apps/api/tests/test_submissions.py

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ def setUp(self):
2222
self.collaborator = UserFactory(username='collab', password='collab')
2323
self.comp = CompetitionFactory(created_by=self.creator, collaborators=[self.collaborator])
2424
self.phase = PhaseFactory(competition=self.comp)
25+
self.leaderboard = LeaderboardFactory()
2526

2627
# Extra dummy user to test permissions, they shouldn't have access to many things
2728
self.other_user = UserFactory(username='other_user', password='other')
@@ -41,7 +42,16 @@ def setUp(self):
4142
phase=self.phase,
4243
owner=self.participant,
4344
status=Submission.SUBMITTED,
44-
secret='7df3600c-1234-5678-bbc8-bbe91f42d875'
45+
secret='7df3600c-1234-5678-bbc8-bbe91f42d875',
46+
leaderboard=None
47+
)
48+
49+
# add submission with that is on the leaderboard
50+
self.leaderboard_submission = SubmissionFactory(
51+
phase=self.phase,
52+
owner=self.participant,
53+
status=Submission.SUBMITTED,
54+
leaderboard=self.leaderboard
4555
)
4656

4757
def test_can_make_submission_checks_if_you_are_participant(self):
@@ -95,34 +105,47 @@ def test_cannot_delete_submission_you_didnt_create(self):
95105
# As anonymous user
96106
resp = self.client.delete(url)
97107
assert resp.status_code == 403
98-
assert resp.data["detail"] == "Cannot interact with submission you did not make"
108+
assert resp.data["detail"] == "You do not have permission to delete this submission!"
99109

100110
# As regular user
101111
self.client.force_login(self.other_user)
102112
resp = self.client.delete(url)
103113
assert resp.status_code == 403
104-
assert resp.data["detail"] == "Cannot interact with submission you did not make"
114+
assert resp.data["detail"] == "You do not have permission to delete this submission!"
105115

116+
def test_can_delete_submission_you_created(self):
117+
url = reverse('submission-detail', args=(self.existing_submission.pk,))
106118
# As user who made submission
107119
self.client.force_login(self.participant)
108120
resp = self.client.delete(url)
109121
assert resp.status_code == 204
110122
assert not Submission.objects.filter(pk=self.existing_submission.pk).exists()
111123

112-
# As superuser (re-making submission since it has been destroyed)
113-
self.existing_submission = SubmissionFactory(
114-
phase=self.phase,
115-
owner=self.participant,
116-
status=Submission.SUBMITTED,
117-
secret='7df3600c-1234-5678-90c8-bbe91f42d875'
118-
)
124+
def test_super_user_can_delete_submission_you_created(self):
119125
url = reverse('submission-detail', args=(self.existing_submission.pk,))
120126

121127
self.client.force_login(self.superuser)
122128
resp = self.client.delete(url)
123129
assert resp.status_code == 204
124130
assert not Submission.objects.filter(pk=self.existing_submission.pk).exists()
125131

132+
def test_super_user_can_delete_leaderboard_submission_you_created(self):
133+
url = reverse('submission-detail', args=(self.leaderboard_submission.pk,))
134+
135+
self.client.force_login(self.superuser)
136+
resp = self.client.delete(url)
137+
assert resp.status_code == 204
138+
assert not Submission.objects.filter(pk=self.leaderboard_submission.pk).exists()
139+
140+
def test_cannot_delete_leaderboard_submission_you_created(self):
141+
url = reverse('submission-detail', args=(self.leaderboard_submission.pk,))
142+
143+
self.client.force_login(self.participant)
144+
resp = self.client.delete(url)
145+
146+
assert resp.status_code == 403
147+
assert resp.data["detail"] == "You cannot delete a leaderboard submission!"
148+
126149
def test_cannot_get_details_of_submission_unless_creator_collab_or_superuser(self):
127150
url = reverse('submission-get-details', args=(self.existing_submission.pk,))
128151

src/apps/api/views/submissions.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,11 +198,25 @@ def create(self, request, *args, **kwargs):
198198
return super(SubmissionViewSet, self).create(request, *args, **kwargs)
199199

200200
def destroy(self, request, *args, **kwargs):
201+
"""
202+
- If user is neither owner nor admin, user cannot delete the submission
203+
- If a user is not admin and is owner of a submission and submission is on the leaderboard, user cannot delete the submission
204+
- In rest of the cases i.e. user is admin/super user or user is owner of the submisison and submission is not on the leaderboard, user can delete the submisison
205+
"""
201206
submission = self.get_object()
202207

203-
if request.user != submission.owner and not self.has_admin_permission(request.user, submission):
204-
raise PermissionDenied("Cannot interact with submission you did not make")
208+
is_owner = request.user == submission.owner
209+
is_super_user_or_competition_admin = self.has_admin_permission(request.user, submission)
210+
211+
# If user is neither owner nor super user/admin return permission denied
212+
if not is_owner and not is_super_user_or_competition_admin:
213+
raise PermissionDenied("You do not have permission to delete this submission!")
214+
215+
# If user is not admin, is owner and submission is on the leaderboard return permission denied
216+
if not is_super_user_or_competition_admin and is_owner and submission.leaderboard:
217+
raise PermissionDenied("You cannot delete a leaderboard submission!")
205218

219+
# Otherwise, delete the submission
206220
self.perform_destroy(submission)
207221
return Response(status=status.HTTP_204_NO_CONTENT)
208222

0 commit comments

Comments
 (0)