diff --git a/.gitignore b/.gitignore index 3052973..06599fd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .vagrant .secret_key .bundle/config +graders/ logs/ files/ pfp/ diff --git a/server/api/admin.py b/server/api/admin.py index 68b65b7..d9e78f8 100644 --- a/server/api/admin.py +++ b/server/api/admin.py @@ -23,7 +23,7 @@ def problem_data(): "value": problem.value, "threshold": problem.threshold, "weightmap": problem.weightmap, - "flag": problem.flag + "grader_contents": open(problem.grader, "r").read() }) problems_return.sort(key=lambda prob: prob["value"]) return { "success": 1, "problems": problems_return } diff --git a/server/api/models.py b/server/api/models.py index 0a5b34d..a872856 100644 --- a/server/api/models.py +++ b/server/api/models.py @@ -135,7 +135,6 @@ class Problems(db.Model): pid = db.Column(db.String(32), primary_key=True, autoincrement=False) title = db.Column(db.String(128)) category = db.Column(db.String(128)) - flag = db.Column(db.String(128)) description = db.Column(db.Text) value = db.Column(db.Integer) hint = db.Column(db.Text) @@ -143,13 +142,13 @@ class Problems(db.Model): bonus = db.Column(db.Integer) threshold = db.Column(db.Integer) weightmap = db.Column(db.PickleType) + grader = db.Column(db.Text) - def __init__(self, pid, title, category, description, flag, value, hint="", autogen=False, bonus=0, threshold=0, weightmap={}): + def __init__(self, pid, title, category, description, value, hint="", autogen=False, bonus=0, threshold=0, weightmap={}): self.pid = pid self.title = title self.category = category self.description = description - self.flag = flag self.value = value self.hint = hint self.autogen = autogen diff --git a/server/api/problem.py b/server/api/problem.py index 7f782e3..634b45a 100644 --- a/server/api/problem.py +++ b/server/api/problem.py @@ -20,8 +20,8 @@ def problem_add(): category = request.form["category"] description = request.form["description"] hint = request.form["hint"] - flag = request.form["flag"] value = request.form["value"] + grader_contents = request.form["grader_contents"] pid = utils.generate_string() while Problems.query.filter_by(pid=pid).first(): pid = utils.generate_string() @@ -30,7 +30,7 @@ def problem_add(): if title_exist: raise WebException("Problem name already taken.") - problem = Problems(pid, title, category, description, flag, value, hint=hint) + problem = Problems(pid, title, category, description, value, hint=hint) db.session.add(problem) db.session.commit() @@ -47,6 +47,14 @@ def problem_add(): db_file = Files(problem.pid, "/".join(file_path.split("/")[2:])) db.session.add(db_file) + grader_folder = os.path.join(app.config["GRADER_FOLDER"], pid) + if not os.path.exists(grader_folder): + os.makedirs(grader_folder) + grader_path = os.path.join(grader_folder, "grader.py") + grader_file = open(grader_path, "w") + grader_file.write(grader_contents) + grader_file.close() + problem.grader = grader_path db.session.commit() return { "success": 1, "message": "Success!" } @@ -73,8 +81,8 @@ def problem_update(): category = request.form["category"] description = request.form["description"] hint = request.form["hint"] - flag = request.form["flag"] value = request.form["value"] + grader_contents = request.form["grader_contents"] problem = Problems.query.filter_by(pid=pid).first() if problem: @@ -82,9 +90,12 @@ def problem_update(): problem.category = category problem.description = description problem.hint = hint - problem.flag = flag problem.value = value + grader = open(problem.grader, "w") + grader.write(grader_contents) + grader.close() + db.session.add(problem) db.session.commit() diff --git a/server/app.py b/server/app.py index ec403b2..6b4a282 100644 --- a/server/app.py +++ b/server/app.py @@ -18,6 +18,8 @@ app.config.from_object(config) if not os.path.exists(app.config["UPLOAD_FOLDER"]): os.makedirs(app.config["UPLOAD_FOLDER"]) +if not os.path.exists(app.config["GRADER_FOLDER"]): + os.makedirs(app.config["GRADER_FOLDER"]) if not os.path.exists("pfp"): os.makedirs("pfp") @@ -117,4 +119,4 @@ def main(): parser.print_help() if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/server/config.py b/server/config.py index 44f2c2e..f1d7569 100644 --- a/server/config.py +++ b/server/config.py @@ -16,6 +16,7 @@ SQLALCHEMY_DATABASE_URI = "mysql://root:i_hate_passwords@localhost/easyctf" SQLALCHEMY_TRACK_MODIFICATIONS = False UPLOAD_FOLDER = os.path.normpath("../web/files") +GRADER_FOLDER = os.path.normpath("graders") CTF_BEGIN = 0 # To be used later CTF_END = 0 # To be used later @@ -24,4 +25,4 @@ MG_HOST = "" MG_API_KEY = "" ADMIN_EMAIL = "" -PROBLEM_DIR = "../problems" \ No newline at end of file +PROBLEM_DIR = "../problems" diff --git a/web/js/admin.js b/web/js/admin.js index b3640ef..b700dd1 100644 --- a/web/js/admin.js +++ b/web/js/admin.js @@ -7,6 +7,8 @@ $(document).ready(function() { var create_problem = function() { var input = "#new_problem_form input"; var data = $("#new_problem_form").serializeObject(); + var grader_contents = ace.edit("new_grader").getValue(); + data["grader_contents"] = grader_contents; $(input).attr("disabled", "disabled"); api_call("POST", "/api/problem/add", data, function(result) { if (result["success"] == 1) { @@ -30,6 +32,10 @@ var update_problem = function(form_id) { var input = "#" + form_id + " input"; var data = $("#" + form_id).serializeObject(); pid = data["pid"]; + + var grader_contents = ace.edit(pid + "_grader").getValue(); + data["grader_contents"] = grader_contents; + $(input).attr("disabled", "disabled"); api_call("POST", "/api/problem/update", data, function(result) { if (result["success"] == 1) { diff --git a/web/js/easyctf.js b/web/js/easyctf.js index 0f290c9..afa9f86 100644 --- a/web/js/easyctf.js +++ b/web/js/easyctf.js @@ -216,6 +216,34 @@ app.controller("adminProblemsController", ["$controller", "$scope", "$http", fun $scope.problems = []; } $scope.$apply(); + $scope.problems.forEach(function(problem) { + + $(".selectpicker").selectpicker(); + var config = { + toolbar: [ + { name: "basicstyles", items: [ "Bold", "Italic", "Underline" ] }, + { name: "links", items: [ "Link" ] }, + { name: "paragraph", items: [ "NumberedList", "BulletedList", "-", "Outdent", "Indent", "-", "Blockquote" ] }, + { name: "tools", items: [ "Maximize" ] }, + { name: "document", items: [ "Source" ] }, + ] + }; + var editor = new EpicEditor({ + container: "new_grader", + theme: { + base: "https://cdnjs.cloudflare.com/ajax/libs/epiceditor/0.2.2/themes/base/epiceditor.css", + preview: "https://cdnjs.cloudflare.com/ajax/libs/epiceditor/0.2.2/themes/preview/github.css", + editor: "https://cdnjs.cloudflare.com/ajax/libs/epiceditor/0.2.2/themes/editor/epic-light.css" + }, + button: { + bar: "show" + } + }).load(); + var grader = ace.edit(problem.pid + "_grader"); + grader.setTheme("ace/theme/tomorrow"); + grader.getSession().setMode("ace/mode/python"); + grader.setValue(problem.grader_contents); + }); }); }]); diff --git a/web/pages/admin/problems.html b/web/pages/admin/problems.html index ec4d7dc..3fb183f 100644 --- a/web/pages/admin/problems.html +++ b/web/pages/admin/problems.html @@ -14,7 +14,7 @@
@@ -25,7 +25,7 @@
- +

@@ -63,7 +61,7 @@

- +