Listing DO hosts

Swapped out API wrappers
selenium-screenshot-testing
CodeKevin 2015-01-24 03:50:45 -05:00
parent 6b81ac4577
commit b1c09e832e
5 changed files with 146 additions and 55 deletions

View File

@ -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/<route>', 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

View File

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

View File

@ -8,4 +8,4 @@ passlib==1.6.2
py-bcrypt==0.4
six==1.8.0
itsdangerous
dop
python-digitalocean

View File

@ -1,5 +1,6 @@
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8">
@ -10,45 +11,55 @@
<link rel="stylesheet" type="text/css" href="/static/admin/css/style.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.5.1/moment.min.js"></script>
</head>
<body>
<nav class="top-bar" data-topbar>
<ul class="title-area">
<li class="name">
<h1><a href="/">CTF</a></h1>
</li>
<li class="toggle-topbar menu-icon"><a href="#">Menu</a></li>
</ul>
<section class="top-bar-section">
<!-- Right Nav Section -->
<ul class="right">
<ul class="title-area">
<li class="name">
<h1><a href="/">CTF</a></h1>
</li>
<li class="toggle-topbar menu-icon"><a href="#">Menu</a>
</li>
</ul>
<!-- Left Nav Section -->
<ul class="left">
<li><a href="/admin/graphs">Graphs</a></li>
<li><a href="/admin/pages">Pages</a></li>
<li><a href="/admin/teams">Teams</a></li>
<li><a href="/admin/scoreboard">Scoreboard</a></li>
<li><a href="/admin/chals">Challenges</a></li>
<li><a href="/admin/statistics">Statistics</a></li>
<li><a href="/admin/config">Config</a></li>
</ul>
</section>
<section class="top-bar-section">
<!-- Right Nav Section -->
<ul class="right">
</li>
</ul>
<!-- Left Nav Section -->
<ul class="left">
<li><a href="/admin/graphs">Graphs</a>
</li>
<li><a href="/admin/pages">Pages</a>
</li>
<li><a href="/admin/hosts">Hosts</a>
</li>
<li><a href="/admin/teams">Teams</a>
</li>
<li><a href="/admin/scoreboard">Scoreboard</a>
</li>
<li><a href="/admin/chals">Challenges</a>
</li>
<li><a href="/admin/statistics">Statistics</a>
</li>
<li><a href="/admin/config">Config</a>
</li>
</ul>
</section>
</nav>
{% block content %}
{% endblock %}
{% block content %} {% endblock %}
<script src="//cdnjs.cloudflare.com/ajax/libs/foundation/5.4.7/js/vendor/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/foundation/5.4.7/js/vendor/modernizr.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/pagedown/1.0/Markdown.Converter.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/foundation/5.4.7/js/foundation.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/foundation/5.4.7/js/foundation/foundation.topbar.min.js"></script>
<script>
$(document).foundation();
$(document).foundation();
</script>
{% block scripts %}
{% endblock %}
{% block scripts %} {% endblock %}
</body>
</html>

View File

@ -0,0 +1,50 @@
{% extends "admin/base.html" %}
{% block content %}
<div class="row">
<br>
<h1>Hosts</h1>
<br>
{% for error in errors %}
<div class="large-8 large-centered columns">
<div data-alert class="alert-box alert radius centered text-center">
<span>{{ error }}</span>
<a href="#" class="close">×</a>
</div>
</div>
{% endfor %}
<table id="teamsboard">
<thead>
<tr>
<td><b>ID</b>
</td>
<td><b>Status</b>
</td>
<td><b>Name</b>
</td>
<td><b>IP Address</b>
</td>
<td><b>Memory</b>
</td>
<td><b>Disk</b>
</td>
</tr>
</thead>
<tbody>
{% for host in hosts %}
<tr>
<td>{{ host.id }}</td>
<td>{{ host.status }}</td>
<td>{{ host.name }}</td>
<td>{{ host.ip_address }}</td>
<td>{{ host.memory }} <sub>MB</sub></td>
<td>{{ host.disk }} <sub>GB</sub></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
{% block scripts %}
{% endblock %}