Compare commits

..

9 Commits

Author SHA1 Message Date
Danhia f1b1214291 Merge pull request 'New permissions to allow a group of user to manage event-related objects' (#89) from Danhia/website:admin/events-permissions into main
Reviewed-on: 42CTF/website#89
2023-09-24 15:25:41 +02:00
Danhia 8b28f73bdb added special permissions to allow a group of user to manage event-related objects 2023-09-24 15:17:49 +02:00
Danhia c8adc6caf9 Merge pull request 'Added speed bonus points for events' (#88) from Danhia/website:events/bonus-points into main
Reviewed-on: 42CTF/website#88
2023-09-17 20:43:42 +02:00
Danhia 6ecb94eab5 added speed bonus points for events 2023-09-17 20:39:13 +02:00
Danhia 44897411f5 Merge pull request 'Fix invalid characters in team name that causes error 500' (#87) from Danhia/website:events/fix-teamname into main
Reviewed-on: 42CTF/website#87
2023-09-01 11:10:54 +02:00
Danhia 5a10e033a2 Merge pull request 'fix(api): Check if user has campus before add to response' (#85) from Starthur/website:main into main
Reviewed-on: 42CTF/website#85
Reviewed-by: Danhia <danhia@protonmail.com>
2023-09-01 11:09:53 +02:00
Starthur 691c53e110
fix(api): Check if user has campus before add to response 2023-02-07 10:15:30 +01:00
Starthur 2d4816e78f Merge pull request '[API][BOT] New endpoint to retrieve campus associated to discord id' (#84) from Danhia/website:api-campus into main
Reviewed-on: 42CTF/website#84
Reviewed-by: Starthur <contact+42ctf@arthur-trt.fr>
2023-02-07 09:43:57 +01:00
Danhia 5d84174db2 Added new endpoint to retrieve campus associated to discord id 2023-02-06 19:41:48 +01:00
15 changed files with 327 additions and 67 deletions

View File

@ -87,7 +87,6 @@ def connect_discord(request):
@login_required @login_required
def authorize_discord(request): def authorize_discord(request):
if request.user.userprofileinfo.discord_id: if request.user.userprofileinfo.discord_id:
print("Already")
return bad_request(request, "Already connected") return bad_request(request, "Already connected")
try: try:
token = oauth.discord.authorize_access_token(request) token = oauth.discord.authorize_access_token(request)

View File

@ -2,6 +2,8 @@ from django.urls import path
from . import views from . import views
urlpatterns = [ urlpatterns = [
path('bot/discord', views.discord_bot, name='discord_bot'), path('bot/discord', views.bot_discord_rank, name='bot_discord_rank'), # legacy, to remove when new bot is deployed
path('bot/discord/rank', views.bot_discord_rank, name='bot_discord_rank'), # use this
path('bot/discord/campus', views.bot_discord_campus, name='bot_discord_campus'),
path('events/<str:event_slug>', views.events_data, name='events_data'), path('events/<str:event_slug>', views.events_data, name='events_data'),
] ]

View File

@ -7,17 +7,16 @@ from django.shortcuts import get_object_or_404
# Create your views here. # Create your views here.
def bot_discord_rank(request):
def discord_bot(request):
if request.method != 'GET': if request.method != 'GET':
return JsonResponse({'error':'bad request'}) return JsonResponse({'error':'bad request'})
token = request.GET.get('token') token = request.GET.get('token')
auth_token = os.getenv('BOT_TOKEN') auth_token = os.getenv('BOT_TOKEN')
if (token != auth_token or not auth_token): if (token != auth_token or not auth_token):
return JsonResponse({'error':'not authorized'}) return JsonResponse({'error':'not authorized'})
all_users = UserProfileInfo.objects.select_related().order_by('-score', 'last_submission_date', 'user__username') all_users = UserProfileInfo.objects.select_related().order_by('-score', 'last_submission_date', 'user__username')
data = {} data = {}
rank = 1 rank = 1
@ -28,15 +27,33 @@ def discord_bot(request):
return JsonResponse(data) return JsonResponse(data)
def bot_discord_campus(request):
if request.method != 'GET':
return JsonResponse({'error':'bad request'})
token = request.GET.get('token')
auth_token = os.getenv('BOT_TOKEN')
if (token != auth_token or not auth_token):
return JsonResponse({'error':'not authorized'})
all_users = UserProfileInfo.objects.select_related().order_by('-score', 'last_submission_date', 'user__username')
data = {}
for user in all_users:
if user.campus and user.discord_id:
data[user.discord_id] = user.campus.name
return JsonResponse(data)
def events_data(request, event_slug): def events_data(request, event_slug):
if request.method != 'GET': if request.method != 'GET':
return JsonResponse({'error':'bad request'}) return JsonResponse({'error':'bad request'})
event_info = get_object_or_404(Event, slug=event_slug) event_info = get_object_or_404(Event, slug=event_slug)
if event_info.password and request.GET.get('password') != event_info.password: if event_info.password and request.GET.get('password') != event_info.password:
return JsonResponse({'error':'not authorized'}) return JsonResponse({'error':'not authorized'})
players = EventPlayer.objects.filter(event=event_info) players = EventPlayer.objects.filter(event=event_info)
data = {} data = {}
@ -50,7 +67,6 @@ def events_data(request, event_slug):
else: else:
for player in players: for player in players:
data[player.user.username] = player.score data[player.user.username] = player.score
return JsonResponse(data) return JsonResponse(data)

View File

@ -2,8 +2,6 @@ from django.contrib import admin
from .models import Category, CTF, CTF_flags from .models import Category, CTF, CTF_flags
admin.site.register(Category) admin.site.register(Category)
#admin.site.register(CTF)
#admin.site.register(CTF_flags)
@admin.register(CTF_flags) @admin.register(CTF_flags)
class ctf_flags(admin.ModelAdmin): class ctf_flags(admin.ModelAdmin):
@ -14,12 +12,61 @@ class ctf_flags(admin.ModelAdmin):
# search list # search list
search_fields = ['ctf__category__name', 'ctf__name', 'user__username'] search_fields = ['ctf__category__name', 'ctf__name', 'user__username']
def get_queryset(self, request):
qs = super().get_queryset(request)
if request.user.is_superuser:
return qs
groups = list(request.user.groups.values_list('name', flat=True))
return qs.filter(event__name__in=groups)
def has_view_permission(self, request, obj=None):
if request.user.is_superuser:
return True
if obj is not None:
return request.user.groups.filter(name=obj.event.name).exists()
return super().has_view_permission(request, obj)
def has_change_permission(self, request, obj=None):
if request.user.is_superuser:
return True
if obj is not None:
return request.user.groups.filter(name=obj.event.name).exists()
return super().has_change_permission(request, obj)
def has_delete_permission(self, request, obj=None):
if request.user.is_superuser:
return True
if obj is not None:
return request.user.groups.filter(name=obj.event.name).exists()
return super().has_delete_permission(request, obj)
@admin.register(CTF) @admin.register(CTF)
class ctf(admin.ModelAdmin): class ctf(admin.ModelAdmin):
#list display #list display
list_display = ['name', 'event', 'category'] list_display = ['name', 'event', 'category', 'points']
#list Filter #list Filter
list_filter = ('category', 'event') list_filter = ('category', 'event')
# search list # search list
search_fields = ['category__name', 'name', 'author__username'] search_fields = ['category__name', 'name', 'author__username']
# Register your models here.
def get_queryset(self, request):
qs = super().get_queryset(request)
if request.user.is_superuser:
return qs
groups = list(request.user.groups.values_list('name', flat=True))
return qs.filter(event__name__in=groups)
def has_view_permission(self, request, obj=None):
if request.user.is_superuser:
return True
if obj is not None:
return request.user.groups.filter(name=obj.event.name).exists()
return super().has_view_permission(request, obj)
def has_change_permission(self, request, obj=None):
if request.user.is_superuser:
return True
if obj is not None:
return request.user.groups.filter(name=obj.event.name).exists()
return super().has_change_permission(request, obj)

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.11 on 2023-09-17 17:57
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('ctfs', '0008_auto_20220215_1713'),
]
operations = [
migrations.AddField(
model_name='ctf_flags',
name='bonus',
field=models.PositiveSmallIntegerField(default=0),
),
]

View File

@ -45,6 +45,7 @@ class CTF_flags(models.Model):
user = models.ForeignKey(User, unique=False, on_delete=models.CASCADE) user = models.ForeignKey(User, unique=False, on_delete=models.CASCADE)
ctf = models.ForeignKey(CTF, unique=False, on_delete=models.CASCADE) ctf = models.ForeignKey(CTF, unique=False, on_delete=models.CASCADE)
flag_date = models.DateTimeField('Flag date') flag_date = models.DateTimeField('Flag date')
bonus = models.PositiveSmallIntegerField(default=0)
class Meta: class Meta:
ordering = ['-flag_date'] ordering = ['-flag_date']

View File

@ -1,5 +1,5 @@
from django.contrib import admin from django.contrib import admin
from .models import Event, EventPlayer, Team from .models import Event, EventPlayer, Team, Bonus
@admin.register(Event) @admin.register(Event)
class event(admin.ModelAdmin): class event(admin.ModelAdmin):
@ -8,6 +8,27 @@ class event(admin.ModelAdmin):
# search list # search list
search_fields = ['name', 'slug', 'description', 'password'] search_fields = ['name', 'slug', 'description', 'password']
def get_queryset(self, request):
qs = super().get_queryset(request)
if request.user.is_superuser:
return qs
groups = list(request.user.groups.values_list('name', flat=True))
return qs.filter(name__in=groups)
def has_view_permission(self, request, obj=None):
if request.user.is_superuser:
return True
if obj is not None:
return request.user.groups.filter(name=obj.name).exists()
return super().has_view_permission(request, obj)
def has_change_permission(self, request, obj=None):
if request.user.is_superuser:
return True
if obj is not None:
return request.user.groups.filter(name=obj.name).exists()
return super().has_change_permission(request, obj)
@admin.register(EventPlayer) @admin.register(EventPlayer)
class score(admin.ModelAdmin): class score(admin.ModelAdmin):
#list display #list display
@ -17,7 +38,33 @@ class score(admin.ModelAdmin):
# search list # search list
search_fields = ['user__username', 'score', 'event__name'] search_fields = ['user__username', 'score', 'event__name']
# Register your models here. def get_queryset(self, request):
qs = super().get_queryset(request)
if request.user.is_superuser:
return qs
groups = list(request.user.groups.values_list('name', flat=True))
return qs.filter(event__name__in=groups)
def has_view_permission(self, request, obj=None):
if request.user.is_superuser:
return True
if obj is not None:
return request.user.groups.filter(name=obj.event.name).exists()
return super().has_view_permission(request, obj)
def has_change_permission(self, request, obj=None):
if request.user.is_superuser:
return True
if obj is not None:
return request.user.groups.filter(name=obj.event.name).exists()
return super().has_change_permission(request, obj)
def has_delete_permission(self, request, obj=None):
if request.user.is_superuser:
return True
if obj is not None:
return request.user.groups.filter(name=obj.event.name).exists()
return super().has_delete_permission(request, obj)
@admin.register(Team) @admin.register(Team)
class team(admin.ModelAdmin): class team(admin.ModelAdmin):
@ -27,3 +74,36 @@ class team(admin.ModelAdmin):
list_filter = ('event',) list_filter = ('event',)
# search list # search list
search_fields = ['name'] search_fields = ['name']
def get_queryset(self, request):
qs = super().get_queryset(request)
if request.user.is_superuser:
return qs
groups = list(request.user.groups.values_list('name', flat=True))
return qs.filter(event__name__in=groups)
def has_view_permission(self, request, obj=None):
if request.user.is_superuser:
return True
if obj is not None:
return request.user.groups.filter(name=obj.event.name).exists()
return super().has_view_permission(request, obj)
def has_change_permission(self, request, obj=None):
if request.user.is_superuser:
return True
if obj is not None:
return request.user.groups.filter(name=obj.event.name).exists()
return super().has_change_permission(request, obj)
def has_delete_permission(self, request, obj=None):
if request.user.is_superuser:
return True
if obj is not None:
return request.user.groups.filter(name=obj.event.name).exists()
return super().has_delete_permission(request, obj)
@admin.register(Bonus)
class bonus(admin.ModelAdmin):
#list display
list_display = ['points', 'absolute']

View File

@ -0,0 +1,28 @@
# Generated by Django 3.2.11 on 2023-09-17 17:00
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('events', '0010_event_campus'),
]
operations = [
migrations.CreateModel(
name='Bonus',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('absolute', models.BooleanField(default=True)),
('points', models.CharField(max_length=100, validators=[django.core.validators.int_list_validator])),
],
),
migrations.AddField(
model_name='event',
name='bonus',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='events.bonus'),
),
]

View File

@ -0,0 +1,24 @@
# Generated by Django 3.2.11 on 2023-09-17 18:38
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('events', '0011_bonus_points'),
]
operations = [
migrations.AlterField(
model_name='event',
name='bonus',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='events.bonus'),
),
migrations.AlterField(
model_name='eventplayer',
name='team',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='events.team'),
),
]

View File

@ -1,10 +1,17 @@
from django.db import models from django.db import models
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.auth.models import timezone from django.contrib.auth.models import timezone
from django.core.validators import int_list_validator
import uuid import uuid
from accounts.models import Campus from accounts.models import Campus
# Create your models here. # Create your models here.
class Bonus(models.Model):
absolute = models.BooleanField(default=True)
points = models.CharField(validators=[int_list_validator], max_length=100)
def __str__(self):
return self.points
class Event(models.Model): class Event(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=200) name = models.CharField(max_length=200)
@ -19,6 +26,7 @@ class Event(models.Model):
auto_match = models.BooleanField(default=False) auto_match = models.BooleanField(default=False)
dynamic = models.BooleanField(default=False) dynamic = models.BooleanField(default=False)
campus = models.ManyToManyField(Campus, blank=True) campus = models.ManyToManyField(Campus, blank=True)
bonus = models.ForeignKey(Bonus, null=True, on_delete=models.SET_NULL, blank=True)
def __str__(self): def __str__(self):
return self.name return self.name
@ -37,8 +45,6 @@ class EventPlayer(models.Model):
event = models.ForeignKey(Event, on_delete=models.CASCADE) event = models.ForeignKey(Event, on_delete=models.CASCADE)
score = models.PositiveIntegerField(default=0, db_index=True) score = models.PositiveIntegerField(default=0, db_index=True)
last_submission_date = models.DateTimeField('Last Submission Date', default=timezone.now) last_submission_date = models.DateTimeField('Last Submission Date', default=timezone.now)
team = models.ForeignKey(Team, on_delete=models.CASCADE, null=True) team = models.ForeignKey(Team, on_delete=models.CASCADE, null=True, blank=True)
class Meta: class Meta:
ordering = ['-score', 'last_submission_date', 'user__username'] ordering = ['-score', 'last_submission_date', 'user__username']

View File

@ -21,7 +21,10 @@
<div class="ctf-footer"> <div class="ctf-footer">
{% if request.user.is_authenticated %} {% if request.user.is_authenticated %}
{% if congrat == True %} {% if congrat == True %}
<p>{% trans "Congratulation !" %}</p> <p>{% trans "Congratulation !" %}</p>
{% if bonus|add:"0" > 0 %}
<p>{% trans "Bonus points awarded" %} : {{ bonus }}</p>
{% endif %}
{% elif alreadyflag == True %} {% elif alreadyflag == True %}
<p>{% trans "Already flagged" %}</p> <p>{% trans "Already flagged" %}</p>
{% elif eventisover == True %} {% elif eventisover == True %}
@ -96,6 +99,9 @@
<ul class="list-group"> <ul class="list-group">
<li class="list-group-item">{% trans "Author" %} : <a style="position:absolute;right: 15px;" class="profile_link {{is_member}}" href="{% url 'accounts:profile' user_name=ctf.author.username %}">{{ ctf.author.username }}</a></li> <li class="list-group-item">{% trans "Author" %} : <a style="position:absolute;right: 15px;" class="profile_link {{is_member}}" href="{% url 'accounts:profile' user_name=ctf.author.username %}">{{ ctf.author.username }}</a></li>
<li class="list-group-item">{% trans "Point reward" %} : <span style="position:absolute;right: 15px;">{{ ctf.points }}</span></li> <li class="list-group-item">{% trans "Point reward" %} : <span style="position:absolute;right: 15px;">{{ ctf.points }}</span></li>
{% if ctf.event.bonus %}
<li class="list-group-item">{% trans "Speed Bonuses" %} : <span style="position:absolute;right: 15px;">{{ bonus_points }}</span></li>
{% endif %}
</ul> </ul>
</div> </div>

View File

@ -26,7 +26,7 @@
{% endif %} {% endif %}
</div> </div>
<div class="event-footer"> <div class="event-footer">
{% if begun == True %} {% if begun == True or is_event_manager == True %}
<h4>{% trans "Challenges" %}</h4> <h4>{% trans "Challenges" %}</h4>
{% if ctfs %} {% if ctfs %}

View File

@ -22,6 +22,7 @@
<th scope="col">{% trans "Challenge Name" %}</th> <th scope="col">{% trans "Challenge Name" %}</th>
<th scope="col">{% trans "Category" %}</th> <th scope="col">{% trans "Category" %}</th>
<th scope="col">{% trans "Points" %}</th> <th scope="col">{% trans "Points" %}</th>
<th scope="col">{% trans "Bonus" %}</th>
<th scope="col">{% trans "Date" %}</th> <th scope="col">{% trans "Date" %}</th>
</tr> </tr>
</thead> </thead>
@ -31,6 +32,7 @@
<th scope="row"><a href="{% url 'events:event_chall_info' event_slug=event.slug chall_slug=s.ctf.slug %}">{{ s.ctf.name }}</a></th> <th scope="row"><a href="{% url 'events:event_chall_info' event_slug=event.slug chall_slug=s.ctf.slug %}">{{ s.ctf.name }}</a></th>
<td>{{ s.ctf.category.name}}</td> <td>{{ s.ctf.category.name}}</td>
<td>{{ s.ctf.points }}</td> <td>{{ s.ctf.points }}</td>
<td>{{ s.bonus }}</td>
<td>{{ s.flag_date|date:"Y-m-d H:i:s" }}</td> <td>{{ s.flag_date|date:"Y-m-d H:i:s" }}</td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@ -41,6 +41,31 @@ def actualize_points(ctf):
player.team.score -= diff player.team.score -= diff
player.team.save() player.team.save()
def compute_bonus_points(ctf):
if not ctf.event.bonus:
return 0
solves = CTF_flags.objects.filter(ctf=ctf)
bonuses = ctf.event.bonus.points.split(',')
if len(solves) >= len(bonuses):
return 0
else:
if ctf.event.bonus.absolute == True:
return int(bonuses[len(solves)])
else:
return int(bonuses[len(solves)]) * ctf.points // 100
def format_bonus_points(ctf):
if not ctf.event.bonus:
return None
bonuses = ctf.event.bonus.points.split(',')
if ctf.event.bonus.absolute == True:
return ''.join([b + ', ' for b in bonuses])[:-2]
return ''.join([str(ctf.points * int(b) // 100) + ', ' for b in bonuses])[:-2]
# Create your views here. # Create your views here.
def events(request): def events(request):
list_events = Event.objects.filter().order_by('-end_date', 'start_date') list_events = Event.objects.filter().order_by('-end_date', 'start_date')
@ -50,7 +75,8 @@ def chall_event_info(request, event_slug, chall_slug):
event_info = get_object_or_404(Event, slug=event_slug) event_info = get_object_or_404(Event, slug=event_slug)
ctf_info = get_object_or_404(CTF, event__slug=event_info.slug, slug=chall_slug) ctf_info = get_object_or_404(CTF, event__slug=event_info.slug, slug=chall_slug)
if timezone.now() < ctf_info.pub_date: is_event_manager = request.user.groups.filter(name=event_info.name).exists() or request.user.is_superuser
if timezone.now() < ctf_info.pub_date and not is_event_manager:
return redirect('events:event_info', event_slug=event_slug) return redirect('events:event_info', event_slug=event_slug)
eventisover = False eventisover = False
alreadyflag = False alreadyflag = False
@ -60,6 +86,7 @@ def chall_event_info(request, event_slug, chall_slug):
notsub = False notsub = False
noteam = False noteam = False
player = None player = None
bonus = 0
if request.user.is_authenticated and not request.user.is_staff: if request.user.is_authenticated and not request.user.is_staff:
player = EventPlayer.objects.filter(event=event_info, user=request.user) player = EventPlayer.objects.filter(event=event_info, user=request.user)
if not player: if not player:
@ -80,6 +107,8 @@ def chall_event_info(request, event_slug, chall_slug):
notsub = True notsub = True
if request.GET.get('NoTeam'): if request.GET.get('NoTeam'):
noteam = True noteam = True
bonus = request.GET.get('Bonus')
bonus_points = format_bonus_points(ctf_info)
solved_challs = CTF_flags.objects.filter(ctf=ctf_info).order_by('flag_date') solved_challs = CTF_flags.objects.filter(ctf=ctf_info).order_by('flag_date')
solved_list = [] solved_list = []
for s in solved_challs: for s in solved_challs:
@ -89,57 +118,59 @@ def chall_event_info(request, event_slug, chall_slug):
solved_list.append([s.user, s.flag_date]) solved_list.append([s.user, s.flag_date])
description = get_description_by_lang(ctf_info) description = get_description_by_lang(ctf_info)
return render(request, 'events/ctf_info.html', { 'ctf' : ctf_info, 'event':event_info, 'solved_list': solved_list, 'description': description, 'eventisover': eventisover, 'alreadyflag': alreadyflag, return render(request, 'events/ctf_info.html', { 'ctf' : ctf_info, 'event':event_info, 'solved_list': solved_list, 'description': description, 'eventisover': eventisover, 'alreadyflag': alreadyflag,
'congrat': congrat, 'wrongflag': wrongflag, 'errorform': errorform, 'notsub': notsub, 'noteam':noteam}) 'congrat': congrat, 'wrongflag': wrongflag, 'errorform': errorform, 'notsub': notsub, 'noteam':noteam, 'bonus':bonus, 'bonus_points':bonus_points})
def event(request, event_slug): def event(request, event_slug):
event_info = get_object_or_404(Event, slug=event_slug) event_info = get_object_or_404(Event, slug=event_slug)
IsRegistered = False
wrongpwd = False wrongpwd = False
alreadyregistered = False alreadyregistered = False
subisover = False subisover = False
is_event_manager = request.user.groups.filter(name=event_info.name).exists() or request.user.is_superuser
ended = (timezone.now() >= event_info.end_date)
begun = (timezone.now() >= event_info.start_date)
if is_event_manager: # we want to see all the challenges
challenges = CTF.objects.filter(event=event_info).order_by('category', 'points')
else:
challenges = CTF.objects.filter(event=event_info, pub_date__lte=timezone.now()).order_by('category', 'points')
if event_info.team_size == 1:
solved_list = EventPlayer.objects.filter(event=event_info).order_by('-score', 'last_submission_date', 'user__username')
else:
solved_list = Team.objects.filter(event=event_info).order_by('-score', 'last_submission_date', 'name')
if request.GET.get('WrongPassword'): if request.GET.get('WrongPassword'):
wrongpwd = True wrongpwd = True
if request.GET.get('AlreadyRegistered'): if request.GET.get('AlreadyRegistered'):
alreadyregistered = True alreadyregistered = True
if request.GET.get('SubscriptionIsOver'): if request.GET.get('SubscriptionIsOver'):
subisover = True subisover = True
if request.user.is_authenticated: if request.user.is_authenticated:
try: try:
player = EventPlayer.objects.get(event=event_info, user=request.user) EventPlayer.objects.get(event=event_info, user=request.user)
return render(request, 'events/event_info.html', {'event' : event_info, 'IsRegistered': True, 'ctfs': challenges, 'solved_list':solved_list,
'ended': ended, 'begun': begun, 'wrongpwd': wrongpwd, 'alreadyregistered': alreadyregistered, 'subisover': subisover, 'is_event_manager':is_event_manager})
except: except:
player = None pass
if player:
IsRegistered = True if (event_info.campus.all() or event_info.password) and request.user.is_authenticated is False:
if event_info.campus.all(): return render(request, 'events/event_pwd.html', {'event' : event_info, 'logged': False})
if request.user.is_authenticated:
if request.user.is_staff is False: if event_info.campus.all() and is_event_manager is False:
user = UserProfileInfo.objects.get(user=request.user) user = UserProfileInfo.objects.get(user=request.user)
if user.campus is None: if user.campus is None:
return render(request, 'events/event_pwd.html', {'event' : event_info, 'logged': True, 'wrongpwd': wrongpwd, 'alreadyregistered': alreadyregistered, 'userHasCampus': False, 'campusCanJoin': True}) return render(request, 'events/event_pwd.html', {'event' : event_info, 'logged': True, 'wrongpwd': wrongpwd, 'alreadyregistered': alreadyregistered, 'userHasCampus': False, 'campusCanJoin': True})
elif user.campus not in event_info.campus.all(): elif user.campus not in event_info.campus.all():
return render(request, 'events/event_pwd.html', {'event' : event_info, 'logged': True, 'wrongpwd': wrongpwd, 'alreadyregistered': alreadyregistered, 'userHasCampus': True, 'campusCanJoin': False}) return render(request, 'events/event_pwd.html', {'event' : event_info, 'logged': True, 'wrongpwd': wrongpwd, 'alreadyregistered': alreadyregistered, 'userHasCampus': True, 'campusCanJoin': False})
else:
return render(request, 'events/event_pwd.html', {'event' : event_info, 'logged': False, 'wrongpwd': wrongpwd, 'alreadyregistered': alreadyregistered, 'userHasCampus': True, 'campusCanJoin': True}) if event_info.password and is_event_manager is False:
if event_info.password: return render(request, 'events/event_pwd.html', {'event' : event_info, 'logged': True, 'wrongpwd': wrongpwd, 'alreadyregistered': alreadyregistered, 'userHasCampus': True, 'campusCanJoin': True})
if request.user.is_authenticated:
if request.user.is_staff is False: return render(request, 'events/event_info.html', {'event' : event_info, 'ctfs': challenges, 'solved_list':solved_list, 'IsRegistered': False,
if not player: 'ended': ended, 'begun': begun, 'wrongpwd': wrongpwd, 'alreadyregistered': alreadyregistered, 'subisover': subisover, 'is_event_manager':is_event_manager})
return render(request, 'events/event_pwd.html', {'event' : event_info, 'logged': True, 'wrongpwd': wrongpwd, 'alreadyregistered': alreadyregistered, 'userHasCampus': True, 'campusCanJoin': True})
else:
return render(request, 'events/event_pwd.html', {'event' : event_info, 'logged': False, 'wrongpwd': wrongpwd, 'alreadyregistered': alreadyregistered, 'userHasCampus': True, 'campusCanJoin': True})
ended = False
if timezone.now() >= event_info.end_date:
ended = True
begun = False
if timezone.now() >= event_info.start_date:
begun = True
challenges = CTF.objects.filter(event=event_info, pub_date__lte=timezone.now()).order_by('category', 'points')
if event_info.team_size == 1:
solved_list = EventPlayer.objects.filter(event=event_info).order_by('-score', 'last_submission_date', 'user__username')
else:
solved_list = Team.objects.filter(event=event_info).order_by('-score', 'last_submission_date', 'name')
return render(request, 'events/event_info.html', {'event' : event_info, 'IsRegistered': IsRegistered, 'ctfs': challenges, 'solved_list':solved_list,
'ended': ended, 'begun': begun, 'wrongpwd': wrongpwd, 'alreadyregistered': alreadyregistered, 'subisover': subisover})
@login_required @login_required
def submit_event_flag(request, event_slug, chall_slug): def submit_event_flag(request, event_slug, chall_slug):
@ -183,20 +214,21 @@ def submit_event_flag(request, event_slug, chall_slug):
if form.is_valid(): if form.is_valid():
if ctf_info.flag == request.POST.get('flag'): if ctf_info.flag == request.POST.get('flag'):
new = CTF_flags(user = request.user, ctf = ctf_info, flag_date = timezone.now()) bonus = compute_bonus_points(ctf_info)
new = CTF_flags(user = request.user, ctf = ctf_info, flag_date = timezone.now(), bonus = bonus)
new.save() new.save()
if ctf_info.points > 0: if ctf_info.points > 0:
player.last_submission_date = timezone.now() player.last_submission_date = timezone.now()
player.score += ctf_info.points player.score += (ctf_info.points + bonus)
player.save() player.save()
if player.team: if player.team:
if ctf_info.points > 0: if ctf_info.points > 0:
player.team.last_submission_date = timezone.now() player.team.last_submission_date = timezone.now()
player.team.score += ctf_info.points player.team.score += (ctf_info.points + bonus)
player.team.save() player.team.save()
if ev.dynamic: if ev.dynamic:
actualize_points(ctf_info) actualize_points(ctf_info)
response['Location'] += '?Congrat=1' response['Location'] += '?Congrat=1&Bonus=' + str(bonus)
return response return response
else: else:
response['Location'] += '?WrongFlag=1' response['Location'] += '?WrongFlag=1'
@ -278,7 +310,7 @@ def profile(request, user_name, event_slug):
percent = (solved_count / max_count) * 100 percent = (solved_count / max_count) * 100
catsDatas.append([cat.name, solved_count, max_count, '{:.0f}'.format(percent)]) catsDatas.append([cat.name, solved_count, max_count, '{:.0f}'.format(percent)])
for flag in solved: for flag in solved:
somme += flag.ctf.points somme += (flag.ctf.points + flag.bonus)
pointDatas[cat.name].append([flag.flag_date.timestamp() * 1000, somme]) pointDatas[cat.name].append([flag.flag_date.timestamp() * 1000, somme])
solves = CTF_flags.objects.filter(user=user_obj, ctf__event=event_info).order_by('-flag_date') solves = CTF_flags.objects.filter(user=user_obj, ctf__event=event_info).order_by('-flag_date')
@ -286,10 +318,10 @@ def profile(request, user_name, event_slug):
somme = 0 somme = 0
solved.append([event_info.start_date.timestamp() * 1000, 0]) solved.append([event_info.start_date.timestamp() * 1000, 0])
for s in solves.reverse(): for s in solves.reverse():
somme += s.ctf.points somme += (s.ctf.points + s.bonus)
solved.append([s.flag_date.timestamp() * 1000,somme]) solved.append([s.flag_date.timestamp() * 1000,somme])
return render(request,'events/profile.html', {'user':user_obj, 'solves':solves,'solved':solved,'catsDatas': catsDatas, 'pointDatas': pointDatas, return render(request,'events/profile.html', {'user':user_obj, 'solves':solves,'solved':solved,'catsDatas': catsDatas, 'pointDatas': pointDatas,
'rank': rank, 'score' : somme, 'cats':cats, 'event': event_info}) 'rank': rank, 'score' : player.score, 'cats':cats, 'event': event_info})

View File

@ -35,7 +35,6 @@ def home(request):
lang_code = request.session[LANGUAGE_SESSION_KEY] lang_code = request.session[LANGUAGE_SESSION_KEY]
url_translated = translate_url(request.path, lang_code) url_translated = translate_url(request.path, lang_code)
if request.path != url_translated: if request.path != url_translated:
print("%s\n%s" % (request.path, url_translated))
response = HttpResponseRedirect(url_translated) response = HttpResponseRedirect(url_translated)
return response return response
news = new.objects.order_by('-pub_date')[:5] news = new.objects.order_by('-pub_date')[:5]