From 06dc8188a0f8138c4b084f6ceabc279c7a26b53c Mon Sep 17 00:00:00 2001 From: ix <0x00fi@protonmail.com> Date: Thu, 21 Oct 2021 15:02:02 +0200 Subject: [PATCH] events added, need to smooth html and css --- src/accounts/admin.py | 9 +- src/accounts/views/views.py | 8 +- src/ctfs/admin.py | 21 ++- src/ctfs/migrations/0005_ctf_event.py | 20 +++ src/ctfs/migrations/0006_alter_ctf_event.py | 20 +++ src/ctfs/models.py | 4 +- src/ctfs/templates/ctfs/ctf_info.html | 108 ++++++------- src/ctfs/views.py | 22 +-- src/events/__init__.py | 0 src/events/admin.py | 23 +++ src/events/apps.py | 6 + src/events/forms.py | 4 + src/events/migrations/0001_initial.py | 46 ++++++ .../migrations/0002_alter_event_password.py | 18 +++ .../migrations/0003_auto_20211019_1519.py | 26 ++++ src/events/migrations/__init__.py | 0 src/events/models.py | 26 ++++ src/events/templates/events/ctf_info.html | 87 +++++++++++ src/events/templates/events/event_info.html | 96 ++++++++++++ src/events/templates/events/event_pwd.html | 37 +++++ src/events/templates/events/events_list.html | 47 ++++++ src/events/templatetags/__init__.py | 0 src/events/templatetags/is_flagged.py | 10 ++ src/events/tests.py | 3 + src/events/urls.py | 13 ++ src/events/views.py | 143 ++++++++++++++++++ src/home/views.py | 2 +- src/project/settings.py | 1 + src/project/urls.py | 3 +- .../templates/scoreboard/scoreboard.html | 62 ++++---- src/static/css/style.css | 2 +- src/statics/css/style.css | 22 ++- src/templates/base.html | 143 +++++++++--------- 33 files changed, 851 insertions(+), 181 deletions(-) create mode 100644 src/ctfs/migrations/0005_ctf_event.py create mode 100644 src/ctfs/migrations/0006_alter_ctf_event.py create mode 100644 src/events/__init__.py create mode 100644 src/events/admin.py create mode 100644 src/events/apps.py create mode 100644 src/events/forms.py create mode 100644 src/events/migrations/0001_initial.py create mode 100644 src/events/migrations/0002_alter_event_password.py create mode 100644 src/events/migrations/0003_auto_20211019_1519.py create mode 100644 src/events/migrations/__init__.py create mode 100644 src/events/models.py create mode 100644 src/events/templates/events/ctf_info.html create mode 100644 src/events/templates/events/event_info.html create mode 100644 src/events/templates/events/event_pwd.html create mode 100755 src/events/templates/events/events_list.html create mode 100644 src/events/templatetags/__init__.py create mode 100644 src/events/templatetags/is_flagged.py create mode 100644 src/events/tests.py create mode 100644 src/events/urls.py create mode 100644 src/events/views.py diff --git a/src/accounts/admin.py b/src/accounts/admin.py index 930ef46..e1fbd9b 100644 --- a/src/accounts/admin.py +++ b/src/accounts/admin.py @@ -1,5 +1,12 @@ from .models import UserProfileInfo from django.contrib import admin -admin.site.register(UserProfileInfo) +#admin.site.register(UserProfileInfo) # Register your models here. + +@admin.register(UserProfileInfo) +class userprofile(admin.ModelAdmin): + #list display + list_display = ['user', 'score', 'last_submission_date'] + # search list + search_fields = ['score', 'user__username'] \ No newline at end of file diff --git a/src/accounts/views/views.py b/src/accounts/views/views.py index 9ad51bf..af6cde5 100644 --- a/src/accounts/views/views.py +++ b/src/accounts/views/views.py @@ -121,11 +121,11 @@ def profile(request, user_name): for cat in cats: # prepare categories - solved_count = CTF_flags.objects.filter(user=user_obj, ctf__category__name=cat.name).count() - max_count = CTF.objects.filter(category__name=cat.name).count() + solved_count = CTF_flags.objects.filter(user=user_obj, ctf__event=None , ctf__category__name=cat.name).count() + max_count = CTF.objects.filter(category__name=cat.name, event=None).count() # get datas somme = 0 - solved = CTF_flags.objects.filter(user=user_obj, ctf__category__name=cat.name).order_by('flag_date') + solved = CTF_flags.objects.filter(user=user_obj, ctf__category__name=cat.name, ctf__event=None).order_by('flag_date') pointDatas[cat.name] = [] pointDatas[cat.name].append([user_obj.date_joined.timestamp() * 1000, 0]) percent = (solved_count / max_count) * 100 @@ -134,7 +134,7 @@ def profile(request, user_name): somme += flag.ctf.points pointDatas[cat.name].append([flag.flag_date.timestamp() * 1000, somme]) - solves = CTF_flags.objects.filter(user=user_obj).order_by('-flag_date') + solves = CTF_flags.objects.filter(user=user_obj, ctf__event=None).order_by('-flag_date') solved = [] somme = 0 solved.append([user_obj.date_joined.timestamp() * 1000, 0]) diff --git a/src/ctfs/admin.py b/src/ctfs/admin.py index 83af521..c563116 100644 --- a/src/ctfs/admin.py +++ b/src/ctfs/admin.py @@ -2,7 +2,24 @@ from django.contrib import admin from .models import Category, CTF, CTF_flags admin.site.register(Category) -admin.site.register(CTF) -admin.site.register(CTF_flags) +#admin.site.register(CTF) +#admin.site.register(CTF_flags) +@admin.register(CTF_flags) +class ctf_flags(admin.ModelAdmin): + #list display + list_display = ['user', 'ctf', 'flag_date'] + #list Filter + list_filter = ('ctf__category', 'ctf', 'user','flag_date') + # search list + search_fields = ['ctf__category__name', 'ctf__name', 'user__username'] + +@admin.register(CTF) +class ctf(admin.ModelAdmin): + #list display + list_display = ['name', 'event', 'category'] + #list Filter + list_filter = ('category', 'event') + # search list + search_fields = ['category__name', 'name', 'author__username'] # Register your models here. diff --git a/src/ctfs/migrations/0005_ctf_event.py b/src/ctfs/migrations/0005_ctf_event.py new file mode 100644 index 0000000..5dd4c8b --- /dev/null +++ b/src/ctfs/migrations/0005_ctf_event.py @@ -0,0 +1,20 @@ +# Generated by Django 3.2.7 on 2021-10-18 14:23 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('events', '0001_initial'), + ('ctfs', '0004_auto_20210907_1407'), + ] + + operations = [ + migrations.AddField( + model_name='ctf', + name='event', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='events.event'), + ), + ] diff --git a/src/ctfs/migrations/0006_alter_ctf_event.py b/src/ctfs/migrations/0006_alter_ctf_event.py new file mode 100644 index 0000000..5651dda --- /dev/null +++ b/src/ctfs/migrations/0006_alter_ctf_event.py @@ -0,0 +1,20 @@ +# Generated by Django 3.2.7 on 2021-10-19 15:03 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('events', '0002_alter_event_password'), + ('ctfs', '0005_ctf_event'), + ] + + operations = [ + migrations.AlterField( + model_name='ctf', + name='event', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='events.event'), + ), + ] diff --git a/src/ctfs/models.py b/src/ctfs/models.py index 4958f77..6f49ca7 100644 --- a/src/ctfs/models.py +++ b/src/ctfs/models.py @@ -1,5 +1,6 @@ from django.db import models from django.contrib.auth.models import User +from events.models import Event class Category(models.Model): name = models.CharField(max_length=200) @@ -17,6 +18,7 @@ class CTF(models.Model): description_de = models.TextField(blank=True) file = models.FileField(blank=True, upload_to='challenges') ctf_url = models.URLField(blank=True) + event = models.ForeignKey(Event, null=True, blank=True, on_delete=models.CASCADE) points = models.PositiveSmallIntegerField() slug = models.SlugField(max_length=55) pub_date = models.DateTimeField('Date published') @@ -25,7 +27,7 @@ class CTF(models.Model): on_delete=models.SET_NULL, null=True, ) - author = models.ForeignKey(User, unique=False, on_delete=models.CASCADE) + author = models.ForeignKey(User, unique=False, on_delete=models.CASCADE) def solved_by(self, user): """True if the exercise has been solved by the user.""" if not user.is_authenticated: diff --git a/src/ctfs/templates/ctfs/ctf_info.html b/src/ctfs/templates/ctfs/ctf_info.html index 4d08e8b..228d7a1 100644 --- a/src/ctfs/templates/ctfs/ctf_info.html +++ b/src/ctfs/templates/ctfs/ctf_info.html @@ -6,79 +6,79 @@
{% trans "Username" %} | -{% trans "Website" %} | -{% trans "Score" %} | -{% trans "Date" %} | +{% trans "Username" %} | +{% trans "Website" %} | +{% trans "Score" %} | +{% trans "Date" %} |
---|---|---|---|---|---|---|---|
{{ s.user.username }} | -{{ s.user.userprofileinfo.portfolio_site }} | -{{ s.user.userprofileinfo.score }} | -{{ s.flag_date }} | + {% for s in solved_list %} +||||
{{ s.user.username }} | +{{ s.user.userprofileinfo.portfolio_site }} | +{{ s.user.userprofileinfo.score }} | +{{ s.flag_date }} |
{% trans "Nobody have solved this CTF." %}
- {% endif %} + {% else %} +{% trans "Nobody have solved this CTF." %}
+ {% endif %} {% endblock %} diff --git a/src/ctfs/views.py b/src/ctfs/views.py index 0b0c1b3..7f15c08 100644 --- a/src/ctfs/views.py +++ b/src/ctfs/views.py @@ -21,10 +21,10 @@ def get_description_by_lang(ctf): def category(request, cat_slug): cat = get_object_or_404(Category, slug=cat_slug) - ctfs = CTF.objects.filter(category=cat).order_by('points') + ctfs = CTF.objects.filter(category=cat, event=None).order_by('points') for ex in ctfs: - ex.solved_num = CTF_flags.objects.filter(ctf=ex).count() - ex.solved = ex.solved_by(request.user) + ex.solved_num = CTF_flags.objects.filter(ctf=ex).count() + ex.solved = ex.solved_by(request.user) return render(request, 'ctfs/ctfs_list.html', {'ctfs' : ctfs, 'cat' : cat}) def ctf(request, cat_slug, ctf_slug): @@ -46,18 +46,12 @@ def ctf(request, cat_slug, ctf_slug): profil.last_submission_date = timezone.now() profil.score += ctf_info.points profil.save() - return render(request, 'ctfs/ctf_info.html', {'form' : form, 'ctf' : ctf_info, 'solved_list': solved_list, 'valitated': True, 'description': description}) + return render(request, 'ctfs/ctf_info.html', { 'ctf' : ctf_info, 'solved_list': solved_list, 'valitated': True, 'description': description}) else: - return render(request, 'ctfs/ctf_info.html', {'form' : form, 'ctf' : ctf_info, 'solved_list': solved_list, 'failed': True, 'description': description}) + return render(request, 'ctfs/ctf_info.html', { 'ctf' : ctf_info, 'solved_list': solved_list, 'failed': True, 'description': description}) else: - form = submit_flag() - return render(request, 'ctfs/ctf_info.html', {'form' : form, 'ctf' : ctf_info, 'solved_list': solved_list, 'alvalitated': True, 'description': description}) + return render(request, 'ctfs/ctf_info.html', { 'ctf' : ctf_info, 'solved_list': solved_list, 'alvalitated': True, 'description': description}) else: - form = submit_flag() - return render(request, 'ctfs/ctf_info.html', {'form' : form, 'ctf' : ctf_info, 'solved_list': solved_list, 'description': description}) + return render(request, 'ctfs/ctf_info.html', { 'ctf' : ctf_info, 'solved_list': solved_list, 'description': description}) else: - form = submit_flag() - return render(request, 'ctfs/ctf_info.html', {'form' : form, 'ctf' : ctf_info, 'solved_list': solved_list, 'alvalitated': flagged, 'description': description}) - - -# Create your views here. + return render(request, 'ctfs/ctf_info.html', { 'ctf' : ctf_info, 'solved_list': solved_list, 'alvalitated': flagged, 'description': description}) diff --git a/src/events/__init__.py b/src/events/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/events/admin.py b/src/events/admin.py new file mode 100644 index 0000000..77ae37b --- /dev/null +++ b/src/events/admin.py @@ -0,0 +1,23 @@ +from django.contrib import admin +from .models import Event, Scores + +#admin.site.register(Event) +#admin.site.register(Scores) + +@admin.register(Event) +class event(admin.ModelAdmin): + #list display + list_display = ['name', 'start_date', 'end_date'] + # search list + search_fields = ['name', 'slug', 'description', 'password'] + +@admin.register(Scores) +class score(admin.ModelAdmin): + #list display + list_display = ['user', 'event', 'score'] + #list Filter + list_filter = ('event',) + # search list + search_fields = ['user__username', 'score', 'event__name'] + +# Register your models here. diff --git a/src/events/apps.py b/src/events/apps.py new file mode 100644 index 0000000..20f48f2 --- /dev/null +++ b/src/events/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class EventsConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'events' diff --git a/src/events/forms.py b/src/events/forms.py new file mode 100644 index 0000000..acdc47e --- /dev/null +++ b/src/events/forms.py @@ -0,0 +1,4 @@ +from django import forms + +class submit_flag(forms.Form): + flag = forms.CharField(label="Flag", max_length=100) diff --git a/src/events/migrations/0001_initial.py b/src/events/migrations/0001_initial.py new file mode 100644 index 0000000..84126c6 --- /dev/null +++ b/src/events/migrations/0001_initial.py @@ -0,0 +1,46 @@ +# Generated by Django 3.2.7 on 2021-10-18 14:19 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone +import uuid + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Event', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('name', models.CharField(max_length=200)), + ('logo', models.CharField(max_length=200)), + ('img', models.CharField(max_length=200)), + ('description', models.TextField()), + ('start_date', models.DateTimeField()), + ('end_date', models.DateTimeField()), + ('password', models.CharField(max_length=200)), + ('slug', models.SlugField(max_length=55)), + ], + ), + migrations.CreateModel( + name='Scores', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('score', models.PositiveIntegerField(db_index=True, default=0)), + ('last_submission_date', models.DateTimeField(default=django.utils.timezone.now, verbose_name='Last Submission Date')), + ('event', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='events.event')), + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'ordering': ['-score', 'last_submission_date', 'user__username'], + }, + ), + ] diff --git a/src/events/migrations/0002_alter_event_password.py b/src/events/migrations/0002_alter_event_password.py new file mode 100644 index 0000000..3216874 --- /dev/null +++ b/src/events/migrations/0002_alter_event_password.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.7 on 2021-10-18 14:43 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('events', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='event', + name='password', + field=models.CharField(blank=True, max_length=200), + ), + ] diff --git a/src/events/migrations/0003_auto_20211019_1519.py b/src/events/migrations/0003_auto_20211019_1519.py new file mode 100644 index 0000000..3ee71f7 --- /dev/null +++ b/src/events/migrations/0003_auto_20211019_1519.py @@ -0,0 +1,26 @@ +# Generated by Django 3.2.7 on 2021-10-19 15:19 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('events', '0002_alter_event_password'), + ] + + operations = [ + migrations.AlterField( + model_name='scores', + name='event', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='events.event'), + ), + migrations.AlterField( + model_name='scores', + name='user', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/src/events/migrations/__init__.py b/src/events/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/events/models.py b/src/events/models.py new file mode 100644 index 0000000..ea8edea --- /dev/null +++ b/src/events/models.py @@ -0,0 +1,26 @@ +from django.db import models +from django.contrib.auth.models import User +from django.contrib.auth.models import timezone +import uuid + +# Create your models here. +class Event(models.Model): + id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) + name = models.CharField(max_length=200) + logo = models.CharField(max_length=200) + img = models.CharField(max_length=200) + description = models.TextField() + start_date = models.DateTimeField() + end_date = models.DateTimeField() + password = models.CharField(max_length=200, blank=True) + slug = models.SlugField(max_length=55) + def __str__(self): + return self.name + +class Scores(models.Model): + user = models.ForeignKey(User, on_delete=models.CASCADE) + event = models.ForeignKey(Event, on_delete=models.CASCADE) + score = models.PositiveIntegerField(default=0, db_index=True) + last_submission_date = models.DateTimeField('Last Submission Date', default=timezone.now) + class Meta: + ordering = ['-score', 'last_submission_date', 'user__username'] \ No newline at end of file diff --git a/src/events/templates/events/ctf_info.html b/src/events/templates/events/ctf_info.html new file mode 100644 index 0000000..08c1900 --- /dev/null +++ b/src/events/templates/events/ctf_info.html @@ -0,0 +1,87 @@ +{% extends 'base.html' %} +{% block content %} +{% load i18n %} +{% trans "Username" %} | +{% trans "Website" %} | +{% trans "Score" %} | +{% trans "Date" %} | +
---|---|---|---|
{{ s.user.username }} | +{{ s.user.userprofileinfo.portfolio_site }} | +{{ s.user.userprofileinfo.score }} | +{{ s.flag_date }} | +
{% trans "Nobody have solved this CTF." %}
+ {% endif %} +{% trans "Rank" %} | +{% trans "Username" %} | +{% trans "Website" %} | +{% trans "Score" %} | +
---|---|---|---|
# {{ forloop.counter0|add:1 }} | ++ {{ s.user.username }} + | +{{ s.user.userprofileinfo.site }} | +{{ s.score }} | +
{% trans "Nobody have solved this CTF." %}
+ {% endif %} ++ Some quick example text to build on the card title and make up the bulk of the + card's content. +
+{% trans "No events available." %}
+ {% endif %} +{% trans "Rank" %} | +{% trans "Rank" %} | {% trans "Username" %} | {% trans "Website" %} | {% trans "Score" %} |
---|---|---|---|---|
# {{ forloop.counter0|add:scores.start_index }} | -{{ s.user.username }} | -- {% if s.user.userprofileinfo.portfolio_site %} - {{ s.user.userprofileinfo.portfolio_site }} - {% endif %} - | -{{ s.user.userprofileinfo.score }} | + {% for s in scores %} +|
# {{ forloop.counter0|add:scores.start_index }} | +{{ s.user.username }} | ++ {% if s.user.userprofileinfo.portfolio_site %} + {{ s.user.userprofileinfo.portfolio_site }} + {% endif %} + | +{{ s.user.userprofileinfo.score }} |