From 17b985d238b866b25367d3a81387188c42aa68b8 Mon Sep 17 00:00:00 2001 From: Vivek Santayana Date: Sat, 18 Jun 2022 02:18:07 +0100 Subject: [PATCH 1/5] Bugfix: 404 errors with request.endpoint Fixed static folder 404 errors --- .../templates/admin/components/og-meta.html | 9 +- .../templates/quiz/components/og-meta.html | 9 +- ref-test/app/templates/404.html | 88 +++++++++++++++++-- .../app/templates/components/og-meta.html | 9 +- ref-test/main.py | 9 +- 5 files changed, 99 insertions(+), 25 deletions(-) diff --git a/ref-test/app/admin/templates/admin/components/og-meta.html b/ref-test/app/admin/templates/admin/components/og-meta.html index 5c63bca..45453e1 100644 --- a/ref-test/app/admin/templates/admin/components/og-meta.html +++ b/ref-test/app/admin/templates/admin/components/og-meta.html @@ -2,16 +2,17 @@ - + - + - + - \ No newline at end of file + + \ No newline at end of file diff --git a/ref-test/app/quiz/templates/quiz/components/og-meta.html b/ref-test/app/quiz/templates/quiz/components/og-meta.html index 5c63bca..45453e1 100644 --- a/ref-test/app/quiz/templates/quiz/components/og-meta.html +++ b/ref-test/app/quiz/templates/quiz/components/og-meta.html @@ -2,16 +2,17 @@ - + - + - + - \ No newline at end of file + + \ No newline at end of file diff --git a/ref-test/app/templates/404.html b/ref-test/app/templates/404.html index 77cf2ac..483d1b0 100644 --- a/ref-test/app/templates/404.html +++ b/ref-test/app/templates/404.html @@ -1,8 +1,82 @@ -{% extends "components/base.html" %} + + + + + + + + + + {% block style %} + {% endblock %} + {% block title %} SKA Referee Test Beta {% endblock %} + + -{% block content %} -

Page Not Found

-

- The page you were looking for does not exist. Try going back and navigating to the desired destination correctly. -

-{% endblock %} \ No newline at end of file + {% block navbar %} + {% include "components/navbar.html" %} + {% endblock %} + +
+ {% block top_alerts %} + {% include "components/server-alerts.html" %} + {% endblock %} + {% block content %} +

Page Not Found

+

+ The page you were looking for does not exist. Try going back and navigating to the desired destination correctly. +

+ {% endblock %} +
+ {% include "components/footer.html" %} +
+
+ + + + + + + + + + {% block script %} + {% endblock %} + + \ No newline at end of file diff --git a/ref-test/app/templates/components/og-meta.html b/ref-test/app/templates/components/og-meta.html index 5c63bca..ec7858a 100644 --- a/ref-test/app/templates/components/og-meta.html +++ b/ref-test/app/templates/components/og-meta.html @@ -2,16 +2,17 @@ - + - + - + - \ No newline at end of file + + \ No newline at end of file diff --git a/ref-test/main.py b/ref-test/main.py index b0ffffe..aa270a9 100644 --- a/ref-test/main.py +++ b/ref-test/main.py @@ -41,14 +41,11 @@ def create_app(): flash(f'Cookie Consent: This web site only stores minimal, functional cookies. It does not store any tracking information. By using this site, you consent to this use of cookies. For more information, see our privacy policy.', 'cookie_alert') @app.errorhandler(404) - def _404_handler(error): - return render_template('404.html') + def _404_handler(error): return render_template('404.html') @app.errorhandler(CSRFError) - def _csrf_handler(): - return jsonify({'error':'Could not validate a secure connection.'}), 403 + def _csrf_handler(): return jsonify({'error':'Could not validate a secure connection.'}), 403 @app.context_processor - def _now(): - return {'now': datetime.now()} + def _now(): return {'now': datetime.now()} from app.admin.views import admin from app.api.views import api From 516c2cdf8132e337b2fb7a245a42d7d165ce0d4a Mon Sep 17 00:00:00 2001 From: Vivek Santayana Date: Sat, 18 Jun 2022 09:26:05 +0100 Subject: [PATCH 2/5] Buxfix: static folders bypass cookie consent --- ref-test/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ref-test/main.py b/ref-test/main.py index aa270a9..40826af 100644 --- a/ref-test/main.py +++ b/ref-test/main.py @@ -36,7 +36,7 @@ def create_app(): def _check_cookie_consent(): if request.cookies.get('cookie_consent'): return - if any([ request.path.startswith(x) for x in [ '/admin/static/', '/static/', '/cookies/' ] ]): + if any([ request.path.startswith(x) for x in [ '/admin/static/', '/root/', '/quiz/static', '/cookies/' ] ]): return flash(f'Cookie Consent: This web site only stores minimal, functional cookies. It does not store any tracking information. By using this site, you consent to this use of cookies. For more information, see our privacy policy.', 'cookie_alert') From 2e00d503c8ac8fde900cfb72638a24e2983415f6 Mon Sep 17 00:00:00 2001 From: Vivek Santayana Date: Sun, 19 Jun 2022 10:48:17 +0100 Subject: [PATCH 3/5] Added detailed data validation --- ref-test/app/tools/data.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/ref-test/app/tools/data.py b/ref-test/app/tools/data.py index d72c60f..8702741 100644 --- a/ref-test/app/tools/data.py +++ b/ref-test/app/tools/data.py @@ -19,6 +19,39 @@ def validate_json(file): file.stream.seek(0) data = json.loads(file.read()) if not isinstance(data, list): return False + for block in data: + block_type = block.pop('type', None) + if block_type not in ['block', 'question']: return False + if block_type == 'question': + if not all (key in block for key in ['q_no', 'text', 'options', 'correct', 'q_type', 'tags']): return False + if not isinstance(block['q_no'], int): return False + if not isinstance(block['text'], str): return False + if not isinstance(block['options'], list): return False + for option in block['options']: + if not isinstance(option, str): return False + if not isinstance(block['correct'], int): return False + if not isinstance(block['q_type'], str): return False + if block['q_type'] not in ['Multiple Choice', 'Yes/No', 'List']: return False + if not isinstance(block['tags'], list): return False + for tag in block['tags']: + if not isinstance(tag, str): return False + if block_type == 'block': + if not all (key in block for key in ['question_header', 'questions']): return False + if not isinstance(block['question_header'], str): return False + if not isinstance(block['questions'], list): return False + for question in block['questions']: + if not all (key in question for key in ['q_no', 'text', 'options', 'correct', 'q_type', 'tags']): return False + if not isinstance(question['text'], str): return False + if not isinstance(question['q_no'], int): return False + if not isinstance(question['options'], list): return False + for option in question['options']: + if not isinstance(option, str): return False + if not isinstance(question['correct'], int): return False + if not isinstance(question['q_type'], str): return False + if question['q_type'] not in ['Multiple Choice', 'Yes/No', 'List']: return False + if not isinstance(question['tags'], list): return False + for tag in question['tags']: + if not isinstance(tag, str): return False return True def randomise_list(list:list): From 6d5f74bd6246e850703b8dc9c94096baff200cae Mon Sep 17 00:00:00 2001 From: Vivek Santayana Date: Sun, 19 Jun 2022 11:17:00 +0100 Subject: [PATCH 4/5] Tidied up code --- ref-test/app/config.py | 6 +++--- ref-test/config.py | 2 +- ref-test/main.py | 3 +-- ref-test/wsgi.py | 4 +--- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/ref-test/app/config.py b/ref-test/app/config.py index b70db97..e62ead5 100644 --- a/ref-test/app/config.py +++ b/ref-test/app/config.py @@ -28,10 +28,10 @@ class Config(object): MAIL_SUPPRESS_SEND = False MAIL_ASCII_ATTACHMENTS = bool(os.getenv('MAIL_ASCII_ATTACHMENTS')) -class ProductionConfig(Config): +class Production(Config): pass -class DevelopmentConfig(Config): +class Development(Config): APP_HOST = '127.0.0.1' DEBUG = True SESSION_COOKIE_SECURE = False @@ -39,7 +39,7 @@ class DevelopmentConfig(Config): MAIL_DEBUG = True MAIL_SUPPRESS_SEND = False -class TestingConfig(DevelopmentConfig): +class Testing(Development): TESTING = True SESSION_COOKIE_SECURE = False MAIL_SERVER = os.getenv('MAIL_SERVER') diff --git a/ref-test/config.py b/ref-test/config.py index beea69e..c21f59c 100644 --- a/ref-test/config.py +++ b/ref-test/config.py @@ -1 +1 @@ -from app.config import ProductionConfig as Config \ No newline at end of file +from app.config import Production as Config \ No newline at end of file diff --git a/ref-test/main.py b/ref-test/main.py index 40826af..97a4d09 100644 --- a/ref-test/main.py +++ b/ref-test/main.py @@ -80,5 +80,4 @@ def create_app(): app = create_app() -if __name__ == '__main__': - app.run() \ No newline at end of file +if __name__ == '__main__': app.run() \ No newline at end of file diff --git a/ref-test/wsgi.py b/ref-test/wsgi.py index b9a49b9..b7bcfb6 100644 --- a/ref-test/wsgi.py +++ b/ref-test/wsgi.py @@ -1,4 +1,2 @@ from main import app - -if __name__ == '__main__': - app.run() \ No newline at end of file +if __name__ == '__main__': app.run() \ No newline at end of file From 76fa1e1dd9bbc8a417a384f2a8b565e52d941b30 Mon Sep 17 00:00:00 2001 From: Vivek Santayana Date: Sun, 19 Jun 2022 11:17:21 +0100 Subject: [PATCH 5/5] Removed todo tags --- ref-test/app/admin/static/js/script.js | 2 +- ref-test/app/admin/views.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ref-test/app/admin/static/js/script.js b/ref-test/app/admin/static/js/script.js index 30c8a49..96004f9 100644 --- a/ref-test/app/admin/static/js/script.js +++ b/ref-test/app/admin/static/js/script.js @@ -77,7 +77,7 @@ $('.test-action').click(function(event) { $.ajax({ url: `/admin/tests/edit/`, type: 'POST', - data: JSON.stringify({'id': id, 'action': action}), // TODO Change how CRUD operations work + data: JSON.stringify({'id': id, 'action': action}), contentType: 'application/json', success: function(response) { window.location.href = '/admin/tests/'; diff --git a/ref-test/app/admin/views.py b/ref-test/app/admin/views.py index 65bb6f2..cfea08f 100644 --- a/ref-test/app/admin/views.py +++ b/ref-test/app/admin/views.py @@ -214,7 +214,7 @@ def _questions(): if form.validate_on_submit(): upload = form.data_file.data if not check_is_json(upload): return jsonify({'error': 'Invalid file. Please upload a JSON file.'}), 400 - if not validate_json(upload): return jsonify({'error': 'The data in the file is invalid.'}), 400 # TODO Perhaps make a more complex validation script + if not validate_json(upload): return jsonify({'error': 'The data in the file is invalid.'}), 400 new_dataset = Dataset() success, message = new_dataset.create( upload = upload,