diff options
-rw-r--r-- | wqflask/wqflask/oauth2/client.py | 8 | ||||
-rw-r--r-- | wqflask/wqflask/templates/show_trait_error.html | 20 | ||||
-rw-r--r-- | wqflask/wqflask/views.py | 81 |
3 files changed, 86 insertions, 23 deletions
diff --git a/wqflask/wqflask/oauth2/client.py b/wqflask/wqflask/oauth2/client.py index 1d3e07ae..dba52644 100644 --- a/wqflask/wqflask/oauth2/client.py +++ b/wqflask/wqflask/oauth2/client.py @@ -1,4 +1,5 @@ """Common oauth2 client utilities.""" +import requests from typing import Optional from urllib.parse import urljoin @@ -46,3 +47,10 @@ def oauth2_post( return Right(resp.json()) return Left(resp) + +def no_token_get(uri_path: str, **kwargs) -> Either: + config = app.config + resp = requests.get(urljoin(config["GN_SERVER_URL"], uri_path), **kwargs) + if resp.status_code == 200: + return Right(resp.json()) + return Left(resp) diff --git a/wqflask/wqflask/templates/show_trait_error.html b/wqflask/wqflask/templates/show_trait_error.html new file mode 100644 index 00000000..c924d1f1 --- /dev/null +++ b/wqflask/wqflask/templates/show_trait_error.html @@ -0,0 +1,20 @@ +{%extends "base.html"%} +{%block title%}Trait Data and Analysis{%endblock%} +{%block css%} +<link rel="stylesheet" type="text/css" href="/static/new/css/bar_chart.css" /> +<link rel="stylesheet" type="text/css" href="/static/new/css/box_plot.css" /> +<link rel="stylesheet" type="text/css" href="/static/new/css/prob_plot.css" /> +<link rel="stylesheet" type="text/css" href="/static/new/css/scatter-matrix.css" /> +<link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='d3-tip/d3-tip.css') }}" /> +<link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" /> +<link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='nouislider/nouislider.min.css') }}" /> +<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" /> +<link rel="stylesheet" type="text/css" href="/static/new/css/trait_list.css" /> +<link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" /> + +{%endblock%} +{%block content%} <!-- Start of body --> +<div class="container"> + {{flash_me()}} +</div> +{%endblock%} <!-- End of body --> diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 90747fc2..f14ccdd0 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -38,6 +38,8 @@ from flask import send_from_directory from flask import redirect from flask import send_file from flask import url_for +from flask import flash +from flask import session # Some of these (like collect) might contain endpoints, so they're still used. # Blueprints should probably be used instead. @@ -75,6 +77,9 @@ from wqflask.docs import Docs, update_text from wqflask.decorators import edit_access_required from wqflask.db_info import InfoPage +from wqflask.oauth2.client import no_token_get +from wqflask.oauth2.request_utils import process_error + from utility import temp_data from utility.tools import TEMPDIR from utility.tools import USE_REDIS @@ -482,30 +487,60 @@ def show_temp_trait_page(): @app.route("/show_trait") def show_trait_page(): - with database_connection() as conn, conn.cursor() as cursor: - user_id = ((g.user_session.record.get(b"user_id") or b"").decode("utf-8") - or g.user_session.record.get("user_id") or "") - template_vars = show_trait.ShowTrait(cursor, - user_id=user_id, - kw=request.args) - template_vars.js_data = json.dumps(template_vars.js_data, - default=json_default_handler, - indent=" ") - # Should there be any mis-configurations, things will still - # work. - metadata = {} - try: - metadata = requests.get( - urljoin( - GN3_LOCAL_URL, - f"/api/metadata/dataset/{request.args.get('dataset')}") - ).json() - except: + def __show_trait__(): + with database_connection() as conn, conn.cursor() as cursor: + + user_id = ((g.user_session.record.get(b"user_id") or b"").decode("utf-8") + or g.user_session.record.get("user_id") or "") + template_vars = show_trait.ShowTrait(cursor, + user_id=user_id, + kw=request.args) + template_vars.js_data = json.dumps(template_vars.js_data, + default=json_default_handler, + indent=" ") + # Should there be any mis-configurations, things will still + # work. metadata = {} - return render_template( - "show_trait.html", - metadata=metadata, - **template_vars.__dict__) + try: + metadata = requests.get( + urljoin( + GN3_LOCAL_URL, + f"/api/metadata/dataset/{request.args.get('dataset')}") + ).json() + except: + metadata = {} + return render_template( + "show_trait.html", + metadata=metadata, + **template_vars.__dict__) + dataset = request.args["dataset"] + trait_id = request.args["trait_id"] + def __failure__(err): + error = process_error(err) + flash(f"{error['error']}: {error['error_description']}", "alert-error") + return render_template("show_trait_error.html") + + def __success__(auth_results): + trait_privileges = auth_results[0]["privileges"] + if ("group:resource:view-resource" in trait_privileges or + "system:resource:public-read" in trait_privileges): + return __show_trait__() + flash( + f"AuthorisationError: You do not have access to trait '{trait_id}' " + f"from the '{dataset}' dataset.", + "alert-danger") + return render_template("show_trait_error.html") + + return no_token_get( + "oauth2/data/authorisation", + headers={ + "Content-Type": "application/json", + **({"Authorization": f"Bearer {session['token']}"} + if bool(session.get("token")) else {}) + }, + json={ + "traits": [f"{dataset}::{trait_id}"] + }).either(__failure__, __success__) @app.route("/heatmap", methods=('POST',)) |