From b1c09e832e3f6a221a4359489910a4c307e28c50 Mon Sep 17 00:00:00 2001 From: CodeKevin Date: Sat, 24 Jan 2015 03:50:45 -0500 Subject: [PATCH] Listing DO hosts Swapped out API wrappers --- CTFd/admin.py | 59 +++++++++++++++++++---------------- CTFd/utils.py | 27 +++++++++++++++- requirements.txt | 2 +- templates/admin/base.html | 63 ++++++++++++++++++++++---------------- templates/admin/hosts.html | 50 ++++++++++++++++++++++++++++++ 5 files changed, 146 insertions(+), 55 deletions(-) create mode 100644 templates/admin/hosts.html diff --git a/CTFd/admin.py b/CTFd/admin.py index eff0f59..d426edf 100644 --- a/CTFd/admin.py +++ b/CTFd/admin.py @@ -1,5 +1,5 @@ from flask import render_template, request, redirect, abort, jsonify, url_for, session -from CTFd.utils import sha512, is_safe_url, authed, admins_only, is_admin, unix_time, unix_time_millis +from CTFd.utils import sha512, is_safe_url, authed, admins_only, is_admin, unix_time, unix_time_millis, get_config, set_config, get_digitalocean from CTFd.models import db, Teams, Solves, Challenges, WrongKeys, Keys, Tags, Files, Tracking, Pages, Config from itsdangerous import TimedSerializer, BadTimeSignature from werkzeug.utils import secure_filename @@ -59,6 +59,8 @@ def init_admin(app): view_challenges_unregistered = None prevent_registration = None + do_api_key = set_config("do_api_key", request.form.get('do_api_key', None)) + db_start = Config.query.filter_by(key='start').first() db_start.value = start @@ -79,39 +81,31 @@ def init_admin(app): db.session.commit() return redirect('/admin/config') - start = Config.query.filter_by(key="start").first() - if start: - start = start.value - else: - start = Config('start', None) - db.session.add(start) + do_api_key = get_config('do_api_key') + if not do_api_key: + set_config('do_api_key', None) - end = Config.query.filter_by(key="end").first() - if end: - end = end.value - else: - end = Config('end', None) - db.session.add(end) + start = get_config('start') + if not start: + set_config('start', None) - view_challenges_unregistered = Config.query.filter_by(key='view_challenges_unregistered').first() - if view_challenges_unregistered: - view_challenges_unregistered = (view_challenges_unregistered.value == '1') - else: - view_challenges_unregistered = Config('view_challenges_unregistered', None) - db.session.add(view_challenges_unregistered) + end = get_config('end') + if not end: + set_config('end', None) - prevent_registration = Config.query.filter_by(key='prevent_registration').first() - if prevent_registration: - prevent_registration = (prevent_registration.value == '1') - else: - prevent_registration = Config('prevent_registration', None) - db.session.add(prevent_registration) + view_challenges_unregistered = get_config('view_challenges_unregistered') == '1' + if not view_challenges_unregistered: + set_config('view_challenges_unregistered', None) + + prevent_registration = get_config('prevent_registration') == '1' + if not prevent_registration: + set_config('prevent_registration', None) db.session.commit() db.session.close() return render_template('admin/config.html', start=start, end=end, view_challenges_unregistered=view_challenges_unregistered, - prevent_registration=prevent_registration) + prevent_registration=prevent_registration, do_api_key=do_api_key) @app.route('/admin/pages', defaults={'route': None}, methods=['GET', 'POST']) @app.route('/admin/pages/', methods=['GET', 'POST']) @@ -148,7 +142,18 @@ def init_admin(app): @app.route('/admin/hosts', methods=['GET']) @admins_only def admin_hosts(): - return render_template('admin/hosts.html') + m = get_digitalocean() + errors = [] + if not m: + errors.append("Your Digital Ocean API key is not set") + return render_template('admin/hosts.html', errors=errors) + + hosts = m.get_all_droplets() + slugs = m.get_all_sizes() + images = m.get_all_images() + regions = m.get_all_regions() + + return render_template('admin/hosts.html', hosts=hosts, slugs=slugs, images=images, regions=regions) @app.route('/admin/chals', methods=['POST', 'GET']) @admins_only diff --git a/CTFd/utils.py b/CTFd/utils.py index 927ed33..3daedb5 100644 --- a/CTFd/utils.py +++ b/CTFd/utils.py @@ -11,7 +11,7 @@ from struct import unpack, pack import time import datetime import hashlib -import json +import digitalocean def init_utils(app): app.jinja_env.filters['unix_time'] = unix_time @@ -40,6 +40,7 @@ def is_admin(): else: return False + def can_register(): config = Config.query.filter_by(key='prevent_registration').first() if config: @@ -111,6 +112,23 @@ def get_kpm(teamid): # keys per minute one_min_ago = datetime.datetime.utcnow() + datetime.timedelta(minutes=-1) return len(db.session.query(WrongKeys).filter(WrongKeys.team == teamid, WrongKeys.date >= one_min_ago).all()) +def get_config(key): + config = Config.query.filter_by(key=key).first() + if config: + return config.value + else: + return None + +def set_config(key, value): + config = Config.query.filter_by(key=key).first() + if config: + config.value = value + else: + config = Config(key, value) + db.session.add(config) + db.session.commit() + return config + def mailserver(): if app.config['MAIL_SERVER'] and app.config['MAIL_PORT'] and app.config['ADMINS']: @@ -133,3 +151,10 @@ def is_safe_url(target): def sha512(string): return hashlib.sha512(string).hexdigest() + +def get_digitalocean(): + token = get_config('do_api_key') + if token: + return digitalocean.Manager(token=token) + else: + return False \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 20ae0cd..9f3f23c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,4 +8,4 @@ passlib==1.6.2 py-bcrypt==0.4 six==1.8.0 itsdangerous -dop \ No newline at end of file +python-digitalocean \ No newline at end of file diff --git a/templates/admin/base.html b/templates/admin/base.html index 7d57489..367cf48 100644 --- a/templates/admin/base.html +++ b/templates/admin/base.html @@ -1,5 +1,6 @@ + @@ -10,45 +11,55 @@ + - {% block content %} - {% endblock %} + {% block content %} {% endblock %} - {% block scripts %} - {% endblock %} + {% block scripts %} {% endblock %} + \ No newline at end of file diff --git a/templates/admin/hosts.html b/templates/admin/hosts.html new file mode 100644 index 0000000..8223ef5 --- /dev/null +++ b/templates/admin/hosts.html @@ -0,0 +1,50 @@ +{% extends "admin/base.html" %} + +{% block content %} +
+
+

Hosts

+
+ {% for error in errors %} +
+
+ {{ error }} + × +
+
+ {% endfor %} + + + + + + + + + + + + + {% for host in hosts %} + + + + + + + + + {% endfor %} + +
ID + Status + Name + IP Address + Memory + Disk +
{{ host.id }}{{ host.status }}{{ host.name }}{{ host.ip_address }}{{ host.memory }} MB{{ host.disk }} GB
+
+{% endblock %} + +{% block scripts %} +{% endblock %} \ No newline at end of file