about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFrederick Muriuki Muriithi2023-05-19 10:49:36 +0300
committerFrederick Muriuki Muriithi2023-05-19 10:49:36 +0300
commite7f884ab69919818948a7d6ef2b6882eba8d815b (patch)
tree1b4ebb6fefd8512e1c53362b6437de84767f3d32
parent1ec8d9e6c1625b398bbcd806180000595214cf43 (diff)
downloadgenenetwork2-e7f884ab69919818948a7d6ef2b6882eba8d815b.tar.gz
auth: Use auth privileges to control UI display
Use the privileges from the authorisation endpoint to control which
elements of the UI are displayed to the user.

* wqflask/base/trait.py: Remove unused import
* wqflask/wqflask/show_trait/show_trait.py: Unhook from GN-PROXY
* wqflask/wqflask/templates/show_trait.html: Display or hide UI
  elements depending on the privileges the user has.
* wqflask/wqflask/templates/show_trait_details.html: Display or hide
  UI elements depending on the privileges the user has.
* wqflask/wqflask/views.py: Pass privileges, user, and resource
  details on to the UI template to be used for controlling UI element
  display.
-rw-r--r--wqflask/base/trait.py2
-rw-r--r--wqflask/wqflask/show_trait/show_trait.py5
-rw-r--r--wqflask/wqflask/templates/show_trait.html224
-rw-r--r--wqflask/wqflask/templates/show_trait_details.html6
-rw-r--r--wqflask/wqflask/views.py33
5 files changed, 134 insertions, 136 deletions
diff --git a/wqflask/base/trait.py b/wqflask/base/trait.py
index e6e1c6b3..37085448 100644
--- a/wqflask/base/trait.py
+++ b/wqflask/base/trait.py
@@ -7,7 +7,7 @@ from base import webqtlConfig
 from base.webqtlCaseData import webqtlCaseData
 from base.data_set import create_dataset
 from utility.authentication_tools import check_resource_availability
-from utility.tools import GN2_BASE_URL, GN_PROXY_URL
+from utility.tools import GN2_BASE_URL
 from utility.redis_tools import get_redis_conn, get_resource_id
 
 from flask import g, request, url_for
diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py
index e958e78c..13e11ff2 100644
--- a/wqflask/wqflask/show_trait/show_trait.py
+++ b/wqflask/wqflask/show_trait/show_trait.py
@@ -37,17 +37,12 @@ ONE_YEAR = 60 * 60 * 24 * 365
 
 class ShowTrait:
     def __init__(self, db_cursor, user_id, kw):
-        self.admin_status = None
         if 'trait_id' in kw and kw['dataset'] != "Temp":
             self.temp_trait = False
             self.trait_id = kw['trait_id']
             helper_functions.get_species_dataset_trait(self, kw)
             self.resource_id = get_resource_id(self.dataset,
                                            self.trait_id)
-            self.admin_status = get_highest_user_access_role(
-                    user_id=user_id,
-                    resource_id=(self.resource_id or ""),
-                    gn_proxy_url=GN_PROXY_URL)
         elif 'group' in kw:
             self.temp_trait = True
             self.trait_id = "Temp_" + kw['species'] + "_" + kw['group'] + \
diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html
index b0390ace..bc5d75cd 100644
--- a/wqflask/wqflask/templates/show_trait.html
+++ b/wqflask/wqflask/templates/show_trait.html
@@ -1,33 +1,38 @@
 {% extends "base.html" %}
+{%from "oauth2/display_error.html" import display_error%}
+
 {% 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" />
+  <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 -->
 
+  {{flash_me()}}
+  {%if "group:resource:view-resource" in trait_privileges%}
     <div class="container">
-        <h2>Trait Data and Analysis for <b>{{ this_trait.display_name }}</b></h2>
-        {% if this_trait.dataset.type != 'Publish' %}
-        <h3>{{ this_trait.description_fmt[0]|upper }}{{ this_trait.description_fmt[1:]|safe }}</h3>
-        {% endif %}
-    </div>
+      <h2>Trait Data and Analysis for <b>{{ this_trait.display_name }}</b></h2>
+      {% if this_trait.dataset.type != 'Publish' %}
+	<h3>{{ this_trait.description_fmt[0]|upper }}{{ this_trait.description_fmt[1:]|safe }}</h3>
+      {% endif %}
 
-    <form method="post" action="" target="_blank" name="trait_page" id="trait_data_form" class="form-horizontal">
-        <div id="hidden_inputs">
-        <input type="hidden" name="trait_hmac" value="{{ data_hmac('{}:{}'.format(this_trait.name, dataset.name)) }}">
-        {% for key in hddn %}
+      <form method="post" action="" target="_blank" name="trait_page" id="trait_data_form" class="form-horizontal">
+	<div id="hidden_inputs">
+          <input type="hidden" name="trait_hmac" value="{{ data_hmac('{}:{}'.format(this_trait.name, dataset.name)) }}">
+          {% for key in hddn %}
             <input type="hidden" name="{{ key }}" value="{{ hddn[key] }}">
-        {% endfor %}
+          {% endfor %}
         </div>
 
         <input type="hidden" name="temp_uuid" id="temp_uuid" value="{{ temp_uuid }}">
@@ -40,100 +45,105 @@
         <input type="hidden" name="sample_vals" value="">
 
         <div class="container showtrait-main-div">
-            <div class="panel-group" id="accordion">
-                <div class="panel panel-default">
-                    <div class="panel-heading" data-toggle="collapse" data-parent="#accordion" data-target="#collapseOne" aria-expanded="true">
-                        <h3 class="panel-title">
-                             <span class="glyphicon glyphicon-chevron-down"></span> Details and Links
-                        </h3>
-                    </div>
-                    <div id="collapseOne" class="panel-collapse collapse" aria-expanded="true">
-                        <div class="panel-body">
-                            {% include 'show_trait_details.html' %}
-                        </div>
-		    </div>
-		    {% if metadata %}
-		    <div class="panel-heading" data-toggle="collapse" data-parent="#accordion" data-target="#collapseMeta">
-                        <h3 class="panel-title">
-                            <span class="glyphicon glyphicon-chevron-down"></span> Data Set Group: {{  dataset.fullname }}
-                        </h3>
-                    </div>
-                    <div id="collapseMeta" class="panel-collapse collapse in">
-                        <div class="panel-body">
-			    {% include 'show_metadata_details.html' %}
-                        </div>
-		    </div>
-		    {% endif %}
+          <div class="panel-group" id="accordion">
+            <div class="panel panel-default">
+              <div class="panel-heading" data-toggle="collapse" data-parent="#accordion" data-target="#collapseOne" aria-expanded="true">
+                <h3 class="panel-title">
+                  <span class="glyphicon glyphicon-chevron-down"></span> Details and Links
+                </h3>
+              </div>
+              <div id="collapseOne" class="panel-collapse collapse" aria-expanded="true">
+                <div class="panel-body">
+                  {% include 'show_trait_details.html' %}
                 </div>
-                <div class="panel panel-default">
-                    <div class="panel-heading stats_panel" data-toggle="collapse" data-parent="#accordion" data-target="#collapseTwo">
-                        <h3 class="panel-title">
-                             <span class="glyphicon glyphicon-chevron-down"></span> Statistics
-                        </h3>
-                    </div>
-                    <div id="collapseTwo" class="panel-collapse collapse in">
-                        <div class="panel-body">
-                            {% include 'show_trait_statistics.html' %}
-                        </div>
-                    </div>
+	      </div>
+	      {% if metadata %}
+		<div class="panel-heading" data-toggle="collapse" data-parent="#accordion" data-target="#collapseMeta">
+                  <h3 class="panel-title">
+                    <span class="glyphicon glyphicon-chevron-down"></span> Data Set Group: {{  dataset.fullname }}
+                  </h3>
+		</div>
+		<div id="collapseMeta" class="panel-collapse collapse in">
+                  <div class="panel-body">
+		    {% include 'show_metadata_details.html' %}
+                  </div>
+		</div>
+	      {% endif %}
+            </div>
+            <div class="panel panel-default">
+              <div class="panel-heading stats_panel" data-toggle="collapse" data-parent="#accordion" data-target="#collapseTwo">
+                <h3 class="panel-title">
+                  <span class="glyphicon glyphicon-chevron-down"></span> Statistics
+                </h3>
+              </div>
+              <div id="collapseTwo" class="panel-collapse collapse in">
+                <div class="panel-body">
+                  {% include 'show_trait_statistics.html' %}
                 </div>
-                <div class="panel panel-default">
-                    <div class="panel-heading" data-toggle="collapse" data-parent="#accordion" data-target="#collapseThree">
-                        <h3 class="panel-title">
-                             <span class="glyphicon glyphicon-chevron-down"></span> Transform and Filter Data
-                        </h3>
-                    </div>
-                    <div id="collapseThree" class="panel-collapse collapse in">
-                        <div class="panel-body">
-                            {% include 'show_trait_transform_and_filter.html' %}
-                        </div>
-                        <div id="transform_alert_placeholder"><div id="transform_alert" style="display: none;"class="alert alert-success outlier-alert"><a href="#" class="close" data-dismiss="alert">�</a><span>Because there are some values between 0 and 1, log2 and log10 transforms will add 1 to each value.</span></div></div>
-                    </div>
+              </div>
+            </div>
+            <div class="panel panel-default">
+              <div class="panel-heading" data-toggle="collapse" data-parent="#accordion" data-target="#collapseThree">
+                <h3 class="panel-title">
+                  <span class="glyphicon glyphicon-chevron-down"></span> Transform and Filter Data
+                </h3>
+              </div>
+              <div id="collapseThree" class="panel-collapse collapse in">
+                <div class="panel-body">
+                  {% include 'show_trait_transform_and_filter.html' %}
+                </div>
+                <div id="transform_alert_placeholder"><div id="transform_alert" style="display: none;"class="alert alert-success outlier-alert"><a href="#" class="close" data-dismiss="alert">�</a><span>Because there are some values between 0 and 1, log2 and log10 transforms will add 1 to each value.</span></div></div>
+              </div>
+            </div>
+            <div class="panel panel-default">
+              <div class="panel-heading" data-toggle="collapse" data-parent="#accordion" data-target="#collapseFour">
+                <h3 class="panel-title">
+                  <span class="glyphicon glyphicon-chevron-down"></span> Calculate Correlations
+                </h3>
+              </div>
+              <div id="collapseFour" class="panel-collapse collapse in">
+                <div class="panel-body">
+                  {% include 'show_trait_calculate_correlations.html' %}
                 </div>
-                <div class="panel panel-default">
-                    <div class="panel-heading" data-toggle="collapse" data-parent="#accordion" data-target="#collapseFour">
-                        <h3 class="panel-title">
-                             <span class="glyphicon glyphicon-chevron-down"></span> Calculate Correlations
-                        </h3>
-                    </div>
-                    <div id="collapseFour" class="panel-collapse collapse in">
-                        <div class="panel-body">
-                            {% include 'show_trait_calculate_correlations.html' %}
-                        </div>
-                    </div>
-                </div>                
-                <div class="panel panel-default">
-                    <div class="panel-heading" data-toggle="collapse" data-parent="#accordion" data-target="#collapseFive">
-                        <h3 class="panel-title">
-                             <span class="glyphicon glyphicon-chevron-down"></span> Mapping Tools
-                        </h3>
-                    </div>
-                    <div id="collapseFive" class="panel-collapse collapse in">
-                        <div class="panel-body">
-                            {% include 'show_trait_mapping_tools.html' %}
-                        </div>
-                        <div id="outlier_alert_placeholder"></div>
-                    </div>
-                </div>                
-                <div class="panel panel-default" {% if (trait_table_width|int > 1100) %}style="min-width: {{ trait_table_width|int + 30 }}px;"{% endif %}>
-                    <div class="panel-heading" data-toggle="collapse" data-parent="#accordion" data-target="#collapseSix" aria-expanded="true">
-                        <h3 class="panel-title">
-                             <span class="glyphicon glyphicon-chevron-up"></span> Review and Edit Data
-                        </h3>
-                    </div>
-                    <div id="collapseSix" class="panel-collapse collapse" aria-expanded="true">
-                        <div class="panel-body">
-                            {% include 'show_trait_edit_data.html' %}
-                        </div>
-                    </div>
+              </div>
+            </div>                
+            <div class="panel panel-default">
+              <div class="panel-heading" data-toggle="collapse" data-parent="#accordion" data-target="#collapseFive">
+                <h3 class="panel-title">
+                  <span class="glyphicon glyphicon-chevron-down"></span> Mapping Tools
+                </h3>
+              </div>
+              <div id="collapseFive" class="panel-collapse collapse in">
+                <div class="panel-body">
+                  {% include 'show_trait_mapping_tools.html' %}
                 </div>
+                <div id="outlier_alert_placeholder"></div>
+              </div>
             </div>
-            {% include 'show_trait_progress_bar.html' %}
- 
+	    {%if "group:resource:edit-resource" in trait_privileges%}
+              <div class="panel panel-default" {%if (trait_table_width|int > 1100)%}style="min-width: {{trait_table_width|int + 30}}px;"{% endif %}>
+		<div class="panel-heading" data-toggle="collapse" data-parent="#accordion" data-target="#collapseSix" aria-expanded="true">
+                  <h3 class="panel-title">
+                    <span class="glyphicon glyphicon-chevron-up"></span> Review and Edit Data
+                  </h3>
+		</div>
+		<div id="collapseSix" class="panel-collapse collapse" aria-expanded="true">
+                  <div class="panel-body">
+                    {% include 'show_trait_edit_data.html' %}
+                  </div>
+		</div>
+              </div>
+	    {%endif%}
+          </div>
+          {% include 'show_trait_progress_bar.html' %}
         </div>
-    </form>
+      </form>
+    </div>
+  {%else%}
+    {{display_error("Access Denied", {"error": "AuthorisationError", "error_description": "No read access for user '" + user.name + "'."})}}
+  {%endif%}
 
-    <!-- End of body -->
+  <!-- End of body -->
 
 {% endblock %}
 
diff --git a/wqflask/wqflask/templates/show_trait_details.html b/wqflask/wqflask/templates/show_trait_details.html
index 83ab1482..cce76082 100644
--- a/wqflask/wqflask/templates/show_trait_details.html
+++ b/wqflask/wqflask/templates/show_trait_details.html
@@ -235,7 +235,7 @@
         {% endif %}
         {% endif %}
         <button type="button" id="view_in_gn1" class="btn btn-primary" title="View Trait in GN1" onclick="window.open('http://gn1.genenetwork.org/webqtl/main.py?cmd=show&db={{ this_trait.dataset.name }}&probeset={{ this_trait.name }}', '_blank')">Go to GN1</button>
-        {% if admin_status != None and admin_status.get('metadata', DataRole.VIEW) > DataRole.VIEW %}
+	{%if "group:resource:edit-resource" in trait_privileges%}
         {% if this_trait.dataset.type == 'Publish' %}
         <button type="button" id="edit_resource" class="btn btn-success" title="Edit Resource" onclick="window.open('/datasets/{{ this_trait.dataset.group.id }}/traits/{{ this_trait.name }}?resource-id={{ resource_id }}', '_blank')">Edit</button>
         {% endif %}
@@ -245,9 +245,9 @@
         {% endif %}
         {% endif %}
     </div>
-    {% if admin_status != None and admin_status.get('metadata', DataRole.VIEW) > DataRole.VIEW %}
+    {%if "group:resource:edit-resource" in trait_privileges%}
     <div class="btn-group">
-        <button type="button" id="edit_resource" class="btn btn-success" title="Edit Privileges" onclick="window.open('/resource-management/resources/{{ resource_id }}', '_blank')">Edit Privileges</button>
+        <button type="button" id="edit_resource" class="btn btn-success" title="Edit Privileges" onclick="window.open('{{url_for('oauth2.resource.view_resource', resource_id=resource_id)}}', '_blank')">Edit Privileges</button>
     </div>
     {% endif %}
 </div>
diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py
index 164cf9ce..188dc27b 100644
--- a/wqflask/wqflask/views.py
+++ b/wqflask/wqflask/views.py
@@ -77,6 +77,7 @@ from wqflask.docs import Docs, update_text
 from wqflask.decorators import edit_access_required
 from wqflask.db_info import InfoPage
 
+from wqflask.oauth2 import client
 from wqflask.oauth2.client import no_token_get
 from wqflask.oauth2.request_utils import process_error
 
@@ -494,7 +495,10 @@ def show_temp_trait_page():
 
 @app.route("/show_trait")
 def show_trait_page():
-    def __show_trait__():
+    def __show_trait__(privileges_data):
+        assert len(privileges_data) == 1
+        privileges_data = privileges_data[0]
+        trait_privileges = tuple(item for item in privileges_data["privileges"])
         with database_connection() as conn, conn.cursor() as cursor:
 
             user_id = ((g.user_session.record.get(b"user_id") or b"").decode("utf-8")
@@ -519,7 +523,12 @@ def show_trait_page():
             return render_template(
                 "show_trait.html",
                 metadata=metadata,
-                **template_vars.__dict__)
+                **{
+                    **template_vars.__dict__,
+                    "user": privileges_data["user"],
+                    "trait_privileges": trait_privileges,
+                    "resource_id": privileges_data["resource_id"]
+                })
     dataset = request.args["dataset"]
     trait_id = request.args["trait_id"]
     def __failure__(err):
@@ -527,27 +536,11 @@ def show_trait_page():
         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(
+    return client.post(
         "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__)
+        }).either(__failure__, __show_trait__)
 
 
 @app.route("/heatmap", methods=('POST',))