mirror of
https://github.com/aljazceru/CTFd.git
synced 2025-12-17 14:04:20 +01:00
Adding functions to register plugin assets (#397)
* Adds functions to register plugin assets
This commit is contained in:
@@ -2,8 +2,60 @@ import glob
|
||||
import importlib
|
||||
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):
|
||||
"""
|
||||
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__) + "/*")
|
||||
blacklist = {'keys', 'challenges', '__pycache__'}
|
||||
for module in modules:
|
||||
|
||||
@@ -17,19 +17,24 @@ def create_ctfd(ctf_name="CTFd", name="admin", email="admin@ctfd.io", password="
|
||||
app = create_app('CTFd.config.TestingConfig')
|
||||
|
||||
if setup:
|
||||
with app.app_context():
|
||||
with app.test_client() as client:
|
||||
data = {}
|
||||
r = client.get('/setup') # Populate session with nonce
|
||||
with client.session_transaction() as sess:
|
||||
data = {
|
||||
"ctf_name": ctf_name,
|
||||
"name": name,
|
||||
"email": email,
|
||||
"password": password,
|
||||
"nonce": sess.get('nonce')
|
||||
}
|
||||
client.post('/setup', data=data)
|
||||
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.test_client() as client:
|
||||
data = {}
|
||||
r = client.get('/setup') # Populate session with nonce
|
||||
with client.session_transaction() as sess:
|
||||
data = {
|
||||
"ctf_name": ctf_name,
|
||||
"name": name,
|
||||
"email": email,
|
||||
"password": password,
|
||||
"nonce": sess.get('nonce')
|
||||
}
|
||||
client.post('/setup', data=data)
|
||||
return app
|
||||
|
||||
|
||||
|
||||
39
tests/test_plugin_utils.py
Normal file
39
tests/test_plugin_utils.py
Normal 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)
|
||||
Reference in New Issue
Block a user