Skip to content

Commit d373f56

Browse files
committed
only competition participant can be added to a competition group
1 parent 67fc7c3 commit d373f56

File tree

3 files changed

+96
-264
lines changed

3 files changed

+96
-264
lines changed

LICENSE.TXT

Lines changed: 0 additions & 201 deletions
This file was deleted.

src/apps/competitions/views.py

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,17 @@ def get_context_data(self, **kwargs):
4646
Q(id__in=comp.participant_groups.values_list('id', flat=True))
4747
).select_related('queue').prefetch_related('user_set')
4848

49+
participant_user_ids = list(
50+
CompetitionParticipant.objects.filter(competition=comp)
51+
.values_list('user_id', flat=True)
52+
)
53+
4954
ctx['available_groups_json'] = json.dumps([
5055
{
5156
'id': g.id,
5257
'name': g.name,
5358
'queue': g.queue.name if g.queue else None,
54-
'members': [u.username for u in g.user_set.all()],
59+
'members': [u.username for u in g.user_set.filter(pk__in=participant_user_ids)],
5560
}
5661
for g in groups_qs
5762
], cls=DjangoJSONEncoder)
@@ -69,15 +74,13 @@ def get_context_data(self, **kwargs):
6974
ctx['available_users_json'] = json.dumps(
7075
list(
7176
User.objects
72-
.filter(is_active=True)
77+
.filter(pk__in=participant_user_ids, is_active=True)
7378
.values('id', 'username', 'email')
7479
),
7580
cls=DjangoJSONEncoder
7681
)
77-
7882
return ctx
7983

80-
8184
def get_object(self, *args, **kwargs):
8285
competition = super().get_object(*args, **kwargs)
8386

@@ -190,6 +193,11 @@ def competition_create_group(request, pk):
190193
if not name:
191194
return HttpResponseBadRequest("Missing name")
192195

196+
allowed_user_ids = set(
197+
CompetitionParticipant.objects.filter(competition=competition)
198+
.values_list('user_id', flat=True)
199+
)
200+
193201
try:
194202
with transaction.atomic():
195203
group = CustomGroup(name=name)
@@ -201,15 +209,19 @@ def competition_create_group(request, pk):
201209
group.queue = None
202210
group.save()
203211

204-
if user_ids:
205-
# normalize to ints
206-
try:
207-
user_ids_int = [int(u) for u in user_ids]
208-
except Exception:
209-
user_ids_int = []
210-
if user_ids_int:
211-
users_qs = User.objects.filter(pk__in=user_ids_int)
212-
group.user_set.set(users_qs)
212+
user_ids_int = []
213+
try:
214+
user_ids_int = [int(u) for u in user_ids]
215+
except Exception:
216+
user_ids_int = []
217+
218+
if user_ids_int:
219+
invalid = [uid for uid in user_ids_int if uid not in allowed_user_ids]
220+
if invalid:
221+
raise ValueError(f"Some users are not participants of this competition: {invalid}")
222+
223+
users_qs = User.objects.filter(pk__in=user_ids_int)
224+
group.user_set.set(users_qs)
213225

214226
competition.participant_groups.add(group)
215227

@@ -220,6 +232,8 @@ def competition_create_group(request, pk):
220232
'queue': group.queue.name if group.queue else None,
221233
'members': members,
222234
}
235+
except ValueError as e:
236+
return HttpResponseBadRequest(str(e))
223237
except Exception as e:
224238
return HttpResponseBadRequest("Error creating group: %s" % str(e))
225239

@@ -240,6 +254,9 @@ def competition_update_group(request, pk, group_id):
240254
if not (user.is_superuser or user == competition.created_by or user in competition.collaborators.all()):
241255
return HttpResponseForbidden("Not allowed")
242256

257+
if not competition.participant_groups.filter(pk=group.pk).exists():
258+
return HttpResponseBadRequest("Group does not belong to this competition")
259+
243260
if request.content_type == 'application/json':
244261
try:
245262
payload = json.loads(request.body.decode())
@@ -258,6 +275,11 @@ def competition_update_group(request, pk, group_id):
258275
if not name:
259276
return HttpResponseBadRequest("Missing name")
260277

278+
allowed_user_ids = set(
279+
CompetitionParticipant.objects.filter(competition=competition)
280+
.values_list('user_id', flat=True)
281+
)
282+
261283
try:
262284
with transaction.atomic():
263285
group.name = name
@@ -267,12 +289,19 @@ def competition_update_group(request, pk, group_id):
267289
group.queue = None
268290
group.save()
269291

270-
# normalize user ids and set membership
271292
try:
272293
user_ids_int = [int(u) for u in user_ids]
273294
except Exception:
274295
user_ids_int = []
296+
297+
if user_ids_int:
298+
invalid = [uid for uid in user_ids_int if uid not in allowed_user_ids]
299+
if invalid:
300+
raise ValueError(f"Some users are not participants of this competition: {invalid}")
301+
275302
group.user_set.set(User.objects.filter(pk__in=user_ids_int))
303+
except ValueError as e:
304+
return HttpResponseBadRequest(str(e))
276305
except Exception as e:
277306
return HttpResponseBadRequest("Error updating group: %s" % str(e))
278307

@@ -303,6 +332,9 @@ def competition_delete_group(request, pk, group_id):
303332
if not (user.is_superuser or user == competition.created_by or user in competition.collaborators.all()):
304333
return HttpResponseForbidden("Not allowed")
305334

335+
if not competition.participant_groups.filter(pk=group.pk).exists():
336+
return HttpResponseBadRequest("Group does not belong to this competition")
337+
306338
try:
307339
with transaction.atomic():
308340
competition.participant_groups.remove(group)

0 commit comments

Comments
 (0)