diff --git a/server/api.html b/server/api.html
deleted file mode 100644
index dfb8ca9..0000000
--- a/server/api.html
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
Python: package api
-
-
-
-
-
-
-
-
-
-Package Contents |
-
- | |
- |
-
\ No newline at end of file
diff --git a/server/api/decorators.py b/server/api/decorators.py
index 558f6b3..cea2547 100644
--- a/server/api/decorators.py
+++ b/server/api/decorators.py
@@ -1,42 +1,59 @@
+from functools import wraps
+from flask import abort, request, session, make_response
+
import json
import traceback
-from functools import wraps
-from flask import session
+import utils
class WebException(Exception): pass
+response_header = { "Content-Type": "application/json; charset=utf-8" }
def api_wrapper(f):
- @wraps(f)
- def wrapper(*args, **kwds):
- web_result = {}
- response = 200
- try:
- web_result = f(*args, **kwds)
- except WebException as error:
- response = 200
- web_result = { "success": 0, "message": str(error) }
- except Exception as error:
- response = 200
- traceback.print_exc()
- web_result = { "success": 0, "message": "Something went wrong! Please notify us about this immediately.", "error": [ str(error), traceback.format_exc() ] }
- return json.dumps(web_result), response, { "Content-Type": "application/json; charset=utf-8" }
- return wrapper
+ @wraps(f)
+ def wrapper(*args, **kwds):
+ if request.method == "POST":
+ token = session.pop("csrf_token")
+ if not token or token != request.form.get("csrf_token"):
+ return make_response(json.dumps({ "success": 0, "message": "Token has been tampered with." }), 403, response_header)
+
+ web_result = {}
+ response = 200
+ try:
+ web_result = f(*args, **kwds)
+ except WebException as error:
+ response = 200
+ web_result = { "success": 0, "message": str(error) }
+ except Exception as error:
+ response = 200
+ traceback.print_exc()
+ web_result = { "success": 0, "message": "Something went wrong! Please notify us about this immediately.", "error": [ str(error), traceback.format_exc() ] }
+ result = (json.dumps(web_result), response, response_header)
+
+ # Setting CSRF token
+ if "token" not in session:
+ token = utils.generate_string()
+ response = make_response(result)
+ response.set_cookie("csrf_token", token)
+ session["csrf_token"] = token
+
+ return response
+ return wrapper
import user # Must go below api_wrapper to prevent import loops
def login_required(f):
- @wraps(f)
- def decorated_function(*args, **kwargs):
- if not user.is_logged_in():
- return { "success": 0, "message": "Not logged in." }
- return f(*args, **kwargs)
- return decorated_function
+ @wraps(f)
+ def decorated_function(*args, **kwargs):
+ if not user.is_logged_in():
+ return { "success": 0, "message": "Not logged in." }
+ return f(*args, **kwargs)
+ return decorated_function
def admins_only(f):
- @wraps(f)
- def decorated_function(*args, **kwargs):
- if not user.is_admin():
- return { "success": 0, "message": "Not authorized." }
- return f(*args, **kwargs)
- return decorated_function
+ @wraps(f)
+ def decorated_function(*args, **kwargs):
+ if not user.is_admin():
+ return { "success": 0, "message": "Not authorized." }
+ return f(*args, **kwargs)
+ return decorated_function
diff --git a/server/api/user.py b/server/api/user.py
index 67b7d9b..730654b 100644
--- a/server/api/user.py
+++ b/server/api/user.py
@@ -1,4 +1,4 @@
-from flask import Blueprint, session, request, redirect, url_for
+from flask import Blueprint, make_response, session, request, redirect, url_for
from flask import current_app as app
from voluptuous import Schema, Length, Required
@@ -44,7 +44,7 @@ def user_register():
return { "success": 1, "message": "Success!" }
-@blueprint.route("/logout", methods=["POST"])
+@blueprint.route("/logout", methods=["GET"])
@api_wrapper
def user_logout():
sid = session["sid"]
@@ -69,7 +69,7 @@ def user_login():
return { "success": 1, "message": "Success!" }
-@blueprint.route("/status", methods=["POST"])
+@blueprint.route("/status", methods=["GET"])
@api_wrapper
def user_status():
logged_in = is_logged_in()
@@ -79,9 +79,10 @@ def user_status():
"admin": is_admin(),
"username": session["username"] if logged_in else "",
}
+
return result
-@blueprint.route("/info", methods=["POST"])
+@blueprint.route("/info", methods=["GET"])
@api_wrapper
def user_info():
logged_in = is_logged_in()
diff --git a/web/index.html b/web/index.html
index 8012137..d66c7b5 100644
--- a/web/index.html
+++ b/web/index.html
@@ -19,6 +19,7 @@
+
diff --git a/web/js/easyctf.js b/web/js/easyctf.js
index 7c23a0f..659dd0d 100644
--- a/web/js/easyctf.js
+++ b/web/js/easyctf.js
@@ -57,7 +57,7 @@ app.config(function($routeProvider, $locationProvider) {
app.controller("mainController", ["$scope", "$http", function($scope, $http) {
$scope.config = { navbar: { } };
- $.post("/api/user/status", function(result) {
+ $.get("/api/user/status", function(result) {
if (result["success"] == 1) {
$scope.config.navbar.logged_in = result["logged_in"];
$scope.config.navbar.username = result["username"];
@@ -74,7 +74,7 @@ app.controller("mainController", ["$scope", "$http", function($scope, $http) {
}]);
app.controller("logoutController", function() {
- $.post("/api/user/logout", function(result) {
+ $.get("/api/user/logout", function(result) {
location.href = "/";
});
});
@@ -83,7 +83,7 @@ app.controller("profileController", ["$controller", "$scope", "$http", "$routePa
var data = { };
if ("username" in $routeParams) data["username"] = $routeParams["username"];
$controller("mainController", { $scope: $scope });
- $.post("/api/user/info", data, function(result) {
+ $.get("/api/user/info", data, function(result) {
if (result["success"] == 1) {
$scope.user = result["user"];
}
@@ -108,7 +108,7 @@ app.controller("adminController", ["$controller", "$scope", "$http", function($c
app.controller("adminProblemsController", ["$controller", "$scope", "$http", function($controller, $scope, $http) {
$controller("adminController", { $scope: $scope });
- $.post("/api/admin/problems/list", function(result) {
+ $.get("/api/admin/problems/list", function(result) {
if (result["success"] == 1) {
$scope.problems = result["problems"];
}
@@ -147,12 +147,16 @@ $.fn.serializeObject = function() {
var register_form = function() {
var input = "#register_form input";
var data = $("#register_form").serializeObject();
+ data["csrf_token"] = $.cookie("csrf_token");
$.post("/api/user/register", data, function(result) {
if (result["success"] == 1) {
location.href = "/profile";
} else {
- display_message("register_msg", "danger", result["message"])
+ display_message("register_msg", "danger", result["message"]);
}
+ }).fail(function(jqXHR, status, error) {
+ var result = JSON.parse(jqXHR["responseText"]);
+ display_message("register_msg", "danger", "Error " + jqXHR["status"] + ": " + result["message"]);
});
};
@@ -161,11 +165,15 @@ var register_form = function() {
var login_form = function() {
var input = "#login_form input";
var data = $("#login_form").serializeObject();
+ data["csrf_token"] = $.cookie("csrf_token");
$.post("/api/user/login", data, function(result) {
if (result["success"] == 1) {
location.href = "/profile";
} else {
- display_message("login_msg", "danger", result["message"])
+ display_message("login_msg", "danger", result["message"]);
}
+ }).fail(function(jqXHR, status, error) {
+ var result = JSON.parse(jqXHR["responseText"]);
+ display_message("login_msg", "danger", "Error " + jqXHR["status"] + ": " + result["message"]);
});
};
\ No newline at end of file
diff --git a/web/pages/login.html b/web/pages/login.html
index 7ff5137..8a9939e 100644
--- a/web/pages/login.html
+++ b/web/pages/login.html
@@ -31,6 +31,7 @@
+
diff --git a/web/pages/profile.html b/web/pages/profile.html
index 7076211..291b788 100644
--- a/web/pages/profile.html
+++ b/web/pages/profile.html
@@ -6,7 +6,7 @@
Edit Picture
{{ user.name }}
-
@{{ user.username }}
+
@{{ user.username }}
@@ -34,6 +34,38 @@
+
+
+
Team Information
+
+
+ Hi.
+
+
+
+
+
Statistics
+
+
+ Hi.
+
+
+
+
+
Top Solves
+
+
+ Hi.
+
+
+
+
+
Achievements
+
+
+ Hi.
+
+