diff --git a/temp.py b/challenge/__init__.py similarity index 100% rename from temp.py rename to challenge/__init__.py diff --git a/challenge/admin.py b/challenge/admin.py new file mode 100644 index 000000000..f913d9b22 --- /dev/null +++ b/challenge/admin.py @@ -0,0 +1,16 @@ +from django.contrib import admin +from .models import Challenge, UserChallenge +# Register your models here. + +@admin.register(Challenge) +class ChallengeAdmin(admin.ModelAdmin): + list_display = ('name', 'docker_image', 'start_port', 'end_port', 'point') + search_fields = ('name', 'docker_image') + empty_value_display = '-empty-' + + +@admin.register(UserChallenge) +class UserChallengeAdmin(admin.ModelAdmin): + list_display = ('user', 'challenge', 'container_id', 'port', 'no_of_attempt', 'is_solved') + search_fields = ('user__username', 'challenge__name') + empty_value_display = '-empty-' \ No newline at end of file diff --git a/challenge/apps.py b/challenge/apps.py new file mode 100644 index 000000000..ad63d6650 --- /dev/null +++ b/challenge/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class ChallengeConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'challenge' diff --git a/challenge/challenge.json b/challenge/challenge.json new file mode 100644 index 000000000..b92c182af --- /dev/null +++ b/challenge/challenge.json @@ -0,0 +1,12 @@ +[ + { + "name":"do-it-fast", + "description":"You want flag ?\nThis webside gives you ?\nyeah, just need to login and grab fast", + "docker_image": "rupak2001/do-it-fast", + "docker_port": 5050, + "start_port" : 5000, + "end_port" : 5500, + "flag": "flag{do_it_fast}", + "point" : 100 + } +] \ No newline at end of file diff --git a/challenge/management/commands/populate_challenge.py b/challenge/management/commands/populate_challenge.py new file mode 100644 index 000000000..62ab6330d --- /dev/null +++ b/challenge/management/commands/populate_challenge.py @@ -0,0 +1,22 @@ +import json +from django.core.management.base import BaseCommand, CommandError +from challenge.models import Challenge + + +class Command(BaseCommand): + help = "Populates the database with some test data" + + def handle(self, *args, **options): + try: + filename = "challenge/challenge.json" + with open(filename, "r") as f: + data = json.load(f) + for challenge in data: + try: + Challenge.objects.create(**challenge).save() + except: + pass + except FileNotFoundError: + raise CommandError("File not found: {}".format(filename)) + + diff --git a/challenge/migrations/0001_initial.py b/challenge/migrations/0001_initial.py new file mode 100644 index 000000000..16e775aa2 --- /dev/null +++ b/challenge/migrations/0001_initial.py @@ -0,0 +1,47 @@ +# Generated by Django 4.0.4 on 2023-03-03 06:33 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Challenge', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100)), + ('description', models.TextField()), + ('docker_image', models.CharField(max_length=100)), + ('start_port', models.IntegerField()), + ('end_port', models.IntegerField()), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('flag', models.CharField(max_length=100)), + ('point', models.IntegerField()), + ], + ), + migrations.CreateModel( + name='UserChallenge', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('container_id', models.CharField(max_length=100)), + ('port', models.IntegerField()), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('is_live', models.BooleanField(default=False)), + ('no_of_attempt', models.IntegerField(default=0)), + ('is_solved', models.BooleanField(default=False)), + ('challenge', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='challenge.challenge')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/challenge/migrations/0002_challenge_docker_port.py b/challenge/migrations/0002_challenge_docker_port.py new file mode 100644 index 000000000..bf8fb3aee --- /dev/null +++ b/challenge/migrations/0002_challenge_docker_port.py @@ -0,0 +1,19 @@ +# Generated by Django 4.0.4 on 2023-03-03 06:45 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('challenge', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='challenge', + name='docker_port', + field=models.IntegerField(default=8000), + preserve_default=False, + ), + ] diff --git a/challenge/migrations/0003_alter_challenge_docker_image_alter_challenge_id_and_more.py b/challenge/migrations/0003_alter_challenge_docker_image_alter_challenge_id_and_more.py new file mode 100644 index 000000000..79c7e8164 --- /dev/null +++ b/challenge/migrations/0003_alter_challenge_docker_image_alter_challenge_id_and_more.py @@ -0,0 +1,28 @@ +# Generated by Django 4.0.4 on 2023-03-03 12:11 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('challenge', '0002_challenge_docker_port'), + ] + + operations = [ + migrations.AlterField( + model_name='challenge', + name='docker_image', + field=models.CharField(max_length=100, unique=True), + ), + migrations.AlterField( + model_name='challenge', + name='id', + field=models.AutoField(primary_key=True, serialize=False, unique=True), + ), + migrations.AlterField( + model_name='challenge', + name='name', + field=models.CharField(max_length=100, unique=True), + ), + ] diff --git a/challenge/migrations/__init__.py b/challenge/migrations/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/challenge/models.py b/challenge/models.py new file mode 100644 index 000000000..95442f220 --- /dev/null +++ b/challenge/models.py @@ -0,0 +1,46 @@ +from django.db import models +from django.contrib.auth.models import User + +# Create your models here +class Challenge(models.Model): + id = models.AutoField(primary_key=True, unique=True) + name = models.CharField(max_length=100, unique=True) + description = models.TextField() + docker_image = models.CharField(max_length=100, unique=True) + docker_port = models.IntegerField() + start_port = models.IntegerField() + end_port = models.IntegerField() + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + flag = models.CharField(max_length=100) + point = models.IntegerField() + + def __str__(self): + return self.name + + # overwriting default save method + def save(self, *args, **kwargs): + if self.start_port > self.end_port: + raise Exception("Start port should be less than end port") + # Here flag need to be hashed + super(Challenge, self).save(*args, **kwargs) + +class UserChallenge(models.Model): + """ + This is a mapping of user to challenge with proper progress tracking + This also allows us to reuse the created container for the user + """ + id = models.AutoField(primary_key=True) + user = models.ForeignKey(User, on_delete=models.CASCADE) + challenge = models.ForeignKey(Challenge, on_delete=models.CASCADE) + container_id = models.CharField(max_length=100) + port = models.IntegerField() + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + is_live = models.BooleanField(default=False) + no_of_attempt = models.IntegerField(default=0) + is_solved = models.BooleanField(default=False) + port = models.IntegerField() + + def __str__(self): + return f"{self.user.username} - {self.challenge.name}" \ No newline at end of file diff --git a/challenge/templates/chal-not-found.html b/challenge/templates/chal-not-found.html new file mode 100644 index 000000000..1bacba43b --- /dev/null +++ b/challenge/templates/chal-not-found.html @@ -0,0 +1,8 @@ +{% extends "introduction/base.html" %} +{% block content %} +
{{ chal.description }}+