fixed merge conflict

master
Glitch 2016-07-16 22:46:30 +00:00
commit 05830d97de
12 changed files with 101 additions and 21 deletions

1
.gitignore vendored
View File

@ -5,4 +5,5 @@ dump.rdb
/problems /problems
__pycache__ __pycache__
/secrets /secrets
/database
venv venv

24
app.py
View File

@ -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):

View File

@ -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)

View File

@ -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

View File

@ -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:

View File

@ -6,3 +6,4 @@ redis
pyyaml pyyaml
oath oath
pycountry pycountry
psycopg2

View File

@ -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>

View File

@ -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 %}

View File

@ -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) {

View File

@ -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>

View File

@ -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>

View File

@ -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))