mirror of
https://github.com/aljazceru/CTFd.git
synced 2025-12-18 14:34:21 +01:00
Format all the things (#991)
* Format Javascript and CSS files with `prettier`: `prettier --write 'CTFd/themes/**/*'` * Format Python with `black`: `black CTFd` & `black tests` * Travis now uses xenial instead of trusty.
This commit is contained in:
@@ -2,7 +2,16 @@ from __future__ import division # Use floating point for math calculations
|
||||
from CTFd.plugins.challenges import BaseChallenge, CHALLENGE_CLASSES
|
||||
from CTFd.plugins import register_plugin_assets_directory
|
||||
from CTFd.plugins.flags import get_flag_class
|
||||
from CTFd.models import db, Solves, Fails, Flags, Challenges, ChallengeFiles, Tags, Hints
|
||||
from CTFd.models import (
|
||||
db,
|
||||
Solves,
|
||||
Fails,
|
||||
Flags,
|
||||
Challenges,
|
||||
ChallengeFiles,
|
||||
Tags,
|
||||
Hints,
|
||||
)
|
||||
from CTFd.utils.user import get_ip
|
||||
from CTFd.utils.uploads import delete_file
|
||||
from CTFd.utils.modes import get_model
|
||||
@@ -14,19 +23,24 @@ class DynamicValueChallenge(BaseChallenge):
|
||||
id = "dynamic" # Unique identifier used to register challenges
|
||||
name = "dynamic" # Name of a challenge type
|
||||
templates = { # Handlebars templates used for each aspect of challenge editing & viewing
|
||||
'create': '/plugins/dynamic_challenges/assets/create.html',
|
||||
'update': '/plugins/dynamic_challenges/assets/update.html',
|
||||
'view': '/plugins/dynamic_challenges/assets/view.html',
|
||||
"create": "/plugins/dynamic_challenges/assets/create.html",
|
||||
"update": "/plugins/dynamic_challenges/assets/update.html",
|
||||
"view": "/plugins/dynamic_challenges/assets/view.html",
|
||||
}
|
||||
scripts = { # Scripts that are loaded when a template is loaded
|
||||
'create': '/plugins/dynamic_challenges/assets/create.js',
|
||||
'update': '/plugins/dynamic_challenges/assets/update.js',
|
||||
'view': '/plugins/dynamic_challenges/assets/view.js',
|
||||
"create": "/plugins/dynamic_challenges/assets/create.js",
|
||||
"update": "/plugins/dynamic_challenges/assets/update.js",
|
||||
"view": "/plugins/dynamic_challenges/assets/view.js",
|
||||
}
|
||||
# Route at which files are accessible. This must be registered using register_plugin_assets_directory()
|
||||
route = '/plugins/dynamic_challenges/assets/'
|
||||
route = "/plugins/dynamic_challenges/assets/"
|
||||
# Blueprint used to access the static_folder directory.
|
||||
blueprint = Blueprint('dynamic_challenges', __name__, template_folder='templates', static_folder='assets')
|
||||
blueprint = Blueprint(
|
||||
"dynamic_challenges",
|
||||
__name__,
|
||||
template_folder="templates",
|
||||
static_folder="assets",
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def create(request):
|
||||
@@ -54,23 +68,23 @@ class DynamicValueChallenge(BaseChallenge):
|
||||
"""
|
||||
challenge = DynamicChallenge.query.filter_by(id=challenge.id).first()
|
||||
data = {
|
||||
'id': challenge.id,
|
||||
'name': challenge.name,
|
||||
'value': challenge.value,
|
||||
'initial': challenge.initial,
|
||||
'decay': challenge.decay,
|
||||
'minimum': challenge.minimum,
|
||||
'description': challenge.description,
|
||||
'category': challenge.category,
|
||||
'state': challenge.state,
|
||||
'max_attempts': challenge.max_attempts,
|
||||
'type': challenge.type,
|
||||
'type_data': {
|
||||
'id': DynamicValueChallenge.id,
|
||||
'name': DynamicValueChallenge.name,
|
||||
'templates': DynamicValueChallenge.templates,
|
||||
'scripts': DynamicValueChallenge.scripts,
|
||||
}
|
||||
"id": challenge.id,
|
||||
"name": challenge.name,
|
||||
"value": challenge.value,
|
||||
"initial": challenge.initial,
|
||||
"decay": challenge.decay,
|
||||
"minimum": challenge.minimum,
|
||||
"description": challenge.description,
|
||||
"category": challenge.category,
|
||||
"state": challenge.state,
|
||||
"max_attempts": challenge.max_attempts,
|
||||
"type": challenge.type,
|
||||
"type_data": {
|
||||
"id": DynamicValueChallenge.id,
|
||||
"name": DynamicValueChallenge.name,
|
||||
"templates": DynamicValueChallenge.templates,
|
||||
"scripts": DynamicValueChallenge.scripts,
|
||||
},
|
||||
}
|
||||
return data
|
||||
|
||||
@@ -88,20 +102,28 @@ class DynamicValueChallenge(BaseChallenge):
|
||||
|
||||
for attr, value in data.items():
|
||||
# We need to set these to floats so that the next operations don't operate on strings
|
||||
if attr in ('initial', 'minimum', 'decay'):
|
||||
if attr in ("initial", "minimum", "decay"):
|
||||
value = float(value)
|
||||
setattr(challenge, attr, value)
|
||||
|
||||
Model = get_model()
|
||||
|
||||
solve_count = Solves.query \
|
||||
.join(Model, Solves.account_id == Model.id) \
|
||||
.filter(Solves.challenge_id == challenge.id, Model.hidden == False, Model.banned == False) \
|
||||
solve_count = (
|
||||
Solves.query.join(Model, Solves.account_id == Model.id)
|
||||
.filter(
|
||||
Solves.challenge_id == challenge.id,
|
||||
Model.hidden == False,
|
||||
Model.banned == False,
|
||||
)
|
||||
.count()
|
||||
)
|
||||
|
||||
# It is important that this calculation takes into account floats.
|
||||
# Hence this file uses from __future__ import division
|
||||
value = (((challenge.minimum - challenge.initial) / (challenge.decay ** 2)) * (solve_count ** 2)) + challenge.initial
|
||||
value = (
|
||||
((challenge.minimum - challenge.initial) / (challenge.decay ** 2))
|
||||
* (solve_count ** 2)
|
||||
) + challenge.initial
|
||||
|
||||
value = math.ceil(value)
|
||||
|
||||
@@ -146,12 +168,12 @@ class DynamicValueChallenge(BaseChallenge):
|
||||
:return: (boolean, string)
|
||||
"""
|
||||
data = request.form or request.get_json()
|
||||
submission = data['submission'].strip()
|
||||
submission = data["submission"].strip()
|
||||
flags = Flags.query.filter_by(challenge_id=challenge.id).all()
|
||||
for flag in flags:
|
||||
if get_flag_class(flag.type).compare(flag, submission):
|
||||
return True, 'Correct'
|
||||
return False, 'Incorrect'
|
||||
return True, "Correct"
|
||||
return False, "Incorrect"
|
||||
|
||||
@staticmethod
|
||||
def solve(user, team, challenge, request):
|
||||
@@ -165,7 +187,7 @@ class DynamicValueChallenge(BaseChallenge):
|
||||
"""
|
||||
chal = DynamicChallenge.query.filter_by(id=challenge.id).first()
|
||||
data = request.form or request.get_json()
|
||||
submission = data['submission'].strip()
|
||||
submission = data["submission"].strip()
|
||||
|
||||
Model = get_model()
|
||||
|
||||
@@ -174,14 +196,19 @@ class DynamicValueChallenge(BaseChallenge):
|
||||
team_id=team.id if team else None,
|
||||
challenge_id=challenge.id,
|
||||
ip=get_ip(req=request),
|
||||
provided=submission
|
||||
provided=submission,
|
||||
)
|
||||
db.session.add(solve)
|
||||
|
||||
solve_count = Solves.query \
|
||||
.join(Model, Solves.account_id == Model.id) \
|
||||
.filter(Solves.challenge_id == challenge.id, Model.hidden == False, Model.banned == False) \
|
||||
solve_count = (
|
||||
Solves.query.join(Model, Solves.account_id == Model.id)
|
||||
.filter(
|
||||
Solves.challenge_id == challenge.id,
|
||||
Model.hidden == False,
|
||||
Model.banned == False,
|
||||
)
|
||||
.count()
|
||||
)
|
||||
|
||||
# We subtract -1 to allow the first solver to get max point value
|
||||
solve_count -= 1
|
||||
@@ -189,9 +216,7 @@ class DynamicValueChallenge(BaseChallenge):
|
||||
# It is important that this calculation takes into account floats.
|
||||
# Hence this file uses from __future__ import division
|
||||
value = (
|
||||
(
|
||||
(chal.minimum - chal.initial) / (chal.decay**2)
|
||||
) * (solve_count**2)
|
||||
((chal.minimum - chal.initial) / (chal.decay ** 2)) * (solve_count ** 2)
|
||||
) + chal.initial
|
||||
|
||||
value = math.ceil(value)
|
||||
@@ -215,13 +240,13 @@ class DynamicValueChallenge(BaseChallenge):
|
||||
:return:
|
||||
"""
|
||||
data = request.form or request.get_json()
|
||||
submission = data['submission'].strip()
|
||||
submission = data["submission"].strip()
|
||||
wrong = Fails(
|
||||
user_id=user.id,
|
||||
team_id=team.id if team else None,
|
||||
challenge_id=challenge.id,
|
||||
ip=get_ip(request),
|
||||
provided=submission
|
||||
provided=submission,
|
||||
)
|
||||
db.session.add(wrong)
|
||||
db.session.commit()
|
||||
@@ -229,19 +254,21 @@ class DynamicValueChallenge(BaseChallenge):
|
||||
|
||||
|
||||
class DynamicChallenge(Challenges):
|
||||
__mapper_args__ = {'polymorphic_identity': 'dynamic'}
|
||||
id = db.Column(None, db.ForeignKey('challenges.id'), primary_key=True)
|
||||
__mapper_args__ = {"polymorphic_identity": "dynamic"}
|
||||
id = db.Column(None, db.ForeignKey("challenges.id"), primary_key=True)
|
||||
initial = db.Column(db.Integer, default=0)
|
||||
minimum = db.Column(db.Integer, default=0)
|
||||
decay = db.Column(db.Integer, default=0)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(DynamicChallenge, self).__init__(**kwargs)
|
||||
self.initial = kwargs['value']
|
||||
self.initial = kwargs["value"]
|
||||
|
||||
|
||||
def load(app):
|
||||
# upgrade()
|
||||
app.db.create_all()
|
||||
CHALLENGE_CLASSES['dynamic'] = DynamicValueChallenge
|
||||
register_plugin_assets_directory(app, base_path='/plugins/dynamic_challenges/assets/')
|
||||
CHALLENGE_CLASSES["dynamic"] = DynamicValueChallenge
|
||||
register_plugin_assets_directory(
|
||||
app, base_path="/plugins/dynamic_challenges/assets/"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user