mirror of
https://github.com/aljazceru/CTFd.git
synced 2025-12-17 14:04:20 +01:00
Adds plugin functions to register javascript and CSS in the admin panel. Move global plugin script/stylesheet lists into application factory specific lists. Closes #804 (#805)
* Adds plugin functions to register javascript and CSS in the admin panel * Move global plugin script/stylesheet lists into application factory specific lists * Closes #804
This commit is contained in:
@@ -3,20 +3,19 @@ import importlib
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from flask.helpers import safe_join
|
|
||||||
from flask import current_app as app, send_file, send_from_directory, abort
|
from flask import current_app as app, send_file, send_from_directory, abort
|
||||||
from CTFd.utils.decorators import admins_only as admins_only_wrapper
|
from CTFd.utils.decorators import admins_only as admins_only_wrapper
|
||||||
from CTFd.utils.plugins import (
|
from CTFd.utils.plugins import (
|
||||||
override_template as utils_override_template,
|
override_template as utils_override_template,
|
||||||
register_script as utils_register_plugin_script,
|
register_script as utils_register_plugin_script,
|
||||||
register_stylesheet as utils_register_plugin_stylesheet,
|
register_stylesheet as utils_register_plugin_stylesheet,
|
||||||
|
register_admin_script as utils_register_admin_plugin_script,
|
||||||
|
register_admin_stylesheet as utils_register_admin_plugin_stylesheet
|
||||||
)
|
)
|
||||||
from CTFd.utils.config.pages import get_pages
|
from CTFd.utils.config.pages import get_pages
|
||||||
|
|
||||||
|
|
||||||
Menu = namedtuple('Menu', ['title', 'route'])
|
Menu = namedtuple('Menu', ['title', 'route'])
|
||||||
ADMIN_PLUGIN_MENU_BAR = []
|
|
||||||
USER_PAGE_MENU_BAR = []
|
|
||||||
|
|
||||||
|
|
||||||
def register_plugin_assets_directory(app, base_path, admins_only=False):
|
def register_plugin_assets_directory(app, base_path, admins_only=False):
|
||||||
@@ -83,6 +82,26 @@ def register_plugin_stylesheet(*args, **kwargs):
|
|||||||
utils_register_plugin_stylesheet(*args, **kwargs)
|
utils_register_plugin_stylesheet(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def register_admin_plugin_script(*args, **kwargs):
|
||||||
|
"""
|
||||||
|
Adds a given script to the base.html of the admin theme which all admin pages inherit from
|
||||||
|
:param args:
|
||||||
|
:param kwargs:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
utils_register_admin_plugin_script(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def register_admin_plugin_stylesheet(*args, **kwargs):
|
||||||
|
"""
|
||||||
|
Adds a given stylesheet to the base.html of the admin theme which all admin pages inherit from
|
||||||
|
:param args:
|
||||||
|
:param kwargs:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
utils_register_admin_plugin_stylesheet(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def register_admin_plugin_menu_bar(title, route):
|
def register_admin_plugin_menu_bar(title, route):
|
||||||
"""
|
"""
|
||||||
Registers links on the Admin Panel menubar/navbar
|
Registers links on the Admin Panel menubar/navbar
|
||||||
@@ -92,7 +111,7 @@ def register_admin_plugin_menu_bar(title, route):
|
|||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
am = Menu(title=title, route=route)
|
am = Menu(title=title, route=route)
|
||||||
ADMIN_PLUGIN_MENU_BAR.append(am)
|
app.admin_plugin_menu_bar.append(am)
|
||||||
|
|
||||||
|
|
||||||
def get_admin_plugin_menu_bar():
|
def get_admin_plugin_menu_bar():
|
||||||
@@ -101,7 +120,7 @@ def get_admin_plugin_menu_bar():
|
|||||||
|
|
||||||
:return: Returns a list of Menu namedtuples. They have name, and route attributes.
|
:return: Returns a list of Menu namedtuples. They have name, and route attributes.
|
||||||
"""
|
"""
|
||||||
return ADMIN_PLUGIN_MENU_BAR
|
return app.admin_plugin_menu_bar
|
||||||
|
|
||||||
|
|
||||||
def register_user_page_menu_bar(title, route):
|
def register_user_page_menu_bar(title, route):
|
||||||
@@ -113,7 +132,7 @@ def register_user_page_menu_bar(title, route):
|
|||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
p = Menu(title=title, route=route)
|
p = Menu(title=title, route=route)
|
||||||
USER_PAGE_MENU_BAR.append(p)
|
app.plugin_menu_bar.append(p)
|
||||||
|
|
||||||
|
|
||||||
def get_user_page_menu_bar():
|
def get_user_page_menu_bar():
|
||||||
@@ -122,7 +141,7 @@ def get_user_page_menu_bar():
|
|||||||
|
|
||||||
:return: Returns a list of Menu namedtuples. They have name, and route attributes.
|
:return: Returns a list of Menu namedtuples. They have name, and route attributes.
|
||||||
"""
|
"""
|
||||||
return get_pages() + USER_PAGE_MENU_BAR
|
return get_pages() + app.plugin_menu_bar
|
||||||
|
|
||||||
|
|
||||||
def bypass_csrf_protection(f):
|
def bypass_csrf_protection(f):
|
||||||
@@ -146,6 +165,14 @@ def init_plugins(app):
|
|||||||
:param app: A CTFd application
|
:param app: A CTFd application
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
|
app.admin_plugin_scripts = []
|
||||||
|
app.admin_plugin_stylesheets = []
|
||||||
|
app.plugin_scripts = []
|
||||||
|
app.plugin_stylesheets = []
|
||||||
|
|
||||||
|
app.admin_plugin_menu_bar = []
|
||||||
|
app.plugin_menu_bar = []
|
||||||
|
|
||||||
if app.config.get('SAFE_MODE', False) is False:
|
if app.config.get('SAFE_MODE', False) is False:
|
||||||
modules = sorted(glob.glob(os.path.dirname(__file__) + "/*"))
|
modules = sorted(glob.glob(os.path.dirname(__file__) + "/*"))
|
||||||
blacklist = {'__pycache__'}
|
blacklist = {'__pycache__'}
|
||||||
|
|||||||
@@ -25,6 +25,15 @@
|
|||||||
var user_mode = "{{ get_config('user_mode') }}";
|
var user_mode = "{{ get_config('user_mode') }}";
|
||||||
</script>
|
</script>
|
||||||
{% block stylesheets %} {% endblock %}
|
{% block stylesheets %} {% endblock %}
|
||||||
|
{% for stylesheet in get_registered_admin_stylesheets() %}
|
||||||
|
{% if stylesheet.startswith('http') %}
|
||||||
|
<link rel="stylesheet" type="text/css" href="{{ stylesheet }}">
|
||||||
|
{% elif request.script_root %}
|
||||||
|
<link rel="stylesheet" type="text/css" href="{{ request.script_root }}/{{ stylesheet }}">
|
||||||
|
{% else %}
|
||||||
|
<link rel="stylesheet" type="text/css" href="{{ stylesheet }}">
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
@@ -135,6 +144,16 @@
|
|||||||
<script src="{{ url_for('views.themes', theme='admin', path='js/ezq.js') }}"></script>
|
<script src="{{ url_for('views.themes', theme='admin', path='js/ezq.js') }}"></script>
|
||||||
<script src="{{ url_for('views.themes', theme='admin', path='js/style.js') }}"></script>
|
<script src="{{ url_for('views.themes', theme='admin', path='js/style.js') }}"></script>
|
||||||
{% block scripts %} {% endblock %}
|
{% block scripts %} {% endblock %}
|
||||||
|
|
||||||
|
{% for script in get_registered_admin_scripts() %}
|
||||||
|
{% if script.startswith('http') %}
|
||||||
|
<script src="{{ script }}"></script>
|
||||||
|
{% elif request.script_root %}
|
||||||
|
<script src="{{ request.script_root }}/{{ script }}"></script>
|
||||||
|
{% else %}
|
||||||
|
<script src="{{ script }}"></script>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -8,7 +8,13 @@ from CTFd.utils import config
|
|||||||
from CTFd.utils.config import can_send_mail, ctf_logo, ctf_name, ctf_theme
|
from CTFd.utils.config import can_send_mail, ctf_logo, ctf_name, ctf_theme
|
||||||
from CTFd.utils.config.pages import get_pages
|
from CTFd.utils.config.pages import get_pages
|
||||||
|
|
||||||
from CTFd.utils.plugins import get_registered_stylesheets, get_registered_scripts, get_configurable_plugins
|
from CTFd.utils.plugins import (
|
||||||
|
get_registered_stylesheets,
|
||||||
|
get_registered_scripts,
|
||||||
|
get_configurable_plugins,
|
||||||
|
get_registered_admin_scripts,
|
||||||
|
get_registered_admin_stylesheets
|
||||||
|
)
|
||||||
|
|
||||||
from CTFd.utils.countries import get_countries, lookup_country_code
|
from CTFd.utils.countries import get_countries, lookup_country_code
|
||||||
from CTFd.utils.user import authed, get_ip, get_current_user, get_current_team
|
from CTFd.utils.user import authed, get_ip, get_current_user, get_current_team
|
||||||
@@ -45,6 +51,8 @@ def init_template_globals(app):
|
|||||||
app.jinja_env.globals.update(get_configurable_plugins=get_configurable_plugins)
|
app.jinja_env.globals.update(get_configurable_plugins=get_configurable_plugins)
|
||||||
app.jinja_env.globals.update(get_registered_scripts=get_registered_scripts)
|
app.jinja_env.globals.update(get_registered_scripts=get_registered_scripts)
|
||||||
app.jinja_env.globals.update(get_registered_stylesheets=get_registered_stylesheets)
|
app.jinja_env.globals.update(get_registered_stylesheets=get_registered_stylesheets)
|
||||||
|
app.jinja_env.globals.update(get_registered_admin_scripts=get_registered_admin_scripts)
|
||||||
|
app.jinja_env.globals.update(get_registered_admin_stylesheets=get_registered_admin_stylesheets)
|
||||||
app.jinja_env.globals.update(get_config=get_config)
|
app.jinja_env.globals.update(get_config=get_config)
|
||||||
app.jinja_env.globals.update(generate_account_url=generate_account_url)
|
app.jinja_env.globals.update(generate_account_url=generate_account_url)
|
||||||
app.jinja_env.globals.update(get_countries=get_countries)
|
app.jinja_env.globals.update(get_countries=get_countries)
|
||||||
|
|||||||
@@ -4,24 +4,36 @@ import os
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
|
|
||||||
SCRIPTS = []
|
|
||||||
STYLESHEETS = []
|
|
||||||
|
|
||||||
|
|
||||||
def register_script(url):
|
def register_script(url):
|
||||||
SCRIPTS.append(url)
|
app.plugin_scripts.append(url)
|
||||||
|
|
||||||
|
|
||||||
def register_stylesheet(url):
|
def register_stylesheet(url):
|
||||||
STYLESHEETS.append(url)
|
app.plugin_stylesheets.append(url)
|
||||||
|
|
||||||
|
|
||||||
|
def register_admin_script(url):
|
||||||
|
app.admin_plugin_scripts.append(url)
|
||||||
|
|
||||||
|
|
||||||
|
def register_admin_stylesheet(url):
|
||||||
|
app.admin_plugin_stylesheets.append(url)
|
||||||
|
|
||||||
|
|
||||||
def get_registered_scripts():
|
def get_registered_scripts():
|
||||||
return SCRIPTS
|
return app.plugin_scripts
|
||||||
|
|
||||||
|
|
||||||
def get_registered_stylesheets():
|
def get_registered_stylesheets():
|
||||||
return STYLESHEETS
|
return app.plugin_stylesheets
|
||||||
|
|
||||||
|
|
||||||
|
def get_registered_admin_scripts():
|
||||||
|
return app.admin_plugin_scripts
|
||||||
|
|
||||||
|
|
||||||
|
def get_registered_admin_stylesheets():
|
||||||
|
return app.admin_plugin_stylesheets
|
||||||
|
|
||||||
|
|
||||||
def override_template(template, html):
|
def override_template(template, html):
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ from CTFd.plugins import (
|
|||||||
register_plugin_asset,
|
register_plugin_asset,
|
||||||
register_plugin_script,
|
register_plugin_script,
|
||||||
register_plugin_stylesheet,
|
register_plugin_stylesheet,
|
||||||
|
register_admin_plugin_script,
|
||||||
|
register_admin_plugin_stylesheet,
|
||||||
override_template,
|
override_template,
|
||||||
register_admin_plugin_menu_bar,
|
register_admin_plugin_menu_bar,
|
||||||
get_admin_plugin_menu_bar,
|
get_admin_plugin_menu_bar,
|
||||||
@@ -77,7 +79,7 @@ def test_admin_override_template():
|
|||||||
|
|
||||||
|
|
||||||
def test_register_plugin_script():
|
def test_register_plugin_script():
|
||||||
'''Test that register_plugin_script adds script paths to the core theme when used from a plugin'''
|
"""Test that register_plugin_script adds script paths to the core theme when used from a plugin"""
|
||||||
app = create_ctfd()
|
app = create_ctfd()
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
register_plugin_script('/fake/script/path.js')
|
register_plugin_script('/fake/script/path.js')
|
||||||
@@ -91,7 +93,7 @@ def test_register_plugin_script():
|
|||||||
|
|
||||||
|
|
||||||
def test_register_plugin_stylesheet():
|
def test_register_plugin_stylesheet():
|
||||||
'''Test that register_plugin_stylesheet adds stylesheet paths to the core theme when used from a plugin'''
|
"""Test that register_plugin_stylesheet adds stylesheet paths to the core theme when used from a plugin"""
|
||||||
app = create_ctfd()
|
app = create_ctfd()
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
register_plugin_script('/fake/stylesheet/path.css')
|
register_plugin_script('/fake/stylesheet/path.css')
|
||||||
@@ -104,6 +106,34 @@ def test_register_plugin_stylesheet():
|
|||||||
destroy_ctfd(app)
|
destroy_ctfd(app)
|
||||||
|
|
||||||
|
|
||||||
|
def test_register_admin_plugin_script():
|
||||||
|
"""Test that register_admin_plugin_script adds script paths to the admin theme when used from a plugin"""
|
||||||
|
app = create_ctfd()
|
||||||
|
with app.app_context():
|
||||||
|
register_admin_plugin_script('/fake/script/path.js')
|
||||||
|
register_admin_plugin_script('http://ctfd.io/fake/script/path.js')
|
||||||
|
with login_as_user(app, name="admin") as client:
|
||||||
|
r = client.get('/admin/statistics')
|
||||||
|
output = r.get_data(as_text=True)
|
||||||
|
assert '/fake/script/path.js' in output
|
||||||
|
assert 'http://ctfd.io/fake/script/path.js' in output
|
||||||
|
destroy_ctfd(app)
|
||||||
|
|
||||||
|
|
||||||
|
def test_register_admin_plugin_stylesheet():
|
||||||
|
"""Test that register_admin_plugin_stylesheet adds stylesheet paths to the admin theme when used from a plugin"""
|
||||||
|
app = create_ctfd()
|
||||||
|
with app.app_context():
|
||||||
|
register_admin_plugin_stylesheet('/fake/stylesheet/path.css')
|
||||||
|
register_admin_plugin_stylesheet('http://ctfd.io/fake/stylesheet/path.css')
|
||||||
|
with login_as_user(app, name="admin") as client:
|
||||||
|
r = client.get('/admin/statistics')
|
||||||
|
output = r.get_data(as_text=True)
|
||||||
|
assert '/fake/stylesheet/path.css' in output
|
||||||
|
assert 'http://ctfd.io/fake/stylesheet/path.css' in output
|
||||||
|
destroy_ctfd(app)
|
||||||
|
|
||||||
|
|
||||||
def test_register_admin_plugin_menu_bar():
|
def test_register_admin_plugin_menu_bar():
|
||||||
"""
|
"""
|
||||||
Test that register_admin_plugin_menu_bar() properly inserts into HTML and get_admin_plugin_menu_bar()
|
Test that register_admin_plugin_menu_bar() properly inserts into HTML and get_admin_plugin_menu_bar()
|
||||||
|
|||||||
Reference in New Issue
Block a user