Simplify url_for calls in themes, rework CTFd.js, fix flaky test (#826)

* Simplify url_for calls in themes, rework CTFd.js, fix flaky test
This commit is contained in:
Kevin Chung
2019-01-10 01:58:39 -05:00
committed by GitHub
parent 83e294057e
commit 9ee743de7e
15 changed files with 88 additions and 216 deletions

View File

@@ -14,6 +14,7 @@
<link rel="stylesheet" href="{{ url_for('views.themes', theme='admin', path='css/jumbotron.css') }}">
<link rel="stylesheet" href="{{ url_for('views.themes', theme='admin', path='css/sticky-footer.css') }}">
<link rel="stylesheet" href="{{ url_for('views.themes', theme='admin', path='css/base.css') }}">
<script src="{{ url_for('views.themes', theme='core', path='js/CTFd.js') }}"></script>
<script src="{{ url_for('views.themes', theme='admin', path='js/vendor/promise-polyfill.min.js') }}"></script>
<script src="{{ url_for('views.themes', theme='admin', path='js/vendor/fetch.min.js') }}"></script>
<script src="{{ url_for('views.themes', theme='admin', path='js/vendor/moment.min.js') }}"></script>
@@ -23,6 +24,8 @@
var script_root = "{{ request.script_root }}";
var csrf_nonce = "{{ nonce }}";
var user_mode = "{{ get_config('user_mode') }}";
CTFd.options.urlRoot = script_root;
CTFd.options.csrfNonce = csrf_nonce;
</script>
{% block stylesheets %} {% endblock %}
{% for stylesheet in get_registered_admin_stylesheets() %}

View File

@@ -1,173 +1,34 @@
var CTFd = (function () {
var urlRoot = '';
var challenges = {
all: function(){
return fetch(urlRoot + '/api/v1/challenges', {
credentials: 'same-origin',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
})
.then(function (response) {
return response.json();
}).then(function (data) {
return data;
});
},
get: function(challengeId){
return fetch(urlRoot + '/api/v1/challenges/' + challengeId, {
credentials: 'same-origin',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
})
.then(function (response) {
return response.json();
}).then(function (data) {
data.solves = function () {
return fetch(urlRoot + '/api/v1/challenges/' + this.id + '/solves', {
credentials: 'same-origin',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
})
.then(function (response) {
return response.json();
}).then(function (data) {
return data;
});
var options = {
urlRoot: '',
csrfNonce: '',
};
var challenges = {};
var scoreboard = function() {};
var teams = {};
var users = {};
var fetch = function(url, options) {
if (options === undefined) {
options = {
method: "GET",
credentials: "same-origin",
headers: {},
};
return data;
});
},
types: function(){
return fetch(urlRoot + '/api/v1/challenges/types', {
credentials: 'same-origin',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
})
.then(function (response) {
return response.json();
}).then(function (data) {
return data;
});
},
solves: function () {
return fetch(urlRoot + '/api/v1/statistics/challenges/solves', {
credentials: 'same-origin',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
})
.then(function (response) {
return response.json();
}).then(function (data) {
return data;
});
}
};
url = this.options.urlRoot + url;
var scoreboard = function() {
return fetch(urlRoot + '/api/v1/scoreboard', {
credentials: 'same-origin',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
})
.then(function (response) {
return response.json();
}).then(function (data) {
return data;
});
};
options.credentials = 'same-origin';
options.headers['Accept'] = 'application/json';
options.headers['Content-Type'] = 'application/json';
options.headers['CSRF-Token'] = this.options.csrfNonce;
var teams = {
all: function () {
return fetch(urlRoot + '/api/v1/teams', {
credentials: 'same-origin',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
})
.then(function (response) {
return response.json();
}).then(function (data) {
return data;
});
},
get: function (teamId) {
return fetch(urlRoot + '/api/v1/teams/' + teamId, {
credentials: 'same-origin',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
})
.then(function (response) {
return response.json();
}).then(function (data) {
data.solves = function () {
};
data.fails = function () {
};
data.awards = function () {
};
return data;
});
},
};
var users = {
all: function () {
return fetch(urlRoot + '/api/v1/users', {
credentials: 'same-origin',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
})
.then(function (response) {
return response.json();
}).then(function (data) {
return data;
});
},
get: function (userId) {
return fetch(urlRoot + '/api/v1/users/' + userId, {
credentials: 'same-origin',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
})
.then(function (response) {
return response.json();
}).then(function (data) {
data.solves = function () {
};
data.fails = function () {
};
data.awards = function () {
};
return data;
});
},
return window.fetch(url, options);
};
return {
@@ -175,5 +36,7 @@ var CTFd = (function () {
scoreboard: scoreboard,
teams: teams,
users: users,
fetch: fetch,
options: options
};
})();

View File

@@ -4,15 +4,15 @@
<title>{{ get_ctf_name() }}</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="{{ url_for('views.themes', theme=get_ctf_theme(), path='img/favicon.ico') }}"
<link rel="shortcut icon" href="{{ url_for('views.themes', path='img/favicon.ico') }}"
type="image/x-icon">
<link rel="stylesheet" href="{{ url_for('views.themes', theme=get_ctf_theme(), path='css/vendor/bootstrap.min.css') }}">
<link rel="stylesheet" href="{{ url_for('views.themes', theme=get_ctf_theme(), path='css/vendor/font-awesome/fontawesome-fonts.css') }}" type='text/css'>
<link rel="stylesheet" href="{{ url_for('views.themes', theme=get_ctf_theme(), path='css/vendor/font-awesome/fontawesome-all.min.css') }}" type='text/css'>
<link rel="stylesheet" href="{{ url_for('views.themes', theme=get_ctf_theme(), path='css/vendor/font.css') }}" type='text/css'>
<link rel="stylesheet" href="{{ url_for('views.themes', theme=get_ctf_theme(), path='css/jumbotron.css') }}">
<link rel="stylesheet" href="{{ url_for('views.themes', theme=get_ctf_theme(), path='css/sticky-footer.css') }}">
<link rel="stylesheet" href="{{ url_for('views.themes', theme=get_ctf_theme(), path='css/base.css') }}">
<link rel="stylesheet" href="{{ url_for('views.themes', path='css/vendor/bootstrap.min.css') }}">
<link rel="stylesheet" href="{{ url_for('views.themes', path='css/vendor/font-awesome/fontawesome-fonts.css') }}" type='text/css'>
<link rel="stylesheet" href="{{ url_for('views.themes', path='css/vendor/font-awesome/fontawesome-all.min.css') }}" type='text/css'>
<link rel="stylesheet" href="{{ url_for('views.themes', path='css/vendor/font.css') }}" type='text/css'>
<link rel="stylesheet" href="{{ url_for('views.themes', path='css/jumbotron.css') }}">
<link rel="stylesheet" href="{{ url_for('views.themes', path='css/sticky-footer.css') }}">
<link rel="stylesheet" href="{{ url_for('views.themes', path='css/base.css') }}">
{% block stylesheets %}{% endblock %}
{% for stylesheet in get_registered_stylesheets() %}
{% if stylesheet.startswith('http') %}
@@ -24,17 +24,18 @@
{% endif %}
{% endfor %}
<link rel="stylesheet" type="text/css" href="{{ url_for('views.custom_css') }}">
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/vendor/promise-polyfill.min.js') }}"></script>
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/vendor/fetch.min.js') }}"></script>
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/CTFd.js') }}"></script>
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/vendor/moment.min.js') }}"></script>
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/vendor/nunjucks.min.js') }}"></script>
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/vendor/socket.io.min.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/vendor/promise-polyfill.min.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/vendor/fetch.min.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/CTFd.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/vendor/moment.min.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/vendor/nunjucks.min.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/vendor/socket.io.min.js') }}"></script>
<script type="text/javascript">
var script_root = "{{ request.script_root }}";
var csrf_nonce = "{{ nonce }}";
var user_mode = "{{ get_config('user_mode') }}";
CTFd.urlRoot = script_root;
CTFd.options.urlRoot = script_root;
CTFd.options.csrfNonce = csrf_nonce;
</script>
</head>
<body>
@@ -142,13 +143,13 @@
</div>
</footer>
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/vendor/jquery.min.js') }}"></script>
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/vendor/markdown-it.min.js') }}"></script>
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/vendor/bootstrap.bundle.min.js') }}"></script>
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/style.js') }}"></script>
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/utils.js') }}"></script>
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/ezq.js') }}"></script>
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/events.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/vendor/jquery.min.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/vendor/markdown-it.min.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/vendor/bootstrap.bundle.min.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/style.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/utils.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/ezq.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/events.js') }}"></script>
{% block scripts %}
{% endblock %}

View File

@@ -1,7 +1,7 @@
{% extends "base.html" %}
{% block stylesheets %}
<link rel="stylesheet" href="{{ url_for('views.themes', theme=get_ctf_theme(), path='css/challenge-board.css') }}">
<link rel="stylesheet" href="{{ url_for('views.themes', path='css/challenge-board.css') }}">
{% endblock %}
{% block content %}
@@ -56,11 +56,11 @@
<script>
var authed = {{ (id is defined) | tojson }};
</script>
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/utils.js') }}"></script>
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/multi-modal.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/utils.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/multi-modal.js') }}"></script>
{% if admin or not errors %}
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/challenges.js') }}"></script>
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/hints.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/challenges.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/hints.js') }}"></script>
{% endif %}
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/style.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/style.js') }}"></script>
{% endblock %}

View File

@@ -59,6 +59,6 @@
{% endblock %}
{% block scripts %}
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/style.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/style.js') }}"></script>
{% endblock %}

View File

@@ -22,6 +22,6 @@
{% endblock %}
{% block scripts %}
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/vendor/plotly.min.js') }}"></script>
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/utils.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/vendor/plotly.min.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/utils.js') }}"></script>
{% endblock %}

View File

@@ -54,5 +54,5 @@
{% endblock %}
{% block scripts %}
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/style.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/style.js') }}"></script>
{% endblock %}

View File

@@ -75,7 +75,7 @@
{% endblock %}
{% block scripts %}
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/vendor/plotly.min.js') }}"></script>
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/utils.js') }}"></script>
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/scoreboard.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/vendor/plotly.min.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/utils.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/scoreboard.js') }}"></script>
{% endblock %}

View File

@@ -93,6 +93,6 @@
{% endblock %}
{% block scripts %}
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/style.js') }}"></script>
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/settings.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/style.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/settings.js') }}"></script>
{% endblock %}

View File

@@ -87,5 +87,5 @@
{% endblock %}
{% block scripts %}
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/style.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/style.js') }}"></script>
{% endblock %}

View File

@@ -158,9 +158,9 @@
{% endif %}
var team_account_id = team_self ? "me" : team_id;
</script>
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/vendor/plotly.min.js') }}"></script>
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/utils.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/vendor/plotly.min.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/utils.js') }}"></script>
{% if solves %}
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/team.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/team.js') }}"></script>
{% endif %}
{% endblock %}

View File

@@ -35,9 +35,9 @@
{% endblock %}
{% block scripts %}
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/vendor/plotly.min.js') }}"></script>
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/utils.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/vendor/plotly.min.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/utils.js') }}"></script>
{% if solves %}
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/team.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/team.js') }}"></script>
{% endif %}
{% endblock %}

View File

@@ -129,7 +129,7 @@
var user_self = {{ (user.id == id) | tojson }};
var user_account_id = user_self ? "me" : user_id;
</script>
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/vendor/plotly.min.js') }}"></script>
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/utils.js') }}"></script>
<script src="{{ url_for('views.themes', theme=get_ctf_theme(), path='js/user.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/vendor/plotly.min.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/utils.js') }}"></script>
<script src="{{ url_for('views.themes', path='js/user.js') }}"></script>
{% endblock %}

View File

@@ -71,6 +71,11 @@ def init_request_processors(app):
return dict(session)
return dict()
@app.url_defaults
def inject_theme(endpoint, values):
if 'theme' not in values and app.url_map.is_endpoint_expecting(endpoint, 'theme'):
values['theme'] = ctf_theme()
@app.before_request
def needs_setup():
if request.path == url_for('views.setup') or request.path.startswith('/themes'):

View File

@@ -107,12 +107,12 @@ def test_api_hint_admin_access():
admin = login_as_user(app, "admin")
register_user(app)
client = login_as_user(app)
r = client.patch('/api/v1/hints/1')
assert r.status_code == 302
r = client.delete('/api/v1/hints/1')
assert r.status_code == 302
r = client.patch('/api/v1/hints/1', json="")
assert r.status_code == 403
r = client.delete('/api/v1/hints/1', json="")
assert r.status_code == 403
r_admin = admin.patch('/api/v1/hints/1', json={"cost": 2})
assert r_admin.status_code == 200
r_admin = admin.delete('/api/v1/hints/1')
r_admin = admin.delete('/api/v1/hints/1', json="")
assert r_admin.status_code == 200
destroy_ctfd(app)