From df5d146e087237ad7dd1435af54696748acee20e Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Wed, 6 Jan 2016 18:23:43 -0600 Subject: [PATCH] added profile page --- ctf.nginx | 4 + deploy | 4 +- server/api.html | 31 +++++++ server/api/admin.py | 31 ++++--- server/api/models.py | 9 ++- server/api/user.py | 35 +++++++- server/app.py | 5 +- web/css/easyctf.css | 10 +++ web/index.html | 15 +++- web/js/easyctf.js | 32 +++++++- web/js/login.js | 16 ---- web/js/register.js | 27 ------- web/pages/404.html | 5 ++ web/pages/admin/problems.html | 148 +++++++++++++++++----------------- web/pages/profile.html | 55 +++++++++++++ 15 files changed, 288 insertions(+), 139 deletions(-) create mode 100644 server/api.html delete mode 100644 web/js/login.js delete mode 100644 web/js/register.js create mode 100644 web/pages/404.html diff --git a/ctf.nginx b/ctf.nginx index f866686..bd36907 100644 --- a/ctf.nginx +++ b/ctf.nginx @@ -17,6 +17,10 @@ server { default_type text/html; try_files /index.html /index.html; } + location ~^/admin/(problems)$ { + default_type text/html; + try_files /index.html /index.html; + } location ~ /api { proxy_set_header Host $host; diff --git a/deploy b/deploy index 2d6014c..bb04d8e 100755 --- a/deploy +++ b/deploy @@ -5,7 +5,9 @@ pkill gunicorn sudo service nginx stop tmux kill-session -t ctf 2> /dev/null +sudo cp /vagrant/ctf.nginx /etc/nginx/sites-enabled/ctf + echo "Starting the server..." cd /home/vagrant/server sudo service nginx start -tmux new-session -s ctf -d 'gunicorn "app:app" -c /home/vagrant/scripts/gunicorn.py.ini' +tmux new-session -s ctf -d 'gunicorn "app:app" -c /home/vagrant/scripts/gunicorn.py.ini' \ No newline at end of file diff --git a/server/api.html b/server/api.html new file mode 100644 index 0000000..dfb8ca9 --- /dev/null +++ b/server/api.html @@ -0,0 +1,31 @@ + + +Python: package api + + + + + +
 
+ 
api
index
/home/vagrant/server/api/__init__.py
+

+

+ + + + + +
 
+Package Contents
       
admin
+api
+decorators
+
logger
+models
+problem
+
schemas
+user
+utils
+
+ \ No newline at end of file diff --git a/server/api/admin.py b/server/api/admin.py index 5152a88..8af0c3c 100644 --- a/server/api/admin.py +++ b/server/api/admin.py @@ -1,19 +1,26 @@ from flask import Blueprint, jsonify -from decorators import admins_only, api_wrapper, login_required +from decorators import admins_only, api_wrapper from models import db, Problems, Files +import json + blueprint = Blueprint("admin", __name__) -@blueprint.route("/problem/data", methods=["POST"]) -#@api_wrapper # Disable atm due to json serialization issues: will fix +@blueprint.route("/problems/list", methods=["POST"]) +@api_wrapper @admins_only -@login_required def problem_data(): - problems = Problems.query.add_columns("pid", "name", "category", "description", "hint", "value", "solves", "disabled", "flag").order_by(Problems.value).all() - jason = [] - - for problem in problems: - problem_files = [ str(_file.location) for _file in Files.query.filter_by(pid=int(problem.pid)).all() ] - jason.append({"pid": problem[1], "name": problem[2] ,"category": problem[3], "description": problem[4], "hint": problem[5], "value": problem[6], "solves": problem[7], "disabled": problem[8], "flag": problem[9], "files": problem_files}) - - return jsonify(data=jason) + problems = Problems.query.order_by(Problems.value).all() + problems_return = [ ] + for problem in problems: + problems_return.append({ + "pid": problem.pid, + "name": problem.name, + "category": problem.category, + "description": problem.description, + "hint": problem.hint, + "value": problem.value, + "threshold": problem.threshold, + "weightmap": json.loads(problem.weightmap) + }) + return { "success": 1, "problems": problems_return } \ No newline at end of file diff --git a/server/api/models.py b/server/api/models.py index e93fa88..715d880 100644 --- a/server/api/models.py +++ b/server/api/models.py @@ -1,5 +1,5 @@ from flask.ext.sqlalchemy import SQLAlchemy -import datetime +import time import utils db = SQLAlchemy() @@ -14,6 +14,8 @@ class Users(db.Model): password = db.Column(db.String(128)) admin = db.Column(db.Boolean) utype = db.Column(db.Integer) + tid = db.Column(db.Integer) + registertime = db.Column(db.Integer) def __init__(self, name, username, email, password, utype=1): self.name = name @@ -23,6 +25,7 @@ class Users(db.Model): self.password = utils.hash_password(password) self.utype = utype self.admin = False + self.registertime = int(time.time()) class Teams(db.Model): tid = db.Column(db.Integer, primary_key=True) @@ -90,11 +93,11 @@ class LoginTokens(db.Model): ua = db.Column(db.String(128)) ip = db.Column(db.String(16)) - def __init__(self, uid, username, expiry=datetime.datetime.utcnow(), active=True, ua=None, ip=None): + def __init__(self, uid, username, expiry=int(time.time()), active=True, ua=None, ip=None): self.sid = utils.generate_string() self.uid = uid self.username = username - self.issued = datetime.datetime.utcnow() + self.issued = int(time.time()) self.expiry = expiry self.active = active self.ua = ua diff --git a/server/api/user.py b/server/api/user.py index c814368..bc786c8 100644 --- a/server/api/user.py +++ b/server/api/user.py @@ -6,6 +6,7 @@ from models import db, LoginTokens, Users from decorators import api_wrapper, WebException from schemas import verify_to_schema, check +import datetime import logger import re import requests @@ -43,7 +44,7 @@ def user_register(): return { "success": 1, "message": "Success!" } -@blueprint.route("/logout", methods=["GET", "POST"]) +@blueprint.route("/logout", methods=["POST"]) @api_wrapper def user_logout(): sid = session["sid"] @@ -80,6 +81,36 @@ def user_status(): } return result +@blueprint.route("/info", methods=["POST"]) +@api_wrapper +def user_info(): + logged_in = is_logged_in() + username = utils.flat_multi(request.form).get("username") + if username is None: + if logged_in: + username = session["username"] + if username is None: + raise WebException("No user specified.") + me = username.lower() == session["username"].lower() + user = get_user(username_lower=username.lower()).first() + if user is None: + raise WebException("User not found.") + + show_email = me if logged_in else False + userdata = { + "user_found": True, + "name": user.name, + "username": user.username, + "type": ["Student", "Instructor", "Observer"][user.utype - 1], + "admin": user.admin, + "registertime": datetime.datetime.fromtimestamp(user.registertime).isoformat() + "Z", + "me": me, + "show_email": show_email + } + if show_email: + userdata["email"] = user.email + return { "success": 1, "user": userdata } + ################## # USER FUNCTIONS # ################## @@ -148,7 +179,7 @@ def login_user(username, password): session["sid"] = token.sid session["username"] = token.username - session["admin"] = user.utype == 0 + session["admin"] = user.admin == True return True diff --git a/server/app.py b/server/app.py index 7ba7b69..e5bd14a 100644 --- a/server/app.py +++ b/server/app.py @@ -5,6 +5,8 @@ import api import config import json +from api.decorators import api_wrapper + app = Flask(__name__) app.config["SQLALCHEMY_DATABASE_URI"] = config.SQLALCHEMY_DATABASE_URI @@ -24,8 +26,9 @@ app.register_blueprint(api.problem.blueprint, url_prefix="/api/problem") api.logger.initialize_logs() @app.route("/api") +@api_wrapper def api_main(): - return json.dumps({ "success": 1, "message": "The API is online." }) + return { "success": 1, "message": "The API is online." } if __name__ == "__main__": with app.app_context(): diff --git a/web/css/easyctf.css b/web/css/easyctf.css index 4690001..9325a9e 100644 --- a/web/css/easyctf.css +++ b/web/css/easyctf.css @@ -10,4 +10,14 @@ * { font-family: "Proxima Nova"; +} + +.tab-content { + padding: 10px; + > .tab-pane { + display: none; + } + > .active { + display: block; + } } \ No newline at end of file diff --git a/web/index.html b/web/index.html index 47c0305..d875017 100644 --- a/web/index.html +++ b/web/index.html @@ -39,6 +39,16 @@

  • Chat
  • +