mirror of
https://github.com/aljazceru/CTFd.git
synced 2026-02-17 20:24:28 +01:00
* Bootstrap v4 (#490) * Upgrading original theme to use Bootstrap v4 and overall improve use of utility classes * Fixing graph issues. Colors per team & cleaner hover * The solves tab now shows relative time instead of absolute time * Redesign admin theme * Updating modals and changing form name from desc to description * Moving CSS config from Pages to Config page * Adding IP address count to statistics * Move control of certain modals (files, flags, tags, hints) to challenges page * Expanding size of config page * Combining statistics and graphs pages * Moving percentage solved to the statistics page instead of the admin challenges page * Rename Keys.key_type to Keys.type (#459) (#478) * Rename keys.key_type to keys.type (#459) * Fixing previous migration to not be worried about key_type v type * Fixing loading of challenge type plugins * Switching from Handlebars to Nunjucks (#491) * Switching from Handlebars to Nunjucks * Allow admins to unlock hints before CTF begins and test that this is not allowed for regular users * Authed only (#492) * Adding authed_only decorator and adding next to url_for * Adding a basic preview to hints (#494) * Hints have a preview now for creating and updating hints. HTML and markdown are still allowed. * Ezq (#495) * Adding ezq as a simple wrapper around bootstrap modals * Use tabs not spaces and remove gray background on inputs * Adding title & draft to Pages. Making page preview open a new tab (#497) * Adding title & draft to Pages. * Making page preview open a new tab instead of render in the existing tab * Draft pages cannot be seen without a preview * Update check (#499) * Add update_check function * Notify user that a CTFd update is available in the admin panel * Adding update_check tests * Ratelimit (#500) * Implementing a ratelimit function * Fix error page formatting * Add rate limiting tests * Rate limit authentication functions and rate limit admin send email function * Load user solves before we load challenges to avoid unstyled buttons (#502) * Add a challenge preview (#503) * Adding a challenge preview to the admin panel * Change /admin/chals/<int:chalid> to /admin/chal/<int:chalid> * Adding codecov (#504) * Test coverage at https://codecov.io/gh/CTFd/CTFd * Sendmail improvements (#505) * Add get_smtp timeout, add sendmail error messages * Adding more error handling to sendmail * Adding Flask-Script (#507) * Pause ctf (#508) * Implement CTF pausing * Test CTF pausing * Fix loading challenges for users (#510) * Fix loading challenges for users * Temporarily switch themes in test * Pause help text (#509) * Adding pause help text * Pages authed (#511) * Adding authentication options to pages * Adding tests for accessing pages while draft & auth_required * Merging master into 1.1 (#513) * Name the core theme and remove the original theme
160 lines
5.4 KiB
Python
160 lines
5.4 KiB
Python
import sys
|
|
import os
|
|
|
|
from distutils.version import StrictVersion
|
|
from flask import Flask
|
|
from jinja2 import FileSystemLoader
|
|
from sqlalchemy.engine.url import make_url
|
|
from sqlalchemy.exc import OperationalError, ProgrammingError
|
|
from sqlalchemy_utils import database_exists, create_database
|
|
from sqlalchemy_utils.functions import get_tables
|
|
from six.moves import input
|
|
|
|
from CTFd.utils import cache, migrate, migrate_upgrade, migrate_stamp, update_check
|
|
from CTFd import utils
|
|
|
|
# Hack to support Unicode in Python 2 properly
|
|
if sys.version_info[0] < 3:
|
|
reload(sys)
|
|
sys.setdefaultencoding("utf-8")
|
|
|
|
__version__ = '1.1.0a1'
|
|
|
|
|
|
class ThemeLoader(FileSystemLoader):
|
|
def __init__(self, searchpath, encoding='utf-8', followlinks=False):
|
|
super(ThemeLoader, self).__init__(searchpath, encoding, followlinks)
|
|
self.overriden_templates = {}
|
|
|
|
def get_source(self, environment, template):
|
|
# Check if the template has been overriden
|
|
if template in self.overriden_templates:
|
|
return self.overriden_templates[template], template, True
|
|
|
|
# Check if the template requested is for the admin panel
|
|
if template.startswith('admin/'):
|
|
template = template[6:] # Strip out admin/
|
|
template = "/".join(['admin', 'templates', template])
|
|
return super(ThemeLoader, self).get_source(environment, template)
|
|
|
|
# Load regular theme data
|
|
theme = utils.get_config('ctf_theme')
|
|
template = "/".join([theme, 'templates', template])
|
|
return super(ThemeLoader, self).get_source(environment, template)
|
|
|
|
|
|
def confirm_upgrade():
|
|
print("/*\\ CTFd has updated and must update the database! /*\\")
|
|
print("/*\\ Please backup your database before proceeding! /*\\")
|
|
print("/*\\ CTFd maintainers are not responsible for any data loss! /*\\")
|
|
if input('Run database migrations (Y/N)').lower().strip() == 'y':
|
|
return True
|
|
else:
|
|
print('/*\\ Ignored database migrations... /*\\')
|
|
return False
|
|
|
|
|
|
def run_upgrade():
|
|
migrate_upgrade()
|
|
utils.set_config('ctf_version', __version__)
|
|
|
|
|
|
def create_app(config='CTFd.config.Config'):
|
|
app = Flask(__name__)
|
|
with app.app_context():
|
|
app.config.from_object(config)
|
|
app.jinja_loader = ThemeLoader(os.path.join(app.root_path, 'themes'), followlinks=True)
|
|
|
|
from CTFd.models import db, Teams, Solves, Challenges, WrongKeys, Keys, Tags, Files, Tracking
|
|
|
|
url = make_url(app.config['SQLALCHEMY_DATABASE_URI'])
|
|
if url.drivername == 'postgres':
|
|
url.drivername = 'postgresql'
|
|
|
|
if url.drivername.startswith('mysql'):
|
|
url.query['charset'] = 'utf8mb4'
|
|
|
|
# Creates database if the database database does not exist
|
|
if not database_exists(url):
|
|
if url.drivername.startswith('mysql'):
|
|
create_database(url, encoding='utf8mb4')
|
|
else:
|
|
create_database(url)
|
|
|
|
# This allows any changes to the SQLALCHEMY_DATABASE_URI to get pushed back in
|
|
# This is mostly so we can force MySQL's charset
|
|
app.config['SQLALCHEMY_DATABASE_URI'] = str(url)
|
|
|
|
# Register database
|
|
db.init_app(app)
|
|
|
|
# Register Flask-Migrate
|
|
migrate.init_app(app, db)
|
|
|
|
# Alembic sqlite support is lacking so we should just create_all anyway
|
|
if url.drivername.startswith('sqlite'):
|
|
db.create_all()
|
|
else:
|
|
if len(db.engine.table_names()) == 0:
|
|
# This creates tables instead of db.create_all()
|
|
# Allows migrations to happen properly
|
|
migrate_upgrade()
|
|
elif 'alembic_version' not in db.engine.table_names():
|
|
# There is no alembic_version because CTFd is from before it had migrations
|
|
# Stamp it to the base migration
|
|
if confirm_upgrade():
|
|
migrate_stamp(revision='cb3cfcc47e2f')
|
|
run_upgrade()
|
|
else:
|
|
exit()
|
|
|
|
app.db = db
|
|
app.VERSION = __version__
|
|
|
|
cache.init_app(app)
|
|
app.cache = cache
|
|
|
|
update_check()
|
|
|
|
version = utils.get_config('ctf_version')
|
|
|
|
# Upgrading from an older version of CTFd
|
|
if version and (StrictVersion(version) < StrictVersion(__version__)):
|
|
if confirm_upgrade():
|
|
run_upgrade()
|
|
else:
|
|
exit()
|
|
|
|
if not utils.get_config('ctf_theme'):
|
|
utils.set_config('ctf_theme', 'core')
|
|
|
|
from CTFd.views import views
|
|
from CTFd.challenges import challenges
|
|
from CTFd.scoreboard import scoreboard
|
|
from CTFd.auth import auth
|
|
from CTFd.admin import admin, admin_statistics, admin_challenges, admin_pages, admin_scoreboard, admin_keys, admin_teams
|
|
from CTFd.utils import init_utils, init_errors, init_logs
|
|
|
|
init_utils(app)
|
|
init_errors(app)
|
|
init_logs(app)
|
|
|
|
app.register_blueprint(views)
|
|
app.register_blueprint(challenges)
|
|
app.register_blueprint(scoreboard)
|
|
app.register_blueprint(auth)
|
|
|
|
app.register_blueprint(admin)
|
|
app.register_blueprint(admin_statistics)
|
|
app.register_blueprint(admin_challenges)
|
|
app.register_blueprint(admin_teams)
|
|
app.register_blueprint(admin_scoreboard)
|
|
app.register_blueprint(admin_keys)
|
|
app.register_blueprint(admin_pages)
|
|
|
|
from CTFd.plugins import init_plugins
|
|
|
|
init_plugins(app)
|
|
|
|
return app
|