This commit is contained in:
Michael Zhang 2015-12-23 22:14:54 -06:00
commit 5f4edf7792
12 changed files with 10631 additions and 61 deletions

View file

@ -16,6 +16,10 @@ If you have any issues during installation, file an issue.
## Notes ## Notes
####reCAPTCHA
Site Key: *6Lc4xhMTAAAAAIaiF3yEWGbHRaGgMg4FHor61p1G*
Secret Key: *6Lc4xhMTAAAAACFaG2NyuKoMdZQtSa_1LI76BCEu*
**Resources** : Flask, MySQL **Resources** : Flask, MySQL

View file

@ -4,17 +4,59 @@ import utils
db = SQLAlchemy() db = SQLAlchemy()
class Users(db.Model): class Users(db.Model):
id = db.Column(db.Integer, primary_key=True) uid = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64)) tid = db.Column(db.Integer)
username = db.Column(db.String(64), unique=True) name = db.Column(db.String(64))
username_lower = db.Column(db.String(64), unique=True) username = db.Column(db.String(64), unique=True)
email = db.Column(db.String(64), unique=True) username_lower = db.Column(db.String(64), unique=True)
password = db.Column(db.String(128)) email = db.Column(db.String(64), unique=True)
admin = db.Column(db.Boolean) password = db.Column(db.String(128))
admin = db.Column(db.Boolean)
def __init__(self, name, username, email, password): def __init__(self, name, username, email, password):
self.name = name self.name = name
self.username = username self.username = username
self.username_lower = username.lower() self.username_lower = username.lower()
self.email = email.lower() self.email = email.lower()
self.password = utils.hash_password(password) 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

View file

@ -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 from utils import api_wrapper
import utils
blueprint = Blueprint("user", __name__) blueprint = Blueprint("user", __name__)
@blueprint.route("/register", methods=["POST"]) @blueprint.route("/register", methods=["POST"])
@api_wrapper @api_wrapper
def user_register(): 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()

View file

@ -6,32 +6,39 @@ import json
import api import api
from api.api import api as api_blueprint from api.api import api as api_blueprint
from api.user import blueprint as user_blueprint
app = Flask(__name__) 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.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(api_blueprint)
app.register_blueprint(user_blueprint, url_prefix="/api/user")
@app.route("/api") @app.route("/api")
def api_main(): 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__": if __name__ == "__main__":
with app.app_context(): with app.app_context():
parser = ArgumentParser(description="EasyCTF Server Configuration") parser = ArgumentParser(description="EasyCTF Server Configuration")
parser.add_argument("-d", "--debug", action="store_true", help="Run the server in debug mode.", default=False) parser.add_argument("-d", "--debug", action="store_true", help="Run the server in debug mode.", default=False)
args = parser.parse_args() args = parser.parse_args()
keyword_args, _ = dict(args._get_kwargs()), args._get_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()
<<<<<<< HEAD
app.register_blueprint(api.admin.blueprint, url_prefix="/api/admin") app.register_blueprint(api.admin.blueprint, url_prefix="/api/admin")
app.register_blueprint(api.user.blueprint, url_prefix="/api/user") 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

View file

@ -10,5 +10,9 @@ with open(".secret_key", "a+") as secret:
key = secret.read() key = secret.read()
SECRET = key SECRET = key
SQLALCHEMY_DATABASE_URI = "mysql://root:i_hate_passwords@localhost/easyctf"
SQLALCHEMY_TRACK_MODIFICATIONS = False
CTF_BEGIN = 0 # To be used later CTF_BEGIN = 0 # To be used later
CTF_END = 0 # To be used later CTF_END = 0 # To be used later

View file

@ -3,9 +3,35 @@
<head> <head>
<title>About</title> <title>About</title>
<script src="js/semantic.min.js"></script> <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"> <link type="text/css" rel="stylesheet" href="css/semantic.min.css">
</head> </head>
<body> <body style="background-color: #EEEEEE;">
<h1>EasyCTF is Fun!</h1> <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> </body>
</html> </html>

View file

@ -1,4 +1,21 @@
marquee { h1 {
background-color: black; font-size: 75px;
color:white; }
::-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;
} }

View file

@ -25,31 +25,26 @@
} }
</style> </style>
</head> </head>
<body> <body style="background-color: #EEEEEE;">
<div class="ui fixed inverted menu"> <div class="ui inverted menu" style="background-color:#FA6900;">
<div class="ui container"> <div class="ui container">
<a href="#" class="header item"> <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>
<a href="#" class="item">Home</a> <a class="item" href="./">Home</a>
<div class="ui simple dropdown item"> <a class="item" href="./about.html">About</a>
Dropdown <i class="dropdown icon"></i> <a class="item" href="./register.html">Register</a>
<div class="menu"> <div class="right menu">
<a class="item" href="#">Link Item</a> <a class="item" href="./login.html">Login</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>
</div> </div>
</div> </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> </body>
</html> </html>

10351
web/js/jquery-1.11.3.js vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -5,7 +5,30 @@
<script src="js/semantic.min.js"></script> <script src="js/semantic.min.js"></script>
<link type="text/css" rel="stylesheet" href="css/semantic.min.css"> <link type="text/css" rel="stylesheet" href="css/semantic.min.css">
</head> </head>
<body> <body style="background-color: #EEEEEE;">
<h1>Please Login to EasyCTF</h1> <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> </body>
</html> </html>

View file

@ -4,8 +4,57 @@
<title>Register</title> <title>Register</title>
<script src="js/semantic.min.js"></script> <script src="js/semantic.min.js"></script>
<link type="text/css" rel="stylesheet" href="css/semantic.min.css"> <link type="text/css" rel="stylesheet" href="css/semantic.min.css">
<script src='https://www.google.com/recaptcha/api.js'></script>
</head> </head>
<body> <body style="background-color: #EEEEEE;">
<h1>Please Register for EasyCTF</h1> <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> </body>
<script>
$('#select')
.dropdown()
;
</script>
<html> <html>