fixed merge conflict
commit
05830d97de
|
@ -5,4 +5,5 @@ dump.rdb
|
||||||
/problems
|
/problems
|
||||||
__pycache__
|
__pycache__
|
||||||
/secrets
|
/secrets
|
||||||
|
/database
|
||||||
venv
|
venv
|
||||||
|
|
24
app.py
24
app.py
|
@ -17,19 +17,26 @@ import socket
|
||||||
app.secret_key = config.secret.key
|
app.secret_key = config.secret.key
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
if config.production:
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
else:
|
||||||
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
|
|
||||||
@app.before_request
|
@app.before_request
|
||||||
def make_info_available():
|
def make_info_available():
|
||||||
if "user_id" in session:
|
if "user_id" in session:
|
||||||
|
g.logged_in = True
|
||||||
try:
|
try:
|
||||||
g.user = User.get(User.id == session["user_id"])
|
g.user = User.get(User.id == session["user_id"])
|
||||||
g.user_restricts = g.user.restricts.split(",")
|
g.user_restricts = g.user.restricts.split(",")
|
||||||
g.team = g.user.team
|
g.team = g.user.team
|
||||||
g.team_restricts = g.team.restricts.split(",")
|
g.team_restricts = g.team.restricts.split(",")
|
||||||
except User.DoesNotExist:
|
except User.DoesNotExist:
|
||||||
|
g.logged_in = False
|
||||||
session.pop("user_id")
|
session.pop("user_id")
|
||||||
return render_template("login.html")
|
return render_template("login.html")
|
||||||
|
else:
|
||||||
|
g.logged_in = False
|
||||||
|
|
||||||
@app.context_processor
|
@app.context_processor
|
||||||
def scoreboard_variables():
|
def scoreboard_variables():
|
||||||
|
@ -56,6 +63,8 @@ app.register_blueprint(admin.admin)
|
||||||
|
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
def root():
|
def root():
|
||||||
|
if g.logged_in:
|
||||||
|
return redirect(url_for('team_dashboard'))
|
||||||
return redirect(url_for('register'))
|
return redirect(url_for('register'))
|
||||||
|
|
||||||
@app.route('/chat/')
|
@app.route('/chat/')
|
||||||
|
@ -183,8 +192,11 @@ def register():
|
||||||
team = Team.get(Team.key == team_key)
|
team = Team.get(Team.key == team_key)
|
||||||
except Team.DoesNotExist:
|
except Team.DoesNotExist:
|
||||||
flash("Couldn't find this team, check your team key.")
|
flash("Couldn't find this team, check your team key.")
|
||||||
return rener_template("register.html")
|
return render_template("register.html")
|
||||||
else:
|
else:
|
||||||
|
if not team_name or len(team_name) > 50:
|
||||||
|
flash("Missing team name")
|
||||||
|
return render_template("register.html")
|
||||||
if not team_affiliation or len(team_affiliation) > 100:
|
if not team_affiliation or len(team_affiliation) > 100:
|
||||||
team_affiliation = "No affiliation"
|
team_affiliation = "No affiliation"
|
||||||
try:
|
try:
|
||||||
|
@ -218,7 +230,7 @@ def register():
|
||||||
def logout():
|
def logout():
|
||||||
session.pop("user_id")
|
session.pop("user_id")
|
||||||
flash("You've successfully logged out.")
|
flash("You've successfully logged out.")
|
||||||
return redirect(url_for('root'))
|
return redirect(url_for('login'))
|
||||||
|
|
||||||
# Things that require a team
|
# Things that require a team
|
||||||
|
|
||||||
|
@ -402,7 +414,7 @@ def team_dashboard():
|
||||||
if not affiliation or len(affiliation) > 100:
|
if not affiliation or len(affiliation) > 100:
|
||||||
affiliation = "No affiliation"
|
affiliation = "No affiliation"
|
||||||
|
|
||||||
if g.team_name != team_name:
|
if g.team.name != team_name:
|
||||||
try:
|
try:
|
||||||
team = Team.get(Team.name == team_name)
|
team = Team.get(Team.name == team_name)
|
||||||
flash("This team name is already in use!")
|
flash("This team name is already in use!")
|
||||||
|
@ -556,9 +568,9 @@ def debug_app():
|
||||||
|
|
||||||
@app.before_request
|
@app.before_request
|
||||||
def before_request():
|
def before_request():
|
||||||
g.connected = True
|
|
||||||
db.connect()
|
db.connect()
|
||||||
g.redis = redis.StrictRedis()
|
g.redis = redis.StrictRedis(host=config.redis.host, port=config.redis.port, db=config.redis.db)
|
||||||
|
g.connected = True
|
||||||
|
|
||||||
@app.teardown_request
|
@app.teardown_request
|
||||||
def teardown_request(exc):
|
def teardown_request(exc):
|
||||||
|
|
20
config.py
20
config.py
|
@ -1,6 +1,8 @@
|
||||||
import os
|
import os
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
production = os.getenv("PRODUCTION", None) is not None
|
||||||
|
|
||||||
ctf_name = "IceCTF"
|
ctf_name = "IceCTF"
|
||||||
#IRC Channel
|
#IRC Channel
|
||||||
ctf_chat_channel = "#IceCTF"
|
ctf_chat_channel = "#IceCTF"
|
||||||
|
@ -32,6 +34,10 @@ custom_stylesheet = "css/main.css"
|
||||||
competition_begin = datetime(1970, 1, 1, 0, 0)
|
competition_begin = datetime(1970, 1, 1, 0, 0)
|
||||||
competition_end = datetime(2018, 1, 1, 0, 0)
|
competition_end = datetime(2018, 1, 1, 0, 0)
|
||||||
|
|
||||||
|
if production:
|
||||||
|
competition_begin = datetime(2016, 8, 12, hour=16, minute=0, second=0)
|
||||||
|
competition_end = datetime(2016, 8, 26, hour=16, minute=0, second=0)
|
||||||
|
|
||||||
# Are you using a resume server?
|
# Are you using a resume server?
|
||||||
resumes = False
|
resumes = False
|
||||||
# If yes, where's it hosted? Otherwise, just put None.
|
# If yes, where's it hosted? Otherwise, just put None.
|
||||||
|
@ -49,3 +55,17 @@ from collections import namedtuple
|
||||||
with open("secrets") as f:
|
with open("secrets") as f:
|
||||||
_secret = yaml.load(f)
|
_secret = yaml.load(f)
|
||||||
secret = namedtuple('SecretsDict', _secret.keys())(**_secret)
|
secret = namedtuple('SecretsDict', _secret.keys())(**_secret)
|
||||||
|
|
||||||
|
_redis = {
|
||||||
|
'host': 'localhost',
|
||||||
|
'port': 6379,
|
||||||
|
'db': 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if production:
|
||||||
|
with open("database") as f:
|
||||||
|
_database = yaml.load(f)
|
||||||
|
database = namedtuple('DatabaseDict', _database.keys())(**_database)
|
||||||
|
_redis['db'] = 1
|
||||||
|
|
||||||
|
redis = namedtuple('RedisDict', _redis.keys())(**_redis)
|
||||||
|
|
2
ctftool
2
ctftool
|
@ -17,7 +17,7 @@ import yaml
|
||||||
import argparse
|
import argparse
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
tables = [User, Team, UserAccess, Challenge, ChallengeSolve, ChallengeFailure, NewsItem, TroubleTicket, TicketComment, Notification, ScoreAdjustment, AdminUser]
|
tables = [Team, User, UserAccess, Challenge, ChallengeSolve, ChallengeFailure, NewsItem, TroubleTicket, TicketComment, Notification, ScoreAdjustment, AdminUser]
|
||||||
|
|
||||||
def create_tables(args):
|
def create_tables(args):
|
||||||
check = True
|
check = True
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
from peewee import *
|
from peewee import *
|
||||||
import bcrypt
|
import bcrypt
|
||||||
db = SqliteDatabase("dev.db")
|
import config
|
||||||
|
if config.production:
|
||||||
|
db = PostgresqlDatabase(config.database.database, user=config.database.user, password=config.database.password)
|
||||||
|
else:
|
||||||
|
db = SqliteDatabase("dev.db")
|
||||||
|
|
||||||
|
|
||||||
class BaseModel(Model):
|
class BaseModel(Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
|
@ -6,3 +6,4 @@ redis
|
||||||
pyyaml
|
pyyaml
|
||||||
oath
|
oath
|
||||||
pycountry
|
pycountry
|
||||||
|
psycopg2
|
||||||
|
|
|
@ -60,20 +60,21 @@
|
||||||
<div class="side-text">Scoreboard</div>
|
<div class="side-text">Scoreboard</div>
|
||||||
</a></li>
|
</a></li>
|
||||||
<li><a href="{{ url_for('chat') }}">
|
<li><a href="{{ url_for('chat') }}">
|
||||||
<div class="side-icon"><i class="material-icons green-text">chat</i></div>
|
<div class="side-icon"><i class="material-icons purple-text">build</i></div>
|
||||||
<div class="side-text">Chat</div>
|
<div class="side-text">Status</div>
|
||||||
</a></li>
|
</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if logged_in %}
|
{% if logged_in %}
|
||||||
|
<li><a href="https://chat.icec.tf/" target="_blank">
|
||||||
|
<div class="side-icon"><i class="material-icons green-text">chat</i></div>
|
||||||
|
<div class="side-text">Chat</div>
|
||||||
|
</a></li>
|
||||||
<li><a href="{{ url_for('team_tickets') }}">
|
<li><a href="{{ url_for('team_tickets') }}">
|
||||||
<div class="side-icon"><i class="material-icons amber-text">report_problem</i></div>
|
<div class="side-icon"><i class="material-icons amber-text">report_problem</i></div>
|
||||||
<div class="side-text">Tickets</div>
|
<div class="side-text">Tickets</div>
|
||||||
</a></li>
|
</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li><a href="{{ url_for('chat') }}">
|
|
||||||
<div class="side-icon"><i class="material-icons purple-text">build</i></div>
|
|
||||||
<div class="side-text">Status</div>
|
|
||||||
</a></li>
|
|
||||||
<div class="divider" /></div>
|
<div class="divider" /></div>
|
||||||
{% if logged_in %}
|
{% if logged_in %}
|
||||||
|
|
||||||
|
@ -151,5 +152,17 @@
|
||||||
</script>
|
</script>
|
||||||
{% block postscript %}
|
{% block postscript %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
{% if config.production %}
|
||||||
|
<script>
|
||||||
|
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||||
|
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||||
|
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||||
|
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||||
|
|
||||||
|
ga('create', 'UA-64770282-2', 'auto');
|
||||||
|
ga('send', 'pageview');
|
||||||
|
|
||||||
|
</script>
|
||||||
|
{% endif %}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="center" style="margin-top: 50px;">
|
<div class="center" style="margin-top: 50px;">
|
||||||
<iframe class="chat-frame" src="http://chat.icec.tf/" frameBorder="0"></iframe>
|
<iframe class="chat-frame" src="https://chat.icec.tf/" frameBorder="0"></iframe>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row team-wrapper z-depth-1">
|
<div class="row team-wrapper z-depth-1">
|
||||||
<input id="join_team" name="join_team" type="hidden" value="0"/>
|
<input id="join_team-input" name="join_team" type="hidden" value="0"/>
|
||||||
<div class="">
|
<div class="">
|
||||||
<ul class="tabs">
|
<ul class="tabs">
|
||||||
<li class="tab col s6"><a class="active truncate" href="#create-team" id="create-team-btn">Create new Team</a></li>
|
<li class="tab col s6"><a class="active truncate" href="#create-team" id="create-team-btn">Create new Team</a></li>
|
||||||
|
@ -110,13 +110,13 @@ $(function(){
|
||||||
$("#create-team #team_name").prop('required', true);
|
$("#create-team #team_name").prop('required', true);
|
||||||
$("#create-team #team_affiliation").prop('required', true);
|
$("#create-team #team_affiliation").prop('required', true);
|
||||||
$("#join-team #team_key").prop('required', false);
|
$("#join-team #team_key").prop('required', false);
|
||||||
$("#join-team #join_team").attr('val', "0");
|
$("#join_team-input").val("0");
|
||||||
});
|
});
|
||||||
$("#join-team-btn").on('click', function(){
|
$("#join-team-btn").on('click', function(){
|
||||||
$("#create-team #team_name").prop('required', false);
|
$("#create-team #team_name").prop('required', false);
|
||||||
$("#create-team #team_affiliation").prop('required', false);
|
$("#create-team #team_affiliation").prop('required', false);
|
||||||
$("#join-team #team_key").prop('required', true);
|
$("#join-team #team_key").prop('required', true);
|
||||||
$("#join-team #join_team").attr('val', "1");
|
$("#join_team-input").val("1");
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#country").change(function(e) {
|
$("#country").change(function(e) {
|
||||||
|
|
|
@ -80,6 +80,34 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header green">Members</div>
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s10 offset-s1">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Username</th>
|
||||||
|
<th>Eligibility Status</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for member in team.members %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ member.username }}</td>
|
||||||
|
<td>{{ "Eligible" if member.eligible() else "Ineligibile" }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header orange">Score Calculation</div>
|
<div class="card-header orange">Score Calculation</div>
|
||||||
|
|
|
@ -124,7 +124,7 @@
|
||||||
<p>First off, please check the email you signed up with. You must confirm your account to solve problems. If needed, you can change your Email or resend confirmation on this page.</p>
|
<p>First off, please check the email you signed up with. You must confirm your account to solve problems. If needed, you can change your Email or resend confirmation on this page.</p>
|
||||||
|
|
||||||
|
|
||||||
<p>We recommend you read the Rules and FAQ. Then, do some Practice to warm up for the competition, join the Chat to meet your fellow competitors and ask questions. The competition will begin soon enough, but in the meanwhile, explore the site!</p>
|
<p>The competition hasn't started yet, but while you wait, we recommend you read the <a href="https://icec.tf/about">Rules</a> and <a href="https://icec.tf/faq">FAQ</a>. Then, do some practice to warm up for the competition, join the Chat to meet your fellow competitors and ask questions. The competition will begin soon enough, but in the meanwhile, explore the site!</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<a href="#!" class="modal-action modal-close waves-effect waves-green btn-flat">Dismiss</a>
|
<a href="#!" class="modal-action modal-close waves-effect waves-green btn-flat">Dismiss</a>
|
||||||
|
|
|
@ -9,7 +9,7 @@ def send_confirmation_email(team_email, confirmation_key):
|
||||||
send_email(team_email, "Welcome to {}!".format(config.ctf_name),
|
send_email(team_email, "Welcome to {}!".format(config.ctf_name),
|
||||||
"""Hello, and thanks for registering for {}! Before you can start solving problems,
|
"""Hello, and thanks for registering for {}! Before you can start solving problems,
|
||||||
you must confirm your email by clicking the link below:
|
you must confirm your email by clicking the link below:
|
||||||
https://play.icec.tf/confirm_email/{}
|
http://play.icec.tf/confirm_email/{}
|
||||||
|
|
||||||
Once you've done that, your account will be enabled, and you will be able to access
|
Once you've done that, your account will be enabled, and you will be able to access
|
||||||
the challenges. If you have any trouble, feel free to contact an organizer!
|
the challenges. If you have any trouble, feel free to contact an organizer!
|
||||||
|
@ -23,7 +23,7 @@ def is_valid_email(email):
|
||||||
def send_password_reset_email(team_email, password_reset_token):
|
def send_password_reset_email(team_email, password_reset_token):
|
||||||
send_email(team_email, "{} Password Reset".format(config.ctf_name),
|
send_email(team_email, "{} Password Reset".format(config.ctf_name),
|
||||||
"""To reset your password click the link below and enter a new password. This link will expire in 24 hours.
|
"""To reset your password click the link below and enter a new password. This link will expire in 24 hours.
|
||||||
https://play.icec.tf/reset_password/{}
|
http://play.icec.tf/reset_password/{}
|
||||||
|
|
||||||
If you didn't request this email, then you can disregard it.
|
If you didn't request this email, then you can disregard it.
|
||||||
""".format(password_reset_token))
|
""".format(password_reset_token))
|
||||||
|
|
Loading…
Reference in New Issue