mirror of
https://github.com/aljazceru/CTFd.git
synced 2026-02-14 02:34:23 +01:00
Merge branch 'master' into 3.1.0-dev
This commit is contained in:
11
CHANGELOG.md
11
CHANGELOG.md
@@ -1,3 +1,14 @@
|
||||
# 3.0.2 / 2020-08-23
|
||||
|
||||
**Admin Panel**
|
||||
|
||||
- Fix submission searching in Admin Panel
|
||||
- Fix update banner being hidden behind navbar
|
||||
|
||||
**Plugins**
|
||||
|
||||
- Change default `input` & `submit` blocks in `challenge.html` to use the default values specified in the original challenge type plugins
|
||||
|
||||
# 3.0.1 / 2020-08-12
|
||||
|
||||
**General**
|
||||
|
||||
@@ -26,7 +26,7 @@ from CTFd.utils.migrations import create_database, migrations, stamp_latest_revi
|
||||
from CTFd.utils.sessions import CachingSessionInterface
|
||||
from CTFd.utils.updates import update_check
|
||||
|
||||
__version__ = "3.0.1"
|
||||
__version__ = "3.0.2"
|
||||
__channel__ = "oss"
|
||||
|
||||
|
||||
|
||||
@@ -100,8 +100,7 @@ class ServerConfig(object):
|
||||
CACHE_THRESHOLD: int = 0
|
||||
|
||||
# === SECURITY ===
|
||||
SESSION_COOKIE_HTTPONLY: bool = config_ini["security"].getboolean("SESSION_COOKIE_HTTPONLY") \
|
||||
or True
|
||||
SESSION_COOKIE_HTTPONLY: bool = config_ini["security"].getboolean("SESSION_COOKIE_HTTPONLY", fallback=True)
|
||||
|
||||
SESSION_COOKIE_SAMESITE: str = empty_str_cast(config_ini["security"]["SESSION_COOKIE_SAMESITE"]) \
|
||||
or "Lax"
|
||||
@@ -173,38 +172,28 @@ class ServerConfig(object):
|
||||
AWS_S3_ENDPOINT_URL: str = empty_str_cast(config_ini["uploads"]["AWS_S3_ENDPOINT_URL"])
|
||||
|
||||
# === OPTIONAL ===
|
||||
REVERSE_PROXY: bool = empty_str_cast(config_ini["optional"]["REVERSE_PROXY"]) \
|
||||
or False
|
||||
REVERSE_PROXY: bool = empty_str_cast(config_ini["optional"]["REVERSE_PROXY"], default=False)
|
||||
|
||||
TEMPLATES_AUTO_RELOAD: bool = empty_str_cast(config_ini["optional"]["TEMPLATES_AUTO_RELOAD"]) \
|
||||
or True
|
||||
TEMPLATES_AUTO_RELOAD: bool = empty_str_cast(config_ini["optional"]["TEMPLATES_AUTO_RELOAD"], default=True)
|
||||
|
||||
SQLALCHEMY_TRACK_MODIFICATIONS: bool = empty_str_cast(config_ini["optional"]["SQLALCHEMY_TRACK_MODIFICATIONS"]) \
|
||||
or False
|
||||
SQLALCHEMY_TRACK_MODIFICATIONS: bool = empty_str_cast(config_ini["optional"]["SQLALCHEMY_TRACK_MODIFICATIONS"], default=False)
|
||||
|
||||
SWAGGER_UI: bool = empty_str_cast(config_ini["optional"]["SWAGGER_UI"]) \
|
||||
or False
|
||||
SWAGGER_UI: bool = empty_str_cast(config_ini["optional"]["SWAGGER_UI"], default=False)
|
||||
|
||||
SWAGGER_UI_ENDPOINT: str = "/" if SWAGGER_UI else None
|
||||
|
||||
UPDATE_CHECK: bool = empty_str_cast(config_ini["optional"]["UPDATE_CHECK"]) \
|
||||
or True
|
||||
UPDATE_CHECK: bool = empty_str_cast(config_ini["optional"]["UPDATE_CHECK"], default=True)
|
||||
|
||||
APPLICATION_ROOT: str = empty_str_cast(config_ini["optional"]["APPLICATION_ROOT"]) \
|
||||
or "/"
|
||||
APPLICATION_ROOT: str = empty_str_cast(config_ini["optional"]["APPLICATION_ROOT"], default="/")
|
||||
|
||||
SERVER_SENT_EVENTS: bool = empty_str_cast(config_ini["optional"]["SERVER_SENT_EVENTS"]) \
|
||||
or True
|
||||
SERVER_SENT_EVENTS: bool = empty_str_cast(config_ini["optional"]["SERVER_SENT_EVENTS"], default=True)
|
||||
|
||||
HTML_SANITIZATION: bool = empty_str_cast(config_ini["optional"]["HTML_SANITIZATION"]) \
|
||||
or False
|
||||
HTML_SANITIZATION: bool = empty_str_cast(config_ini["optional"]["HTML_SANITIZATION"], default=False)
|
||||
|
||||
if DATABASE_URL.startswith("sqlite") is False:
|
||||
SQLALCHEMY_ENGINE_OPTIONS = {
|
||||
"max_overflow": int(empty_str_cast(config_ini["optional"]["SQLALCHEMY_MAX_OVERFLOW"], default=0)) # noqa: E131
|
||||
or 20, # noqa: E131
|
||||
"pool_pre_ping": empty_str_cast(config_ini["optional"]["SQLALCHEMY_POOL_PRE_PING"]) # noqa: E131
|
||||
or True, # noqa: E131
|
||||
"max_overflow": int(empty_str_cast(config_ini["optional"]["SQLALCHEMY_MAX_OVERFLOW"], default=20)), # noqa: E131
|
||||
"pool_pre_ping": empty_str_cast(config_ini["optional"]["SQLALCHEMY_POOL_PRE_PING"], default=True), # noqa: E131
|
||||
}
|
||||
|
||||
# === OAUTH ===
|
||||
|
||||
@@ -109,20 +109,18 @@
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
{% if get_config('version_latest') %}
|
||||
<div class="container-fluid bg-warning text-center py-3">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<a class="btn btn-warning" href="{{ get_config('version_latest') }}">
|
||||
A new CTFd version is available!
|
||||
</a>
|
||||
<main role="main">
|
||||
{% if get_config('version_latest') %}
|
||||
<div class="container-fluid bg-warning text-center py-3">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<a class="btn btn-warning" href="{{ get_config('version_latest') }}">
|
||||
A new CTFd version is available!
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
<main role="main">
|
||||
{% endif %}
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
</main>
|
||||
|
||||
@@ -29,30 +29,30 @@
|
||||
|
||||
<div class="form-group col-md-2">
|
||||
<label for="start-month">Month:</label>
|
||||
<input class="form-control start-date" id='start-month' name='start-month' min="0" max="12"
|
||||
<input class="form-control start-date" id='start-month' min="0" max="12"
|
||||
type='number'>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-2">
|
||||
<label for="start-day">Day:</label>
|
||||
<input class="form-control start-date" id='start-day' name='start-day' min="0" max="31"
|
||||
<input class="form-control start-date" id='start-day' min="0" max="31"
|
||||
type='number'>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-3">
|
||||
<label for="start-year">Year:</label>
|
||||
<input class="form-control start-date" id='start-year' name='start-year' type='number'>
|
||||
<input class="form-control start-date" id='start-year' type='number'>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-2">
|
||||
<label for="start-hour">Hour:</label>
|
||||
<input class="form-control start-date" id='start-hour' name='start-hour' min="0" max="23"
|
||||
<input class="form-control start-date" id='start-hour' min="0" max="23"
|
||||
type='number'>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-3">
|
||||
<label for="start-minute">Minute:</label>
|
||||
<input class="form-control start-date" id='start-minute' name='start-minute' min="0" max="59"
|
||||
<input class="form-control start-date" id='start-minute' min="0" max="59"
|
||||
type='number'>
|
||||
</div>
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
|
||||
<div class="form-group col-md-12">
|
||||
<label>UTC Timestamp:</label>
|
||||
<input class="form-control" id='start' name='start' type='text'
|
||||
<input class="form-control" id='start' name='start' type='number'
|
||||
placeholder="Start Date (UTC timestamp)"
|
||||
{% if start is defined and start != None %}value="{{ start }}"{% endif %} readonly>
|
||||
</div>
|
||||
@@ -92,30 +92,30 @@
|
||||
|
||||
<div class="form-group col-md-2">
|
||||
<label for="end-month">Month:</label>
|
||||
<input class="form-control end-date" id='end-month' name='end-month' min="0" max="12"
|
||||
<input class="form-control end-date" id='end-month' min="0" max="12"
|
||||
type='number'>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-2">
|
||||
<label for="end-day">Day:</label>
|
||||
<input class="form-control end-date" id='end-day' name='end-day' min="0" max="31"
|
||||
<input class="form-control end-date" id='end-day' min="0" max="31"
|
||||
type='number'>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-4">
|
||||
<label for="end-year">Year:</label>
|
||||
<input class="form-control end-date" id='end-year' name='end-year' type='number'>
|
||||
<input class="form-control end-date" id='end-year' type='number'>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-2">
|
||||
<label for="end-hour">Hour:</label>
|
||||
<input class="form-control end-date" id='end-hour' name='end-hour' min="0" max="23"
|
||||
<input class="form-control end-date" id='end-hour' min="0" max="23"
|
||||
type='number'>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-2">
|
||||
<label for="end-minute">Minute:</label>
|
||||
<input class="form-control end-date" id='end-minute' name='end-minute' min="0"
|
||||
<input class="form-control end-date" id='end-minute' min="0"
|
||||
max="59" type='number'>
|
||||
</div>
|
||||
|
||||
@@ -147,7 +147,7 @@
|
||||
|
||||
<div class="form-group col-md-12">
|
||||
<label for="end">UTC Timestamp:</label>
|
||||
<input class="form-control" id='end' name='end' type='text'
|
||||
<input class="form-control" id='end' name='end' type='number'
|
||||
placeholder="End Date (UTC timestamp)"
|
||||
{% if end is defined and end != None %}value="{{ end }}"{% endif %} readonly>
|
||||
</div>
|
||||
@@ -164,30 +164,30 @@
|
||||
|
||||
<div class="form-group col-md-2">
|
||||
<label for="freeze-month">Month:</label>
|
||||
<input class="form-control freeze-date" id='freeze-month' name='freeze-month' min="0" max="12"
|
||||
<input class="form-control freeze-date" id='freeze-month' min="0" max="12"
|
||||
type='number'>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-2">
|
||||
<label for="freeze-day">Day:</label>
|
||||
<input class="form-control freeze-date" id='freeze-day' name='freeze-day' min="0" max="31"
|
||||
<input class="form-control freeze-date" id='freeze-day' min="0" max="31"
|
||||
type='number'>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-4">
|
||||
<label for="freeze-year">Year:</label>
|
||||
<input class="form-control freeze-date" id='freeze-year' name='freeze-year' type='number'>
|
||||
<input class="form-control freeze-date" id='freeze-year' type='number'>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-2">
|
||||
<label for="freeze-hour">Hour:</label>
|
||||
<input class="form-control freeze-date" id='freeze-hour' name='freeze-hour' min="0" max="23"
|
||||
<input class="form-control freeze-date" id='freeze-hour' min="0" max="23"
|
||||
type='number'>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-2">
|
||||
<label for="freeze-minute">Minute:</label>
|
||||
<input class="form-control freeze-date" id='freeze-minute' name='freeze-minute' min="0"
|
||||
<input class="form-control freeze-date" id='freeze-minute' min="0"
|
||||
max="59" type='number'>
|
||||
</div>
|
||||
|
||||
@@ -211,7 +211,7 @@
|
||||
|
||||
<div class="form-group col-md-12">
|
||||
<label for="freeze">UTC Timestamp:</label>
|
||||
<input class="form-control" id='freeze' name='freeze' type='text'
|
||||
<input class="form-control" id='freeze' name='freeze' type='number'
|
||||
placeholder="Freeze Date (UTC timestamp)"
|
||||
{% if freeze is defined and freeze != None %}value="{{ freeze }}"{% endif %} readonly>
|
||||
</div>
|
||||
|
||||
@@ -30,16 +30,21 @@ function switchTab(event) {
|
||||
}
|
||||
|
||||
function processDateTime(datetime) {
|
||||
let date_picker = $(`#${datetime}-date`);
|
||||
let time_picker = $(`#${datetime}-time`);
|
||||
return function(_event) {
|
||||
let date_picker = $(`#${datetime}-date`);
|
||||
let time_picker = $(`#${datetime}-time`);
|
||||
let unix_time = Moment(
|
||||
`${date_picker.val()} ${time_picker.val()}`,
|
||||
"YYYY-MM-DD HH:mm"
|
||||
)
|
||||
.utc()
|
||||
.format("X");
|
||||
$(`#${datetime}-preview`).val(unix_time);
|
||||
.unix();
|
||||
|
||||
if (isNaN(unix_time)) {
|
||||
$(`#${datetime}-preview`).val("");
|
||||
} else {
|
||||
$(`#${datetime}-preview`).val(unix_time);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
;
|
||||
eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/core/assets/js/pages/main.js\");\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nvar _momentTimezone = _interopRequireDefault(__webpack_require__(/*! moment-timezone */ \"./node_modules/moment-timezone/index.js\"));\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! ../CTFd */ \"./CTFd/themes/core/assets/js/CTFd.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction switchTab(event) {\n event.preventDefault(); // Handle tab validation\n\n var valid_tab = true;\n (0, _jquery.default)(event.target).closest(\"[role=tabpanel]\").find(\"input,textarea\").each(function (i, e) {\n var $e = (0, _jquery.default)(e);\n var status = e.checkValidity();\n\n if (status === false) {\n $e.removeClass(\"input-filled-valid\");\n $e.addClass(\"input-filled-invalid\");\n valid_tab = false;\n }\n });\n\n if (valid_tab == false) {\n return;\n }\n\n var href = (0, _jquery.default)(event.target).data(\"href\");\n (0, _jquery.default)(\".nav a[href=\\\"\".concat(href, \"\\\"]\")).tab(\"show\");\n}\n\nfunction processDateTime(datetime) {\n var date_picker = (0, _jquery.default)(\"#\".concat(datetime, \"-date\"));\n var time_picker = (0, _jquery.default)(\"#\".concat(datetime, \"-time\"));\n return function (_event) {\n var unix_time = (0, _momentTimezone.default)(\"\".concat(date_picker.val(), \" \").concat(time_picker.val()), \"YYYY-MM-DD HH:mm\").utc().format(\"X\");\n (0, _jquery.default)(\"#\".concat(datetime, \"-preview\")).val(unix_time);\n };\n}\n\nfunction mlcSetup(_event) {\n var params = {\n name: (0, _jquery.default)(\"#ctf_name\").val(),\n type: \"jeopardy\",\n description: (0, _jquery.default)(\"#ctf_description\").val(),\n user_mode: (0, _jquery.default)(\"#user_mode\").val(),\n event_url: window.location.origin + _CTFd.default.config.urlRoot,\n redirect_url: window.location.origin + _CTFd.default.config.urlRoot + \"/redirect\",\n integration_setup_url: window.location.origin + _CTFd.default.config.urlRoot + \"/setup/integrations\",\n start: (0, _jquery.default)(\"#start-preview\").val(),\n end: (0, _jquery.default)(\"#end-preview\").val(),\n platform: \"CTFd\",\n state: window.STATE\n };\n var ret = [];\n\n for (var p in params) {\n ret.push(encodeURIComponent(p) + \"=\" + encodeURIComponent(params[p]));\n }\n\n window.open(\"https://www.majorleaguecyber.org/events/new?\" + ret.join(\"&\"), \"_blank\");\n}\n\n(0, _jquery.default)(function () {\n (0, _jquery.default)(\".tab-next\").click(switchTab);\n (0, _jquery.default)(\"input\").on(\"keypress\", function (e) {\n // Hook Enter button\n if (e.keyCode == 13) {\n e.preventDefault();\n (0, _jquery.default)(e.target).closest(\".tab-pane\").find(\"button[data-href]\").click();\n }\n });\n (0, _jquery.default)(\"#integration-mlc\").click(mlcSetup);\n (0, _jquery.default)(\"#start-date,#start-time\").change(processDateTime(\"start\"));\n (0, _jquery.default)(\"#end-date,#end-time\").change(processDateTime(\"end\"));\n (0, _jquery.default)(\"#config-color-picker\").on(\"input\", function (_e) {\n (0, _jquery.default)(\"#config-color-input\").val((0, _jquery.default)(this).val());\n });\n (0, _jquery.default)(\"#config-color-reset\").click(function () {\n (0, _jquery.default)(\"#config-color-input\").val(\"\");\n (0, _jquery.default)(\"#config-color-picker\").val(\"\");\n });\n window.addEventListener(\"storage\", function (event) {\n if (event.key == \"integrations\" && event.newValue) {\n var integration = JSON.parse(event.newValue);\n\n if (integration[\"name\"] == \"mlc\") {\n (0, _jquery.default)(\"#integration-mlc\").text(\"Already Configured\").attr(\"disabled\", true);\n window.focus();\n localStorage.removeItem(\"integrations\");\n }\n }\n });\n (0, _jquery.default)(\"#setup-form\").submit(function (e) {\n if ((0, _jquery.default)(\"#newsletter-checkbox\").prop(\"checked\")) {\n var email = (0, _jquery.default)(e.target).find(\"input[name=email]\").val();\n\n _jquery.default.ajax({\n type: \"POST\",\n url: \"https://ctfd.us15.list-manage.com/subscribe/post-json?u=6c7fa6feeced52775aec9d015&id=dd1484208e&c=?\",\n data: {\n EMAIL: email,\n subscribe: \"Subscribe\",\n b_6c7fa6feeced52775aec9d015_dd1484208e: \"\"\n },\n dataType: \"jsonp\",\n contentType: \"application/json; charset=utf-8\"\n });\n }\n });\n});\n\n//# sourceURL=webpack:///./CTFd/themes/core/assets/js/pages/setup.js?");
|
||||
eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/core/assets/js/pages/main.js\");\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nvar _momentTimezone = _interopRequireDefault(__webpack_require__(/*! moment-timezone */ \"./node_modules/moment-timezone/index.js\"));\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! ../CTFd */ \"./CTFd/themes/core/assets/js/CTFd.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction switchTab(event) {\n event.preventDefault(); // Handle tab validation\n\n var valid_tab = true;\n (0, _jquery.default)(event.target).closest(\"[role=tabpanel]\").find(\"input,textarea\").each(function (i, e) {\n var $e = (0, _jquery.default)(e);\n var status = e.checkValidity();\n\n if (status === false) {\n $e.removeClass(\"input-filled-valid\");\n $e.addClass(\"input-filled-invalid\");\n valid_tab = false;\n }\n });\n\n if (valid_tab == false) {\n return;\n }\n\n var href = (0, _jquery.default)(event.target).data(\"href\");\n (0, _jquery.default)(\".nav a[href=\\\"\".concat(href, \"\\\"]\")).tab(\"show\");\n}\n\nfunction processDateTime(datetime) {\n return function (_event) {\n var date_picker = (0, _jquery.default)(\"#\".concat(datetime, \"-date\"));\n var time_picker = (0, _jquery.default)(\"#\".concat(datetime, \"-time\"));\n var unix_time = (0, _momentTimezone.default)(\"\".concat(date_picker.val(), \" \").concat(time_picker.val()), \"YYYY-MM-DD HH:mm\").utc().unix();\n\n if (isNaN(unix_time)) {\n (0, _jquery.default)(\"#\".concat(datetime, \"-preview\")).val(\"\");\n } else {\n (0, _jquery.default)(\"#\".concat(datetime, \"-preview\")).val(unix_time);\n }\n };\n}\n\nfunction mlcSetup(_event) {\n var params = {\n name: (0, _jquery.default)(\"#ctf_name\").val(),\n type: \"jeopardy\",\n description: (0, _jquery.default)(\"#ctf_description\").val(),\n user_mode: (0, _jquery.default)(\"#user_mode\").val(),\n event_url: window.location.origin + _CTFd.default.config.urlRoot,\n redirect_url: window.location.origin + _CTFd.default.config.urlRoot + \"/redirect\",\n integration_setup_url: window.location.origin + _CTFd.default.config.urlRoot + \"/setup/integrations\",\n start: (0, _jquery.default)(\"#start-preview\").val(),\n end: (0, _jquery.default)(\"#end-preview\").val(),\n platform: \"CTFd\",\n state: window.STATE\n };\n var ret = [];\n\n for (var p in params) {\n ret.push(encodeURIComponent(p) + \"=\" + encodeURIComponent(params[p]));\n }\n\n window.open(\"https://www.majorleaguecyber.org/events/new?\" + ret.join(\"&\"), \"_blank\");\n}\n\n(0, _jquery.default)(function () {\n (0, _jquery.default)(\".tab-next\").click(switchTab);\n (0, _jquery.default)(\"input\").on(\"keypress\", function (e) {\n // Hook Enter button\n if (e.keyCode == 13) {\n e.preventDefault();\n (0, _jquery.default)(e.target).closest(\".tab-pane\").find(\"button[data-href]\").click();\n }\n });\n (0, _jquery.default)(\"#integration-mlc\").click(mlcSetup);\n (0, _jquery.default)(\"#start-date,#start-time\").change(processDateTime(\"start\"));\n (0, _jquery.default)(\"#end-date,#end-time\").change(processDateTime(\"end\"));\n (0, _jquery.default)(\"#config-color-picker\").on(\"input\", function (_e) {\n (0, _jquery.default)(\"#config-color-input\").val((0, _jquery.default)(this).val());\n });\n (0, _jquery.default)(\"#config-color-reset\").click(function () {\n (0, _jquery.default)(\"#config-color-input\").val(\"\");\n (0, _jquery.default)(\"#config-color-picker\").val(\"\");\n });\n window.addEventListener(\"storage\", function (event) {\n if (event.key == \"integrations\" && event.newValue) {\n var integration = JSON.parse(event.newValue);\n\n if (integration[\"name\"] == \"mlc\") {\n (0, _jquery.default)(\"#integration-mlc\").text(\"Already Configured\").attr(\"disabled\", true);\n window.focus();\n localStorage.removeItem(\"integrations\");\n }\n }\n });\n (0, _jquery.default)(\"#setup-form\").submit(function (e) {\n if ((0, _jquery.default)(\"#newsletter-checkbox\").prop(\"checked\")) {\n var email = (0, _jquery.default)(e.target).find(\"input[name=email]\").val();\n\n _jquery.default.ajax({\n type: \"POST\",\n url: \"https://ctfd.us15.list-manage.com/subscribe/post-json?u=6c7fa6feeced52775aec9d015&id=dd1484208e&c=?\",\n data: {\n EMAIL: email,\n subscribe: \"Subscribe\",\n b_6c7fa6feeced52775aec9d015_dd1484208e: \"\"\n },\n dataType: \"jsonp\",\n contentType: \"application/json; charset=utf-8\"\n });\n }\n });\n});\n\n//# sourceURL=webpack:///./CTFd/themes/core/assets/js/pages/setup.js?");
|
||||
|
||||
/***/ })
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -96,13 +96,13 @@
|
||||
<div class="row submit-row">
|
||||
<div class="col-md-9 form-group">
|
||||
{% block input %}
|
||||
<input id="challenge-id" type="hidden" value="{{ challenge.id }}">
|
||||
<input class="form-control" type="text" name="answer" id="submission-input" placeholder="Flag"/>
|
||||
<input id="challenge-id" class="challenge-id" type="hidden" value="{{ challenge.id }}">
|
||||
<input id="challenge-input" class="challenge-input" type="text" name="answer" placeholder="Flag"/>
|
||||
{% endblock %}
|
||||
</div>
|
||||
<div class="col-md-3 form-group key-submit">
|
||||
{% block submit %}
|
||||
<button type="submit" id="submit-key" class="btn btn-md btn-outline-secondary float-right">
|
||||
<button id="challenge-submit" class="challenge-submit" type="submit">
|
||||
Submit
|
||||
</button>
|
||||
{% endblock %}
|
||||
@@ -141,4 +141,4 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="float-right">
|
||||
<div class="text-right">
|
||||
<button type="button" class="btn btn-primary btn-outlined tab-next" data-href="#administration">
|
||||
Next
|
||||
</button>
|
||||
@@ -100,7 +100,7 @@
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="float-right">
|
||||
<div class="text-right">
|
||||
<button type="button" class="btn btn-primary btn-outlined tab-next" data-href="#style">
|
||||
Next
|
||||
</button>
|
||||
@@ -130,7 +130,7 @@
|
||||
{{ form.theme_color.description }}
|
||||
</small>
|
||||
</div>
|
||||
<div class="float-right">
|
||||
<div class="text-right">
|
||||
<button type="button" class="btn btn-primary btn-outlined tab-next" data-href="#datetime">
|
||||
Next
|
||||
</button>
|
||||
@@ -179,7 +179,7 @@
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="float-right">
|
||||
<div class="text-right">
|
||||
<button type="button" class="btn btn-primary btn-outlined tab-next" data-href="#integrations">
|
||||
Next
|
||||
</button>
|
||||
@@ -207,7 +207,7 @@
|
||||
<hr>
|
||||
<br>
|
||||
|
||||
<div class="submit-row float-right">
|
||||
<div class="submit-row text-right">
|
||||
{{ form.submit(class="btn btn-md btn-primary btn-outlined") }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -11,13 +11,13 @@ def build_model_filters(model, query, field, extra_columns=None):
|
||||
column = getattr(model, field)
|
||||
|
||||
if type(column.type) == sqlalchemy.sql.sqltypes.Integer:
|
||||
_filter = column.op("==")(query)
|
||||
_filter = column.op("=")(query)
|
||||
else:
|
||||
_filter = column.like(f"%{query}%")
|
||||
filters.append(_filter)
|
||||
else:
|
||||
if field in extra_columns:
|
||||
column = extra_columns[field]
|
||||
_filter = column.op("==")(query)
|
||||
_filter = column.op("=")(query)
|
||||
filters.append(_filter)
|
||||
return filters
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ctfd",
|
||||
"version": "3.0.1",
|
||||
"version": "3.0.2",
|
||||
"description": "CTFd is a Capture The Flag framework focusing on ease of use and customizability. It comes with everything you need to run a CTF and it's easy to customize with plugins and themes.",
|
||||
"main": "index.js",
|
||||
"directories": {
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
from CTFd.models import Users
|
||||
from tests.helpers import (
|
||||
create_ctfd,
|
||||
destroy_ctfd,
|
||||
login_as_user,
|
||||
register_user,
|
||||
simulate_user_activity,
|
||||
)
|
||||
|
||||
|
||||
def test_browse_admin_submissions():
|
||||
"""Test that an admin can create a challenge properly"""
|
||||
app = create_ctfd()
|
||||
with app.app_context():
|
||||
register_user(app, name="RegisteredUser")
|
||||
user = Users.query.filter_by(id=2).first()
|
||||
simulate_user_activity(app.db, user)
|
||||
|
||||
admin = login_as_user(app, name="admin", password="password")
|
||||
|
||||
# It's difficult to do better checks here becase we're just doing string search.
|
||||
# incorrect includes the word correct and the navbar has correct and incorrect in it
|
||||
r = admin.get("/admin/submissions")
|
||||
assert r.status_code == 200
|
||||
assert "RegisteredUser" in r.get_data(as_text=True)
|
||||
assert "correct" in r.get_data(as_text=True)
|
||||
assert "incorrect" in r.get_data(as_text=True)
|
||||
|
||||
r = admin.get("/admin/submissions/correct")
|
||||
assert r.status_code == 200
|
||||
assert "RegisteredUser" in r.get_data(as_text=True)
|
||||
assert "correct" in r.get_data(as_text=True)
|
||||
|
||||
r = admin.get("/admin/submissions/incorrect")
|
||||
assert r.status_code == 200
|
||||
assert "RegisteredUser" in r.get_data(as_text=True)
|
||||
|
||||
r = admin.get("/admin/submissions/correct?field=challenge_id&q=1")
|
||||
assert r.status_code == 200
|
||||
assert "RegisteredUser" in r.get_data(as_text=True)
|
||||
destroy_ctfd(app)
|
||||
|
||||
Reference in New Issue
Block a user