diff --git a/CTFd/plugins/sport_challenges/__init__.py b/CTFd/plugins/sport_challenges/__init__.py index a7bcf07ac6c348804f14695e12f304d79851bcdb..a960c2ee209de32e83c647a07c50165069688f1b 100644 --- a/CTFd/plugins/sport_challenges/__init__.py +++ b/CTFd/plugins/sport_challenges/__init__.py @@ -24,6 +24,8 @@ class SportChallenge(Challenges): db.Integer, db.ForeignKey("challenges.id", ondelete="CASCADE"), primary_key=True ) max_points = db.Column(db.Integer, default=0) + unit = db.Column(db.String(32), default="km") #Unitées associées à l'activité + points = db.Column(db.Integer, default=0) def __init__(self, *args, **kwargs): super(SportChallenge, self).__init__(**kwargs) @@ -77,7 +79,9 @@ class SportValueChallenge(BaseChallenge): "category": challenge.category, "state": challenge.state, "max_points": challenge.max_points, + "unit": challenge.unit, "type": challenge.type, + "points": challenge.points, "type_data": { "id": cls.id, "name": cls.name, diff --git a/CTFd/themes/core-beta/assets/js/challenges.js b/CTFd/themes/core-beta/assets/js/challenges.js index 5b5dfff08b5e455e20166bea3243470e82672e71..602b28e7c773b06feb15a0f34e222419556aa91b 100644 --- a/CTFd/themes/core-beta/assets/js/challenges.js +++ b/CTFd/themes/core-beta/assets/js/challenges.js @@ -223,6 +223,7 @@ Alpine.data("Challenge", () => ({ }, async submitManualChallenge(type) { + alert(type); //dans le cas ou le user envoit des fichier if (!document.getElementById("file-input").hidden){ diff --git a/CTFd/themes/core-beta/templates/challenge.html b/CTFd/themes/core-beta/templates/challenge.html index 9e155c53fe7776cc7ce4ebb41aa2b5db0e47b494..d1d0e65af743620fc64699bcb172899924cb223b 100644 --- a/CTFd/themes/core-beta/templates/challenge.html +++ b/CTFd/themes/core-beta/templates/challenge.html @@ -246,7 +246,7 @@ </div> {% endif %} - {% if (not solved_by_me and attempts == 0) or ((max_attempts == 0 or max_attempts > attempts) and challenge.type == "manualRecursive") or ((max_attempts == 0 or max_attempts > attempts) and challenge.type == "standard" and not solved_by_me) or (challenge.type == "sport" and (points < max_points)) %} + {% if (not solved_by_me and attempts == 0) or ((max_attempts == 0 or max_attempts > attempts) and challenge.type == "manualRecursive") or ((max_attempts == 0 or max_attempts > attempts) and challenge.type == "standard" and not solved_by_me) or (challenge.type == "sport" and (challenge.max_points > challenge.points)) %} <div class="row submit-row"> <div class="col-12 col-sm-8 w-100"> {% block input %} @@ -261,6 +261,27 @@ @keyup.enter="submitChallenge()" placeholder="{% trans %}Flag{% endtrans %}" x-model="submission" > + {% elif challenge.type == "sport" %} + <input + id="challenge-id" class="challenge-id" type="hidden" + value="{{ challenge.id }}"> + {{challenge.unit}} + {{challenge.max_points}} + {{challenge.points}} + <input + id="challenge-input" + type="hidden"> + <h3 style="font-size: 1em!important; font-weight: bold;" id="soumettre-media-label">Soumettre un ou plusieurs médias</h3> + <label for="form-file-input-btn" id="file-input" style="display: flex;" class="btn btn-outline-secondary"> + Sélectionnez un fichier + </label> + + + <textarea id="text-input" style="display: flex; width: 100%;--bs-btn-hover-color:black;--bs-btn-hover-bg:white;--bs-btn-active-bg:white;" class="btn btn-outline-secondary" hidden></textarea> + <form id="form-file-input" > + <input id="form-file-input-btn" onchange="changeLabel(event)" class="challenge-input form-control" + type="file" name="file" multiple style="display: none;"> + </form> {% else %} <input id="challenge-id" class="challenge-id" type="hidden" @@ -324,6 +345,10 @@ <h3 class="challenge-value text-center"> Défi déjà complété! </h3> + {% elif attempts > 0 and challenge.type == "sport" %} + <h3 class="challenge-value text-center" style="display: flex; justify-content: center; align-items: center; width: 100%;"> + Vous avez déjà atteint la limite de points pour ce challenge. [{{challenge.points}}/{{challenge.max_points}}] + </h3> {% elif attempts > 0 and challenge.type != "standard" %} <h3 class="challenge-value text-center"> Défi soumis. Si vous êtes le propriétaire, vous pouvez le supprimer dans la section Équipe. Sinon, demandez à un admin ou à votre capitaine d'équipe ! diff --git a/migrations/versions/cf1a32af89a7_add_sportchallenge_class.py b/migrations/versions/cf1a32af89a7_add_sportchallenge_class.py new file mode 100644 index 0000000000000000000000000000000000000000..fde6020317833ac46070b3207aec55a115ae02f7 --- /dev/null +++ b/migrations/versions/cf1a32af89a7_add_sportchallenge_class.py @@ -0,0 +1,39 @@ +"""Add SportChallenge class + +Revision ID: cf1a32af89a7 +Revises: f27b6be89c67 +Create Date: 2024-11-12 15:57:58.814728 + +""" +from alembic import op +import sqlalchemy as sa + + + + +# revision identifiers, used by Alembic. +revision = 'cf1a32af89a7' +down_revision = 'f27b6be89c67' +branch_labels = None +depends_on = None + + +def upgrade(): + # op.create_table('sport_challenge', + # sa.Column('id', sa.Integer(), nullable=False), + # sa.ForeignKeyConstraint(['id'], ['challenges.id'], ondelete='CASCADE'), + # sa.PrimaryKeyConstraint('id') + # ) + op.create_table( + "sport_challenge", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("unit", sa.Integer(), nullable=True), + sa.Column("points", sa.Integer(), nullable=True), + sa.Column("category", sa.String(length=32), nullable=True), + sa.ForeignKeyConstraint(['id'], ['challenges.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + + +def downgrade(): + op.drop_table("sport_challenge") \ No newline at end of file