Files
CTFd/CTFd/__init__.py
Kevin Chung 3af98b17d5 Version 1.1 CTFd (#514)
* 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
2017-12-11 06:42:07 -05:00

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