Adding a rudimentary plugin configuration page (#219)

* Adding a rudimentary plugin configuration page

* Streamlining changes
selenium-screenshot-testing
Kevin Chung 2017-03-07 01:07:32 -05:00 committed by GitHub
parent e237715b33
commit c1e9cffc94
4 changed files with 113 additions and 3 deletions

View File

@ -2,13 +2,14 @@ import hashlib
import json
import os
from flask import current_app as app, render_template, request, redirect, jsonify, url_for, Blueprint
from flask import current_app as app, render_template, request, redirect, jsonify, url_for, Blueprint, \
abort, render_template_string
from passlib.hash import bcrypt_sha256
from sqlalchemy.sql import not_
from CTFd.utils import admins_only, is_admin, unix_time, get_config, \
set_config, sendmail, rmdir, create_image, delete_image, run_image, container_status, container_ports, \
container_stop, container_start, get_themes, cache, upload_file
container_stop, container_start, get_themes, cache, upload_file, get_configurable_plugins
from CTFd.models import db, Teams, Solves, Awards, Containers, Challenges, WrongKeys, Keys, Tags, Files, Tracking, Pages, Config, DatabaseError
from CTFd.scoreboard import get_standings
from CTFd.plugins.keys import get_key_class, KEY_CLASSES
@ -33,6 +34,20 @@ def admin_view():
return redirect(url_for('auth.login'))
@admin.route('/admin/plugins/<plugin>', methods=['GET', 'POST'])
@admins_only
def admin_plugin_config(plugin):
if request.method == 'GET':
if plugin in get_configurable_plugins():
config = open(os.path.join(app.root_path, 'plugins', plugin, 'config.html')).read()
return render_template('admin/page.html', content=config)
abort(404)
elif request.method == 'POST':
for k, v in request.form.items():
set_config(k, v)
return '1'
@admin.route('/admin/config', methods=['GET', 'POST'])
@admins_only
def admin_config():
@ -160,4 +175,4 @@ def admin_config():
prevent_name_change=prevent_name_change,
verify_emails=verify_emails,
view_after_ctf=view_after_ctf,
themes=themes)
themes=themes)

View File

@ -53,6 +53,14 @@
<li><a href="{{ request.script_root }}/admin/chals">Challenges</a></li>
<li><a href="{{ request.script_root }}/admin/statistics">Statistics</a></li>
<li><a href="{{ request.script_root }}/admin/config">Config</a></li>
<li>
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Plugins <span class="caret"></span></a>
<ul class="dropdown-menu">
{% for plugin in get_configurable_plugins() %}
<li><a href="{{ request.script_root }}/admin/plugins/{{ plugin }}">{{ plugin }}</a></li>
{% endfor %}
</ul>
</li>
</ul>
</div>
</div>

View File

@ -0,0 +1,79 @@
<!DOCTYPE html>
<html>
<head>
<title>Admin Panel</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="{{ request.script_root }}/static/original/img/favicon.ico" type="image/x-icon">
<link rel="icon" href="{{ request.script_root }}/static/original/img/favicon.ico" type="image/x-icon">
<link rel="stylesheet" href="{{ request.script_root }}/static/admin/css/vendor/bootstrap.min.css">
<link rel="stylesheet" href="{{ request.script_root }}/static/admin/css/vendor/font-awesome/css/font-awesome.min.css" />
<link rel="stylesheet" href="{{ request.script_root }}/static/admin/css/style.css">
<link href='{{ request.script_root }}/static/admin/css/vendor/lato.css' rel='stylesheet' type='text/css'>
<link href='{{ request.script_root }}/static/admin/css/vendor/raleway.css' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="{{ request.script_root }}/static/admin/css/style.css">
<script src="{{ request.script_root }}/static/admin/js/vendor/moment.min.js"></script>
<script src="{{ request.script_root }}/static/admin/js/vendor/moment-timezone-with-data.min.js"></script>
<script src="{{ request.script_root }}/static/admin/js/vendor/handlebars.min.js"></script>
<script type="text/javascript">
var script_root = "{{ request.script_root }}";
</script>
{% block stylesheets %} {% endblock %}
</head>
<body>
<div class="body-container">
<div class="navbar navbar-inverse home">
<div class="container">
<div class="navbar-header">
<button class="navbar-toggle" data-target=".navbar-collapse" data-toggle="collapse" type="button">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a href="{{ request.script_root }}/" class="navbar-brand">CTFd</a>
</div>
<div class="navbar-collapse collapse" aria-expanded="false" style="height: 0px">
<ul class="nav navbar-nav navbar-nav-right">
<li><a href="{{ request.script_root }}/admin/graphs">Graphs</a></li>
<li>
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">Pages <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="{{ request.script_root }}/admin/pages">All Pages</a></li>
<li><a href="{{ request.script_root }}/admin/pages?mode=create">New Page</a></li>
</ul>
</li>
<li><a href="{{ request.script_root }}/admin/teams">Teams</a></li>
<li><a href="{{ request.script_root }}/admin/scoreboard">Scoreboard</a></li>
{% if can_create_container() %}
<li><a href="{{ request.script_root }}/admin/containers">Containers</a></li>
{% endif %}
<li><a href="{{ request.script_root }}/admin/chals">Challenges</a></li>
<li><a href="{{ request.script_root }}/admin/statistics">Statistics</a></li>
<li><a href="{{ request.script_root }}/admin/config">Config</a></li>
<li>
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Plugins <span class="caret"></span></a>
<ul class="dropdown-menu">
{% for plugin in get_configurable_plugins() %}
<li><a href="{{ request.script_root }}/admin/plugins/{{ plugin }}">{{ plugin }}</a></li>
{% endfor %}
</ul>
</li>
</ul>
</div>
</div>
</div>
<div class="container">
{{ content | safe }}
</div>
</div>
<script src="{{ request.script_root }}/static/admin/js/vendor/jquery.min.js"></script>
<script src="{{ request.script_root }}/static/admin/js/vendor/marked.min.js"></script>
<script src="{{ request.script_root }}/static/admin/js/vendor/bootstrap.min.js"></script>
{% block scripts %} {% endblock %}
</body>
</html>

View File

@ -100,6 +100,8 @@ def init_utils(app):
app.jinja_env.globals.update(ctf_name=ctf_name)
app.jinja_env.globals.update(ctf_theme=ctf_theme)
app.jinja_env.globals.update(can_create_container=can_create_container)
app.jinja_env.globals.update(get_configurable_plugins=get_configurable_plugins)
app.jinja_env.globals.update(get_config=get_config)
@app.context_processor
def inject_user():
@ -300,6 +302,12 @@ def get_themes():
if os.path.isdir(os.path.join(dir, name)) and name != 'admin']
def get_configurable_plugins():
dir = os.path.join(app.root_path, 'plugins')
return [name for name in os.listdir(dir)
if os.path.isfile(os.path.join(dir, name, 'config.html'))]
def upload_file(file, chalid):
filename = secure_filename(file.filename)