aboutsummaryrefslogtreecommitdiff
path: root/gn2/wqflask/oauth2/resources.py
diff options
context:
space:
mode:
Diffstat (limited to 'gn2/wqflask/oauth2/resources.py')
-rw-r--r--gn2/wqflask/oauth2/resources.py294
1 files changed, 294 insertions, 0 deletions
diff --git a/gn2/wqflask/oauth2/resources.py b/gn2/wqflask/oauth2/resources.py
new file mode 100644
index 00000000..7d20b859
--- /dev/null
+++ b/gn2/wqflask/oauth2/resources.py
@@ -0,0 +1,294 @@
+import uuid
+
+from flask import (
+ flash, request, jsonify, url_for, redirect, Response, Blueprint)
+
+from . import client
+from .ui import render_ui
+from .checks import require_oauth2
+from .client import oauth2_get, oauth2_post
+from .request_utils import (
+ flash_error, flash_success, request_error, process_error)
+
+resources = Blueprint("resource", __name__)
+
+@resources.route("/", methods=["GET"])
+@require_oauth2
+def user_resources():
+ """List the resources the user has access to."""
+ def __success__(resources):
+ return render_ui("oauth2/resources.html", resources=resources)
+
+ return oauth2_get("auth/user/resources").either(
+ request_error, __success__)
+
+@resources.route("/create", methods=["GET", "POST"])
+@require_oauth2
+def create_resource():
+ """Create a new resource."""
+ def __render_template__(categories=[], error=None):
+ return render_ui(
+ "oauth2/create-resource.html",
+ resource_categories=categories,
+ resource_category_error=error,
+ resource_name=request.args.get("resource_name"),
+ resource_category=request.args.get("resource_category"))
+
+ if request.method == "GET":
+ return oauth2_get("auth/resource/categories").either(
+ lambda error: __render_template__(error=process_error(
+ error, "Could not retrieve resource categories")),
+ lambda cats: __render_template__(categories=cats))
+
+ def __perr__(error):
+ err = process_error(error)
+ flash(f"{err['error']}: {err['error_description']}", "alert-danger")
+ return redirect(url_for(
+ "oauth2.resource.create_resource",
+ resource_name=request.form.get("resource_name"),
+ resource_category=request.form.get("resource_category")))
+ def __psuc__(succ):
+ flash("Resource created successfully", "alert-success")
+ return redirect(url_for("oauth2.resource.user_resources"))
+ return oauth2_post(
+ "auth/resource/create", data=request.form).either(
+ __perr__, __psuc__)
+
+def __compute_page__(submit, current_page):
+ if submit == "next":
+ return current_page + 1
+ return (current_page - 1) or 1
+
+@resources.route("/view/<uuid:resource_id>", methods=["GET"])
+@require_oauth2
+def view_resource(resource_id: uuid.UUID):
+ """View the given resource."""
+ page = __compute_page__(request.args.get("submit"),
+ int(request.args.get("page", "1"), base=10))
+ count_per_page = int(request.args.get("count_per_page", "100"), base=10)
+ def __users_success__(
+ resource, unlinked_data, users_n_roles, this_user, group_roles,
+ users):
+ return render_ui(
+ "oauth2/view-resource.html", resource=resource,
+ unlinked_data=unlinked_data, users_n_roles=users_n_roles,
+ this_user=this_user, group_roles=group_roles, users=users,
+ page=page, count_per_page=count_per_page)
+
+ def __group_roles_success__(
+ resource, unlinked_data, users_n_roles, this_user, group_roles):
+ return oauth2_get("auth/user/list").either(
+ lambda err: render_ui(
+ "oauth2/view-resource.html", resource=resource,
+ unlinked_data=unlinked_data, users_n_roles=users_n_roles,
+ this_user=this_user, group_roles=group_roles,
+ users_error=process_error(err)),
+ lambda users: __users_success__(
+ resource, unlinked_data, users_n_roles, this_user, group_roles,
+ users))
+
+ def __this_user_success__(resource, unlinked_data, users_n_roles, this_user):
+ return oauth2_get("auth/group/roles").either(
+ lambda err: render_ui(
+ "oauth2/view-resources.html", resource=resource,
+ unlinked_data=unlinked_data, users_n_roles=users_n_roles,
+ this_user=this_user, group_roles_error=process_error(err)),
+ lambda groles: __group_roles_success__(
+ resource, unlinked_data, users_n_roles, this_user, groles))
+
+ def __users_n_roles_success__(resource, unlinked_data, users_n_roles):
+ return oauth2_get("auth/user/").either(
+ lambda err: render_ui(
+ "oauth2/view-resources.html",
+ this_user_error=process_error(err)),
+ lambda usr_dets: __this_user_success__(
+ resource, unlinked_data, users_n_roles, usr_dets))
+
+ def __unlinked_success__(resource, unlinked_data):
+ return oauth2_get(f"auth/resource/{resource_id}/user/list").either(
+ lambda err: render_ui(
+ "oauth2/view-resource.html",
+ resource=resource,
+ unlinked_data=unlinked_data,
+ users_n_roles_error=process_error(err),
+ page=page,
+ count_per_page=count_per_page),
+ lambda users_n_roles: __users_n_roles_success__(
+ resource, unlinked_data, users_n_roles))
+
+ def __resource_success__(resource):
+ dataset_type = resource["resource_category"]["resource_category_key"]
+ return oauth2_get(f"auth/group/{dataset_type}/unlinked-data").either(
+ lambda err: render_ui(
+ "oauth2/view-resource.html", resource=resource,
+ unlinked_error=process_error(err)),
+ lambda unlinked: __unlinked_success__(resource, unlinked))
+
+ def __fetch_resource_data__(resource):
+ """Fetch the resource's data."""
+ return client.get(
+ f"auth/resource/view/{resource['resource_id']}/data?page={page}"
+ f"&count_per_page={count_per_page}").either(
+ lambda err: {
+ **resource, "resource_data_error": process_error(err)
+ },
+ lambda resdata: {**resource, "resource_data": resdata})
+
+ return oauth2_get(f"auth/resource/view/{resource_id}").map(
+ __fetch_resource_data__).either(
+ lambda err: render_ui(
+ "oauth2/view-resource.html",
+ resource=None, resource_error=process_error(err)),
+ __resource_success__)
+
+@resources.route("/data/link", methods=["POST"])
+@require_oauth2
+def link_data_to_resource():
+ """Link group data to a resource"""
+ form = request.form
+ try:
+ assert "resource_id" in form, "Resource ID not provided."
+ assert "data_link_id" in form, "Data Link ID not provided."
+ assert "dataset_type" in form, "Dataset type not specified"
+ assert form["dataset_type"].lower() in (
+ "mrna", "genotype", "phenotype"), "Invalid dataset type provided."
+ resource_id = form["resource_id"]
+
+ def __error__(error):
+ err = process_error(error)
+ flash(f"{err['error']}: {err['error_description']}", "alert-danger")
+ return redirect(url_for(
+ "oauth2.resource.view_resource", resource_id=resource_id))
+
+ def __success__(success):
+ flash(f"Data linked to resource successfully", "alert-success")
+ return redirect(url_for(
+ "oauth2.resource.view_resource", resource_id=resource_id))
+ return oauth2_post("auth/resource/data/link", data=dict(form)).either(
+ __error__,
+ __success__)
+ except AssertionError as aserr:
+ flash(aserr.args[0], "alert-danger")
+ return redirect(url_for(
+ "oauth2.resource.view_resource", resource_id=form["resource_id"]))
+
+@resources.route("/data/unlink", methods=["POST"])
+@require_oauth2
+def unlink_data_from_resource():
+ """Unlink group data from a resource"""
+ form = request.form
+ try:
+ assert "resource_id" in form, "Resource ID not provided."
+ assert "data_link_id" in form, "Data Link ID not provided."
+ resource_id = form["resource_id"]
+
+ def __error__(error):
+ err = process_error(error)
+ flash(f"{err['error']}: {err['error_description']}", "alert-danger")
+ return redirect(url_for(
+ "oauth2.resource.view_resource", resource_id=resource_id))
+
+ def __success__(success):
+ flash(f"Data unlinked from resource successfully", "alert-success")
+ return redirect(url_for(
+ "oauth2.resource.view_resource", resource_id=resource_id))
+ return oauth2_post(
+ "auth/resource/data/unlink", data=dict(form)).either(
+ __error__, __success__)
+ except AssertionError as aserr:
+ flash(aserr.args[0], "alert-danger")
+ return redirect(url_for(
+ "oauth2.resource.view_resource", resource_id=form["resource_id"]))
+
+@resources.route("<uuid:resource_id>/user/assign", methods=["POST"])
+@require_oauth2
+def assign_role(resource_id: uuid.UUID) -> Response:
+ form = request.form
+ group_role_id = form.get("group_role_id", "")
+ user_email = form.get("user_email", "")
+ try:
+ assert bool(group_role_id), "The role must be provided."
+ assert bool(user_email), "The user email must be provided."
+
+ def __assign_error__(error):
+ err = process_error(error)
+ flash(f"{err['error']}: {err['error_description']}", "alert-danger")
+ return redirect(url_for(
+ "oauth2.resource.view_resource", resource_id=resource_id))
+
+ def __assign_success__(success):
+ flash(success["description"], "alert-success")
+ return redirect(url_for(
+ "oauth2.resource.view_resource", resource_id=resource_id))
+
+ return oauth2_post(
+ f"auth/resource/{resource_id}/user/assign",
+ data={
+ "group_role_id": group_role_id,
+ "user_email": user_email
+ }).either(__assign_error__, __assign_success__)
+ except AssertionError as aserr:
+ flash(aserr.args[0], "alert-danger")
+ return redirect(url_for("oauth2.resources.view_resource", resource_id=resource_id))
+
+@resources.route("<uuid:resource_id>/user/unassign", methods=["POST"])
+@require_oauth2
+def unassign_role(resource_id: uuid.UUID) -> Response:
+ form = request.form
+ group_role_id = form.get("group_role_id", "")
+ user_id = form.get("user_id", "")
+ try:
+ assert bool(group_role_id), "The role must be provided."
+ assert bool(user_id), "The user id must be provided."
+
+ def __unassign_error__(error):
+ err = process_error(error)
+ flash(f"{err['error']}: {err['error_description']}", "alert-danger")
+ return redirect(url_for(
+ "oauth2.resource.view_resource", resource_id=resource_id))
+
+ def __unassign_success__(success):
+ flash(success["description"], "alert-success")
+ return redirect(url_for(
+ "oauth2.resource.view_resource", resource_id=resource_id))
+
+ return oauth2_post(
+ f"auth/resource/{resource_id}/user/unassign",
+ data={
+ "group_role_id": group_role_id,
+ "user_id": user_id
+ }).either(__unassign_error__, __unassign_success__)
+ except AssertionError as aserr:
+ flash(aserr.args[0], "alert-danger")
+ return redirect(url_for("oauth2.resources.view_resource", resource_id=resource_id))
+
+@resources.route("/toggle/<uuid:resource_id>", methods=["POST"])
+@require_oauth2
+def toggle_public(resource_id: uuid.UUID):
+ """Toggle the given resource's public status."""
+ def __handle_error__(err):
+ flash_error(process_error(err))
+ return redirect(url_for(
+ "oauth2.resource.view_resource", resource_id=resource_id))
+
+ def __handle_success__(success):
+ flash_success(success)
+ return redirect(url_for(
+ "oauth2.resource.view_resource", resource_id=resource_id))
+
+ return oauth2_post(
+ f"auth/resource/{resource_id}/toggle-public", data={}).either(
+ lambda err: __handle_error__(err),
+ lambda suc: __handle_success__(suc))
+
+@resources.route("/edit/<uuid:resource_id>", methods=["GET"])
+@require_oauth2
+def edit_resource(resource_id: uuid.UUID):
+ """Edit the given resource."""
+ return "WOULD Edit THE GIVEN RESOURCE'S DETAILS"
+
+@resources.route("/delete/<uuid:resource_id>", methods=["GET"])
+@require_oauth2
+def delete_resource(resource_id: uuid.UUID):
+ """Delete the given resource."""
+ return "WOULD DELETE THE GIVEN RESOURCE"