update
This commit is contained in:
commit
5f4edf7792
12 changed files with 10631 additions and 61 deletions
|
@ -16,6 +16,10 @@ If you have any issues during installation, file an issue.
|
|||
|
||||
## Notes
|
||||
|
||||
####reCAPTCHA
|
||||
Site Key: *6Lc4xhMTAAAAAIaiF3yEWGbHRaGgMg4FHor61p1G*
|
||||
Secret Key: *6Lc4xhMTAAAAACFaG2NyuKoMdZQtSa_1LI76BCEu*
|
||||
|
||||
**Resources** : Flask, MySQL
|
||||
|
||||
|
||||
|
|
|
@ -4,17 +4,59 @@ import utils
|
|||
db = SQLAlchemy()
|
||||
|
||||
class Users(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
name = db.Column(db.String(64))
|
||||
username = db.Column(db.String(64), unique=True)
|
||||
username_lower = db.Column(db.String(64), unique=True)
|
||||
email = db.Column(db.String(64), unique=True)
|
||||
password = db.Column(db.String(128))
|
||||
admin = db.Column(db.Boolean)
|
||||
uid = db.Column(db.Integer, primary_key=True)
|
||||
tid = db.Column(db.Integer)
|
||||
name = db.Column(db.String(64))
|
||||
username = db.Column(db.String(64), unique=True)
|
||||
username_lower = db.Column(db.String(64), unique=True)
|
||||
email = db.Column(db.String(64), unique=True)
|
||||
password = db.Column(db.String(128))
|
||||
admin = db.Column(db.Boolean)
|
||||
|
||||
def __init__(self, name, username, email, password):
|
||||
self.name = name
|
||||
self.username = username
|
||||
self.username_lower = username.lower()
|
||||
self.email = email.lower()
|
||||
self.password = utils.hash_password(password)
|
||||
def __init__(self, name, username, email, password):
|
||||
self.name = name
|
||||
self.username = username
|
||||
self.username_lower = username.lower()
|
||||
self.email = email.lower()
|
||||
self.password = utils.hash_password(password)
|
||||
|
||||
class Teams(db.Model):
|
||||
tid = db.Column(db.Integer, primary_key=True)
|
||||
name = db.Column(db.String(64), unique=True)
|
||||
join_code = db.Column(db.String(128), unique=True)
|
||||
school = db.Column(db.Text)
|
||||
size = db.Column(db.Integer)
|
||||
score = db.Column(db.Integer)
|
||||
observer = db.Column(db.Boolean)
|
||||
owner = db.Column(db.Integer)
|
||||
|
||||
def __init__(self, name, school):
|
||||
self.name = name
|
||||
self.school = school
|
||||
|
||||
class Problems(db.Model):
|
||||
pid = db.Column(db.Integer, primary_key=True)
|
||||
name = db.Column(db.String(128))
|
||||
description = db.Column(db.Text)
|
||||
hint = db.Column(db.Text)
|
||||
flag = db.Column(db.Text)
|
||||
disabled = db.Column(db.Boolean)
|
||||
value = db.Column(db.Integer)
|
||||
solves = db.Column(db.Integer)
|
||||
|
||||
def __init__(self, name, description, hint, flag, value):
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.hint = hint
|
||||
self.flag = flag
|
||||
self.value = value
|
||||
|
||||
class Solves(db.Model):
|
||||
sid = db.Column(db.Integer, primary_key=True)
|
||||
pid = db.Column(db.Integer)
|
||||
tid = db.Column(db.Integer)
|
||||
date = db.Column(db.Integer, default=utils.get_time_since_epoch())
|
||||
|
||||
def __init__(self, pid, tid):
|
||||
self.pid = pid
|
||||
self.tid = tid
|
||||
|
|
|
@ -1,9 +1,61 @@
|
|||
from flask import Blueprint
|
||||
from flask import Blueprint, session, request
|
||||
from flask import current_app as app
|
||||
|
||||
from models import db, Users
|
||||
from utils import api_wrapper
|
||||
|
||||
import utils
|
||||
|
||||
blueprint = Blueprint("user", __name__)
|
||||
|
||||
@blueprint.route("/register", methods=["POST"])
|
||||
@api_wrapper
|
||||
def user_register():
|
||||
return { "success": 0, "message": "Registration is not open yet." }
|
||||
name = request.form["name"]
|
||||
username = request.form["username"]
|
||||
password = request.form["password"]
|
||||
password_confirm = request.form["password_confirm"]
|
||||
email = request.form["email"]
|
||||
|
||||
username_exists = Users.query.add_columns("name", "uid").filter_by(username=username).first()
|
||||
email_exists = Users.query.add_columns("name", "uid").filter_by(email=email).first()
|
||||
|
||||
if password != password_confirm:
|
||||
return { "success": 0, "message": "Passwords do not match." }
|
||||
if len(password) > 128:
|
||||
return { "success": 0, "message": "Password is too long." }
|
||||
if len(password) == 0:
|
||||
return { "success": 0, "message": "Password is too short." }
|
||||
if len(username) > 64:
|
||||
return { "success": 0, "message": "Username is too long." }
|
||||
if username_exists:
|
||||
return { "success": 0, "message": "Username is already taken." }
|
||||
if email_exists:
|
||||
return { "success": 0, "message": "Email has already been used." }
|
||||
|
||||
add_user(name, username, email, password)
|
||||
|
||||
return { "success": 1, "message": "Success!" }
|
||||
|
||||
@blueprint.route("/logout", methods=["POST"])
|
||||
@api_wrapper
|
||||
def user_logout():
|
||||
session.clear()
|
||||
|
||||
@blueprint.route("/login", methods=["POST"])
|
||||
@api_wrapper
|
||||
def user_login():
|
||||
username = request.form["username"]
|
||||
password = request.form["password"]
|
||||
user = Users.query.filter_by(username=username).first()
|
||||
if utils.check_password(user.password, password):
|
||||
session["username"] = username
|
||||
session["admin"] = user.admin
|
||||
return { "success": 1, "message": "Success!" }
|
||||
else:
|
||||
return { "success": 0, "message": "Invalid credentials." }
|
||||
|
||||
def add_user(name, username, email, password):
|
||||
user = Users(name, username, email, password)
|
||||
db.session.add(user)
|
||||
db.session.commit()
|
||||
|
|
|
@ -40,4 +40,4 @@ def api_wrapper(f):
|
|||
traceback.print_exc()
|
||||
web_result = { "success": 0, "message": "Something went wrong! Please notify us about this immediately.", error: traceback.format_exc() }
|
||||
return json.dumps(web_result), response, { "Content-Type": "application/json; charset=utf-8" }
|
||||
return wrapper
|
||||
return wrapper
|
||||
|
|
|
@ -6,32 +6,39 @@ import json
|
|||
import api
|
||||
|
||||
from api.api import api as api_blueprint
|
||||
from api.user import blueprint as user_blueprint
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
with app.app_context():
|
||||
from api.models import db
|
||||
db.init_app(app)
|
||||
db.create_all()
|
||||
|
||||
app.secret_key = config.SECRET
|
||||
app.config["SQLALCHEMY_DATABASE_URI"] = config.SQLALCHEMY_DATABASE_URI
|
||||
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = config.SQLALCHEMY_TRACK_MODIFICATIONS
|
||||
app.register_blueprint(api_blueprint)
|
||||
app.register_blueprint(user_blueprint, url_prefix="/api/user")
|
||||
|
||||
@app.route("/api")
|
||||
def api_main():
|
||||
return json.dumps({ "success": 1, "message": "The API is online." })
|
||||
return json.dumps({ "success": 1, "message": "The API is online." })
|
||||
|
||||
if __name__ == "__main__":
|
||||
with app.app_context():
|
||||
parser = ArgumentParser(description="EasyCTF Server Configuration")
|
||||
parser.add_argument("-d", "--debug", action="store_true", help="Run the server in debug mode.", default=False)
|
||||
args = parser.parse_args()
|
||||
keyword_args, _ = dict(args._get_kwargs()), args._get_args()
|
||||
|
||||
app.debug = keyword_args["debug"]
|
||||
|
||||
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:i_hate_passwords@localhost/easyctf"
|
||||
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
|
||||
|
||||
from api.models import db
|
||||
db.init_app(app)
|
||||
db.create_all()
|
||||
with app.app_context():
|
||||
parser = ArgumentParser(description="EasyCTF Server Configuration")
|
||||
parser.add_argument("-d", "--debug", action="store_true", help="Run the server in debug mode.", default=False)
|
||||
args = parser.parse_args()
|
||||
keyword_args, _ = dict(args._get_kwargs()), args._get_args()
|
||||
|
||||
<<<<<<< HEAD
|
||||
app.register_blueprint(api.admin.blueprint, url_prefix="/api/admin")
|
||||
app.register_blueprint(api.user.blueprint, url_prefix="/api/user")
|
||||
|
||||
app.run(host="0.0.0.0", port=8000)
|
||||
app.run(host="0.0.0.0", port=8000)
|
||||
=======
|
||||
app.debug = keyword_args["debug"]
|
||||
|
||||
app.run(host="0.0.0.0", port=8000)
|
||||
>>>>>>> 6e538e221f28f239512f5c52a7d73ccb0f27576c
|
||||
|
|
|
@ -10,5 +10,9 @@ with open(".secret_key", "a+") as secret:
|
|||
key = secret.read()
|
||||
|
||||
SECRET = key
|
||||
|
||||
SQLALCHEMY_DATABASE_URI = "mysql://root:i_hate_passwords@localhost/easyctf"
|
||||
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
||||
|
||||
CTF_BEGIN = 0 # To be used later
|
||||
CTF_END = 0 # To be used later
|
||||
|
|
|
@ -3,9 +3,35 @@
|
|||
<head>
|
||||
<title>About</title>
|
||||
<script src="js/semantic.min.js"></script>
|
||||
<script src="js/jquery-1.11.3.js"></script>
|
||||
<link type="text/css" rel="stylesheet" href="css/semantic.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>EasyCTF is Fun!</h1>
|
||||
<body style="background-color: #EEEEEE;">
|
||||
<div class="ui inverted menu" style="margin: -0.1em; background-color: #FA6900;">
|
||||
<a class="item" href="./">Home</a>
|
||||
<a class="item" href="./about.html">About</a>
|
||||
<a class="item" href="./register.html">Register</a>
|
||||
<div class="right menu">
|
||||
<a class="item" href="./login.html">Login</a>
|
||||
</div>
|
||||
</div>
|
||||
<center style="margin-left: 10em; margin-right: 10em;">
|
||||
<h1 style="color: #69D2E7; font-size: 75px;">About EasyCTF</h1>
|
||||
<hr>
|
||||
<br>
|
||||
<div class="page-header">
|
||||
<h2 style="font-size: 2.5em;">Why Capture the Flag?</h2>
|
||||
</div>
|
||||
|
||||
<p>No, we're not running around in a gym, tagging other players. <b>Capture the flag</b> contests, or CTFs for short, are intense cybersecurity contests where participants try to capture a piece of information. To do this, they must use skills to capture a <i>virtual</i> flag, usually taking the form of a string, like this: <code>flag{this_is_a_flag}</code>. There are two common types of CTF competitions: <b>jeopardy</b>, and <b>attack-defense</b>.</p>
|
||||
<p>CTFs are different from the hacking you may hear from the news. While hacking is commonly associated with stealing and destruction, CTFs are all about learning and community.</p>
|
||||
|
||||
<div class="page-header">
|
||||
<h2 style="font-size: 2.5em;">EasyCTF</h2>
|
||||
</div>
|
||||
|
||||
<p>EasyCTF is a CTF that's tailored for the high school level. Started by high school students, it was created with a passion for learning. The following events have passed, but the site will remain online for historical purposes.</p>
|
||||
</div>
|
||||
</center>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,4 +1,21 @@
|
|||
marquee {
|
||||
background-color: black;
|
||||
color:white;
|
||||
h1 {
|
||||
font-size: 75px;
|
||||
}
|
||||
::-webkit-input-placeholder {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
:-moz-placeholder { /* Firefox 18- */
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
::-moz-placeholder { /* Firefox 19+ */
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
:-ms-input-placeholder {
|
||||
color: #999999;
|
||||
}
|
||||
.intro {
|
||||
text-align: center;
|
||||
}
|
||||
|
|
|
@ -25,31 +25,26 @@
|
|||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="ui fixed inverted menu">
|
||||
<body style="background-color: #EEEEEE;">
|
||||
<div class="ui inverted menu" style="background-color:#FA6900;">
|
||||
<div class="ui container">
|
||||
<a href="#" class="header item">
|
||||
<img class="logo" src="assets/images/logo.png"> EasyCTF
|
||||
<img class="logo" src="http://placehold.it/40x40">
|
||||
EasyCTF
|
||||
</a>
|
||||
<a href="#" class="item">Home</a>
|
||||
<div class="ui simple dropdown item">
|
||||
Dropdown <i class="dropdown icon"></i>
|
||||
<div class="menu">
|
||||
<a class="item" href="#">Link Item</a>
|
||||
<a class="item" href="#">Link Item</a>
|
||||
<div class="divider"></div>
|
||||
<div class="header">Header Item</div>
|
||||
<div class="item">
|
||||
<i class="dropdown icon"></i> Sub Menu
|
||||
<div class="menu">
|
||||
<a class="item" href="#">Link Item</a>
|
||||
<a class="item" href="#">Link Item</a>
|
||||
</div>
|
||||
</div>
|
||||
<a class="item" href="#">Link Item</a>
|
||||
</div>
|
||||
<a class="item" href="./">Home</a>
|
||||
<a class="item" href="./about.html">About</a>
|
||||
<a class="item" href="./register.html">Register</a>
|
||||
<div class="right menu">
|
||||
<a class="item" href="./login.html">Login</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="intro">
|
||||
<center>
|
||||
<h1 style="margin-bottom:-0.4em; font-size:75px; color:#69D2E7;">EasyCTF</h1>
|
||||
<h2 style="color:#A7DBDB;">Coming 2016</h2>
|
||||
</center>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
10351
web/js/jquery-1.11.3.js
vendored
Normal file
10351
web/js/jquery-1.11.3.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
|
@ -5,7 +5,30 @@
|
|||
<script src="js/semantic.min.js"></script>
|
||||
<link type="text/css" rel="stylesheet" href="css/semantic.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Please Login to EasyCTF</h1>
|
||||
<body style="background-color: #EEEEEE;">
|
||||
<div class="ui inverted menu" style="margin: -0.1em; background-color: #FA6900;">
|
||||
<a class="item" href="./">Home</a>
|
||||
<a class="item" href="./about.html">About</a>
|
||||
<a class="item" href="./register.html">Register</a>
|
||||
<div class="right menu">
|
||||
<a class="item" href="./login.html">Login</a>
|
||||
</div>
|
||||
</div>
|
||||
<center>
|
||||
<h1 style="color: #69D2E7; font-size: 75px;">Login</h1>
|
||||
<hr style="margin-left: 10em; margin-right: 10em;">
|
||||
<br>
|
||||
<div class="ui input">
|
||||
<input type="text" placeholder="Username" style="width:50em;">
|
||||
</div>
|
||||
<br><br>
|
||||
<div class="ui input">
|
||||
<input type="password" placeholder="Password" style="width:50em;">
|
||||
</div>
|
||||
<br><br>
|
||||
<button class="ui primary button" style="width:25em">
|
||||
Login
|
||||
</button>
|
||||
</center>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -4,8 +4,57 @@
|
|||
<title>Register</title>
|
||||
<script src="js/semantic.min.js"></script>
|
||||
<link type="text/css" rel="stylesheet" href="css/semantic.min.css">
|
||||
<script src='https://www.google.com/recaptcha/api.js'></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Please Register for EasyCTF</h1>
|
||||
<body style="background-color: #EEEEEE;">
|
||||
<div class="ui inverted menu" style="margin: -0.1em; background-color: #FA6900;">
|
||||
<a class="item" href="./">Home</a>
|
||||
<a class="item" href="./about.html">About</a>
|
||||
<a class="item" href="./register.html">Register</a>
|
||||
<div class="right menu">
|
||||
<a class="item" href="./login.html">Login</a>
|
||||
</div>
|
||||
</div>
|
||||
<center>
|
||||
<h1 style="color: #69D2E7; font-size: 75px;">Register Yourself</h1>
|
||||
<hr style="margin-left: 10em; margin-right: 10em;">
|
||||
<br>
|
||||
<div class="ui input">
|
||||
<input type="text" placeholder="Name" id="name" style="width:50em;">
|
||||
</div>
|
||||
<br><br>
|
||||
<select name="gender" class="ui dropdown" id="select" style="width: 50em;">
|
||||
<option value="1">US Middle/High School Student</option>
|
||||
<option value="2">US Middle/High School Teacher</option>
|
||||
<option value="3">Non-US/Non-Student/Observer</option>
|
||||
</select>
|
||||
<br><br>
|
||||
<div class="ui input">
|
||||
<input type="text" placeholder="Username" style="width:50em;">
|
||||
</div>
|
||||
<br><br>
|
||||
<div class="ui input">
|
||||
<input type="email" placeholder="Email" style="width:50em;">
|
||||
</div>
|
||||
<br><br>
|
||||
<div class="ui input">
|
||||
<input type="password" placeholder="Password" style="width:50em;">
|
||||
</div>
|
||||
<br><br>
|
||||
<div class="ui input">
|
||||
<input type="password" placeholder="Confirm Password" style="width:50em;">
|
||||
</div>
|
||||
<br><br>
|
||||
<div class="g-recaptcha" data-sitekey="6Lc4xhMTAAAAAIaiF3yEWGbHRaGgMg4FHor61p1G"></div>
|
||||
<br><br>
|
||||
<button class="ui primary button" style="width:25em">
|
||||
Submit
|
||||
</button>
|
||||
</center>
|
||||
</body>
|
||||
<script>
|
||||
$('#select')
|
||||
.dropdown()
|
||||
;
|
||||
</script>
|
||||
<html>
|
||||
|
|
Loading…
Reference in a new issue