feat: First commit
This commit is contained in:
41
__init__.py
Normal file
41
__init__.py
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
from flask import render_template, Blueprint
|
||||||
|
from flask import request
|
||||||
|
|
||||||
|
from .models import CheaterTeams
|
||||||
|
from . import globals
|
||||||
|
|
||||||
|
from CTFd.plugins.migrations import upgrade
|
||||||
|
from CTFd.utils.decorators import admins_only
|
||||||
|
from CTFd.models import db
|
||||||
|
|
||||||
|
PLUGIN_PATH = os.path.dirname(__file__)
|
||||||
|
|
||||||
|
directory_name = PLUGIN_PATH.split(os.sep)[-1] # Get the directory name of this file
|
||||||
|
|
||||||
|
bp = Blueprint(directory_name, __name__, template_folder="templates")
|
||||||
|
|
||||||
|
|
||||||
|
def add_cheater(challenge_id: int, cheater_id: int, helper_id: int, flag: str):
|
||||||
|
cheater = CheaterTeams(challenge_id, cheater_id, helper_id, flag)
|
||||||
|
db.session.add(cheater)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/admin/cheaters", methods=["GET"])
|
||||||
|
@admins_only
|
||||||
|
def show_cheaters():
|
||||||
|
if request.method == "GET":
|
||||||
|
cheaters = CheaterTeams.query.all()
|
||||||
|
return render_template("cheaters.html", cheaters=cheaters)
|
||||||
|
|
||||||
|
|
||||||
|
def load(app):
|
||||||
|
globals.initialize()
|
||||||
|
app.db.create_all()
|
||||||
|
upgrade(plugin_name="cheaters")
|
||||||
|
|
||||||
|
app.register_blueprint(bp)
|
||||||
|
|
||||||
|
load_hooks()
|
||||||
42
models.py
Normal file
42
models.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
from CTFd.models import db
|
||||||
|
|
||||||
|
|
||||||
|
class CheaterTeams(db.Model):
|
||||||
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
|
challenge_id = db.Column(
|
||||||
|
db.Integer, db.ForeignKey("challenges.id", ondelete="CASCADE")
|
||||||
|
)
|
||||||
|
cheater_id = db.Column(db.Integer, db.ForeignKey("users.id", ondelete="CASCADE"))
|
||||||
|
helper_id = db.Column(db.Integer, db.ForeignKey("users.id", ondelete="CASCADE"))
|
||||||
|
|
||||||
|
flag = db.Column(db.String(128), nullable=False)
|
||||||
|
date = db.Column(db.DateTime, default=db.func.current_timestamp())
|
||||||
|
|
||||||
|
# Relationships
|
||||||
|
cheater = db.relationship(
|
||||||
|
"Users", foreign_keys="CheaterTeams.cheater_id", lazy="select"
|
||||||
|
)
|
||||||
|
helper = db.relationship(
|
||||||
|
"Users", foreign_keys="CheaterTeams.helper_id", lazy="select"
|
||||||
|
)
|
||||||
|
|
||||||
|
challenge = db.relationship(
|
||||||
|
"BaseChallenge",
|
||||||
|
foreign_keys="CheaterTeams.challenge_id",
|
||||||
|
lazy="select",
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(self, challenge_id: int, cheater_id: int, helper_id: int, flag: str):
|
||||||
|
self.challenge_id = challenge_id
|
||||||
|
self.cheater_id = cheater_id
|
||||||
|
self.helper_id = helper_id
|
||||||
|
self.flag = flag
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "<CheaterTeams User {0} maybe cheated for challenge {1} with the flag {2} belonging to the User {3} at {4} >".format(
|
||||||
|
self.cheater_id,
|
||||||
|
self.challenge_id,
|
||||||
|
self.flag,
|
||||||
|
self.helper_id,
|
||||||
|
self.date,
|
||||||
|
)
|
||||||
5
pyrightconfig.json
Normal file
5
pyrightconfig.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"include": ["."],
|
||||||
|
"extraPaths": ["/home/matteo/Gitted/CTFd"],
|
||||||
|
"reportMissingImports": true
|
||||||
|
}
|
||||||
42
templates/cheaters.html
Normal file
42
templates/cheaters.html
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block stylesheets %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="jumbotron">
|
||||||
|
<div class="container">
|
||||||
|
<h1>Cheat Monitor</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
|
<div id="cheat" class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td scope="col" width="10px"><b>ID</b></td>
|
||||||
|
<td scope="col"><b>Challenge</b></td>
|
||||||
|
<td scope="col"><b>Cheat User</b></td>
|
||||||
|
<td scope="col"><b>Helper User</b></td>
|
||||||
|
<td scope="col"><b>Flag</b></td>
|
||||||
|
<td scope="col"><b>Date</b></td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for cheater in cheaters %}
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="text-center">{{ loop.index }}</th>
|
||||||
|
<td><a href="{{ request.script_root }}/admin/challenges/{{ cheater.challengeid }}">{{ cheater.challenge_name() }}</a></td>
|
||||||
|
<td><a href="{{ request.script_root }}/teams/{{ cheater.cheatteamid }}">{{ cheater.cheated_team_name() }}</a></td>
|
||||||
|
<td><a href="{{ request.script_root }}/teams/{{ cheater.sharerteamid }}">{{ cheater.shared_team_name() }}</a></td>
|
||||||
|
<td><a href="{{ request.script_root }}/teams/{{ cheater.sharerteamid }}">{{ cheater.shared_team_name() }}</a></td>
|
||||||
|
<td>{{cheater.date}}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
Reference in New Issue
Block a user