diff --git a/source/apps/ctf/admin.py b/source/apps/ctf/admin.py index 8c38f3f..5a74873 100644 --- a/source/apps/ctf/admin.py +++ b/source/apps/ctf/admin.py @@ -1,3 +1,17 @@ from django.contrib import admin -# Register your models here. +from source.apps.ctf import models + + +@admin.register(models.Team) +class TeamAdmin(admin.ModelAdmin): + list_display = ("id", "name") + +@admin.register(models.Flag) +class FlagAdmin(admin.ModelAdmin): + list_display = ("id", "name", "type") + + +@admin.register(models.Hint) +class HintAdmin(admin.ModelAdmin): + list_display = ("id", "flag") diff --git a/source/apps/ctf/apps.py b/source/apps/ctf/apps.py index 72da749..a24299d 100644 --- a/source/apps/ctf/apps.py +++ b/source/apps/ctf/apps.py @@ -3,4 +3,4 @@ from django.apps import AppConfig class CtfConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' - name = 'apps.ctf' + name = 'source.apps.ctf' diff --git a/source/apps/ctf/forms.py b/source/apps/ctf/forms.py new file mode 100644 index 0000000..b059663 --- /dev/null +++ b/source/apps/ctf/forms.py @@ -0,0 +1,9 @@ +from django import forms + + +class TeamForm(forms.Form): + name = forms.CharField(label="Team's name", max_length=32) + + +class FlagForm(forms.Form): + name = forms.UUIDField(label="Identifier", max_length=32) diff --git a/source/apps/ctf/models.py b/source/apps/ctf/models.py index 71a8362..9c0c276 100644 --- a/source/apps/ctf/models.py +++ b/source/apps/ctf/models.py @@ -1,3 +1,65 @@ +import uuid + from django.db import models -# Create your models here. + +class Team(models.Model): + """ + Represent a team participating in the event + """ + + id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) + name = models.CharField(max_length=32) + + validated_flags = models.ManyToManyField(to="Flag", blank=True, related_name="validated_by_teams") + + def __str__(self): + return f"<{self.__class__.__name__}({self.name!r}, {self.id!r})>" + + +class Flag(models.Model): + """ + Represent a flag that can be validated by the team + """ + + class FlagType(models.IntegerChoices): + NORMAL = 0 + BONUS = 1 + MALUS = 2 + + id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) + + # the flag might depend on other flags + parents = models.ManyToManyField( + "self", + blank=True, + symmetrical=False, + related_name="children", + ) + + # information about the flags + # TODO(Faraphel): store code as hash ? + code = models.CharField(max_length=32) # the password that must be given to obtain the flag + name = models.CharField(max_length=32) # the name of the flag + description = models.TextField() # the description on how to obtain the flag + + # TODO(Faraphel): replace with or add a points amount you gain ? + type = models.IntegerField(choices=FlagType.choices, default=FlagType.NORMAL) + + def __str__(self): + return f"<{self.__class__.__name__}({self.name!r}, {self.id!r})>" + + +class Hint(models.Model): + """ + Represent a hint that can be given to a team + """ + + id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) + importance = models.PositiveIntegerField() + description = models.TextField() + penalty = models.PositiveIntegerField() + flag = models.ForeignKey(to=Flag, on_delete=models.CASCADE, related_name="hints") + + def __str__(self): + return f"<{self.__class__.__name__}({self.flag.name!r}, {self.id!r})>" diff --git a/source/apps/ctf/templates/ctf/base/base.html b/source/apps/ctf/templates/ctf/base/base.html index 35ddc74..8ebfeb3 100644 --- a/source/apps/ctf/templates/ctf/base/base.html +++ b/source/apps/ctf/templates/ctf/base/base.html @@ -2,6 +2,7 @@
+