Adding functions to register plugin assets (#397)

* Adds functions to register plugin assets
This commit is contained in:
Kevin Chung
2017-09-29 21:22:10 -04:00
committed by GitHub
parent 0aae79d176
commit faa84ff1e5
3 changed files with 109 additions and 13 deletions

View File

@@ -2,8 +2,60 @@ import glob
import importlib import importlib
import os import os
from flask.helpers import safe_join
from flask import send_file, send_from_directory, abort
from CTFd.utils import admins_only as admins_only_wrapper
def register_plugin_assets_directory(app, base_path, admins_only=False):
"""
Registers a directory to serve assets
:param app: A CTFd application
:param string base_path: The path to the directory
:param boolean admins_only: Whether or not the assets served out of the directory should be accessible to the public
:return:
"""
base_path = base_path.strip('/')
def assets_handler(path):
return send_from_directory(base_path, path)
if admins_only:
asset_handler = admins_only_wrapper(assets_handler)
rule = '/' + base_path + '/<path:path>'
app.add_url_rule(rule=rule, endpoint=base_path, view_func=assets_handler)
def register_plugin_asset(app, asset_path, admins_only=False):
"""
Registers an file path to be served by CTFd
:param app: A CTFd application
:param string asset_path: The path to the asset file
:param boolean admins_only: Whether or not this file should be accessible to the public
:return:
"""
asset_path = asset_path.strip('/')
def asset_handler():
return send_file(asset_path)
if admins_only:
asset_handler = admins_only_wrapper(asset_handler)
rule = '/' + asset_path
app.add_url_rule(rule=rule, endpoint=asset_path, view_func=asset_handler)
def init_plugins(app): def init_plugins(app):
"""
Searches for the load function in modules in the CTFd/plugins folder. This function is called with the current CTFd
app as a parameter. This allows CTFd plugins to modify CTFd's behavior.
:param app: A CTFd application
:return:
"""
modules = glob.glob(os.path.dirname(__file__) + "/*") modules = glob.glob(os.path.dirname(__file__) + "/*")
blacklist = {'keys', 'challenges', '__pycache__'} blacklist = {'keys', 'challenges', '__pycache__'}
for module in modules: for module in modules:

View File

@@ -17,6 +17,11 @@ def create_ctfd(ctf_name="CTFd", name="admin", email="admin@ctfd.io", password="
app = create_app('CTFd.config.TestingConfig') app = create_app('CTFd.config.TestingConfig')
if setup: if setup:
app = setup_ctfd(app, ctf_name, name, email, password)
return app
def setup_ctfd(app, ctf_name="CTFd", name="admin", email="admin@ctfd.io", password="password"):
with app.app_context(): with app.app_context():
with app.test_client() as client: with app.test_client() as client:
data = {} data = {}

View File

@@ -0,0 +1,39 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from tests.helpers import *
from CTFd.models import ip2long, long2ip
from CTFd.plugins import register_plugin_assets_directory, register_plugin_asset
from freezegun import freeze_time
from mock import patch
import json
import six
def test_register_plugin_asset():
"""Test that plugin asset registration works"""
app = create_ctfd(setup=False)
register_plugin_asset(app, asset_path='/plugins/__init__.py')
app = setup_ctfd(app)
with app.app_context():
with app.test_client() as client:
r = client.get('/plugins/__init__.py')
assert len(r.get_data(as_text=True)) > 0
assert r.status_code == 200
destroy_ctfd(app)
def test_register_plugin_assets_directory():
"""Test that plugin asset directory registration works"""
app = create_ctfd(setup=False)
register_plugin_assets_directory(app, base_path='/plugins/')
app = setup_ctfd(app)
with app.app_context():
with app.test_client() as client:
r = client.get('/plugins/__init__.py')
assert len(r.get_data(as_text=True)) > 0
assert r.status_code == 200
r = client.get('/plugins/challenges/__init__.py')
assert len(r.get_data(as_text=True)) > 0
assert r.status_code == 200
destroy_ctfd(app)