about summary refs log tree commit diff
path: root/gn_auth/auth/authorisation/resources/views.py
diff options
context:
space:
mode:
Diffstat (limited to 'gn_auth/auth/authorisation/resources/views.py')
-rw-r--r--gn_auth/auth/authorisation/resources/views.py83
1 files changed, 72 insertions, 11 deletions
diff --git a/gn_auth/auth/authorisation/resources/views.py b/gn_auth/auth/authorisation/resources/views.py
index 31421f4..a960ca3 100644
--- a/gn_auth/auth/authorisation/resources/views.py
+++ b/gn_auth/auth/authorisation/resources/views.py
@@ -39,21 +39,23 @@ from gn_auth.auth.authorisation.roles.models import (
 from gn_auth.auth.authentication.oauth2.resource_server import require_oauth
 from gn_auth.auth.authentication.users import User, user_by_id, user_by_email
 
-from .checks import authorised_for
 from .inbredset.views import popbp
 from .genotypes.views import genobp
+from .phenotypes.views import phenobp
 from .errors import MissingGroupError
 from .groups.models import Group, user_group
+from .checks import authorised_for, authorised_for_spec
 from .models import (
     Resource, resource_data, resource_by_id, public_resources,
     resource_categories, assign_resource_user, link_data_to_resource,
     unassign_resource_user, resource_category_by_id, user_roles_on_resources,
     unlink_data_from_resource, create_resource as _create_resource,
-    get_resource_id)
+    get_resource_id, delete_resource as _delete_resource)
 
 resources = Blueprint("resources", __name__)
 resources.register_blueprint(popbp, url_prefix="/")
 resources.register_blueprint(genobp, url_prefix="/")
+resources.register_blueprint(phenobp, url_prefix="/")
 
 @resources.route("/categories", methods=["GET"])
 @require_oauth("profile group resource")
@@ -73,8 +75,7 @@ def create_resource() -> Response:
         resource_name = form.get("resource_name")
         resource_category_id = UUID(form.get("resource_category"))
         db_uri = app.config["AUTH_DB"]
-        with (db.connection(db_uri) as conn,
-              db.cursor(conn) as cursor):
+        with db.connection(db_uri) as conn:
             try:
                 group = user_group(conn, the_token.user).maybe(
                     False, lambda grp: grp)# type: ignore[misc, arg-type]
@@ -82,7 +83,7 @@ def create_resource() -> Response:
                     raise MissingGroupError(# Not all resources require an owner group
                         "User with no group cannot create a resource.")
                 resource = _create_resource(
-                    cursor,
+                    conn,
                     resource_name,
                     resource_category_by_id(conn, resource_category_id),
                     the_token.user,
@@ -98,7 +99,9 @@ def create_resource() -> Response:
                     f"{type(sql3ie)=}: {sql3ie=}")
                 raise
 
+
 @resources.route("/view/<uuid:resource_id>")
+@resources.route("/<uuid:resource_id>/view")
 @require_oauth("profile group resource")
 def view_resource(resource_id: UUID) -> Response:
     """View a particular resource's details."""
@@ -135,7 +138,7 @@ def view_resource_data(resource_id: UUID) -> Response:
     with require_oauth.acquire("profile group resource") as the_token:
         db_uri = app.config["AUTH_DB"]
         count_per_page = __safe_get_requests_count__("count_per_page")
-        offset = (__safe_get_requests_page__("page") - 1)
+        offset = __safe_get_requests_page__("page") - 1
         with db.connection(db_uri) as conn:
             resource = resource_by_id(conn, the_token.user, resource_id)
             return jsonify(resource_data(
@@ -151,7 +154,7 @@ def link_data():
     try:
         form = request_json()
         assert "resource_id" in form, "Resource ID not provided."
-        assert "data_link_id" in form, "Data Link ID not provided."
+        assert "data_link_ids" in form, "Data Link IDs not provided."
         assert "dataset_type" in form, "Dataset type not specified"
         assert form["dataset_type"].lower() in (
             "mrna", "genotype", "phenotype"), "Invalid dataset type provided."
@@ -159,8 +162,11 @@ def link_data():
         with require_oauth.acquire("profile group resource") as the_token:
             def __link__(conn: db.DbConnection):
                 return link_data_to_resource(
-                    conn, the_token.user, UUID(form["resource_id"]),
-                    form["dataset_type"], UUID(form["data_link_id"]))
+                    conn,
+                    the_token.user,
+                    UUID(form["resource_id"]),
+                    form["dataset_type"],
+                    tuple(UUID(dlinkid) for dlinkid in form["data_link_ids"]))
 
             return jsonify(with_db_connection(__link__))
     except AssertionError as aserr:
@@ -409,9 +415,18 @@ def resource_roles(resource_id: UUID) -> Response:
                     "ON rp.privilege_id=p.privilege_id "
                     "WHERE rr.resource_id=? AND rr.role_created_by=?",
                     (str(resource_id), str(_token.user.user_id)))
-                results = cursor.fetchall()
+                user_created = db_rows_to_roles(cursor.fetchall())
+
+                cursor.execute(
+                    "SELECT ur.user_id, ur.resource_id, r.*, p.* FROM user_roles AS ur "
+                    "INNER JOIN roles AS r ON ur.role_id=r.role_id "
+                    "INNER JOIN role_privileges AS rp ON r.role_id=rp.role_id "
+                    "INNER JOIN privileges AS p ON rp.privilege_id=p.privilege_id "
+                    "WHERE resource_id=? AND user_id=?",
+                    (str(resource_id), str(_token.user.user_id)))
+                assigned_to_user = db_rows_to_roles(cursor.fetchall())
 
-            return db_rows_to_roles(results)
+            return assigned_to_user + user_created
 
         return jsonify(with_db_connection(__roles__))
 
@@ -659,3 +674,49 @@ def user_resource_roles(resource_id: UUID, user_id: UUID):
 
         return jsonify([asdict(role) for role in
                         _user_resource_roles(conn, _token.user, _resource)])
+
+
+@resources.route("/delete", methods=["POST"])
+@require_oauth("profile group resource")
+def delete_resource():
+    """Delete the specified resource, if possible."""
+    with (require_oauth.acquire("profile group resource") as the_token,
+          db.connection(app.config["AUTH_DB"]) as conn):
+        form = request_json()
+        try:
+            resource_id = UUID(form.get("resource_id"))
+            if not authorised_for_spec(
+                    conn,
+                    the_token.user.user_id,
+                    resource_id,
+                    "(OR group:resource:delete-resource system:resource:delete)"):
+                raise AuthorisationError("You do not have the appropriate "
+                                         "privileges to delete this resource.")
+
+            data = resource_data(
+                conn,
+                resource_by_id(conn, the_token.user, resource_id),
+                0,
+                10)
+            if bool(data):
+                return jsonify({
+                    "error": "NonEmptyResouce",
+                    "error-description": "Cannot delete a resource with linked data"
+                }), 400
+
+            _delete_resource(conn, resource_id)
+            return jsonify({
+                "description": f"Successfully deleted resource with ID '{resource_id}'."
+            })
+        except ValueError as _verr:
+            app.logger.debug("Error!", exc_info=True)
+            return jsonify({
+                "error": "ValueError",
+                "error-description": "An invalid identifier was provided"
+            }), 400
+        except TypeError as _terr:
+            app.logger.debug("Error!", exc_info=True)
+            return jsonify({
+                "error": "TypeError",
+                "error-description": "An invalid identifier was provided"
+            }), 400