From bbd61fc91bd9bdbf41201dd8f609e02ef8339974 Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Tue, 28 Feb 2023 12:45:57 +0300 Subject: auth: Unlink data from resources Enable the data editor to unlink data from a particular resource. --- gn3/auth/authorisation/resources/models.py | 65 ++++++++++++++++++++++++++++++ gn3/auth/authorisation/resources/views.py | 23 ++++++++++- 2 files changed, 87 insertions(+), 1 deletion(-) (limited to 'gn3') diff --git a/gn3/auth/authorisation/resources/models.py b/gn3/auth/authorisation/resources/models.py index 8940e00..13f234f 100644 --- a/gn3/auth/authorisation/resources/models.py +++ b/gn3/auth/authorisation/resources/models.py @@ -321,6 +321,13 @@ def link_data_to_resource( conn: db.DbConnection, user: User, resource_id: UUID, dataset_type: str, dataset_id: str): """Link data to resource.""" + if not authorised_for( + conn, user, ("group:resource:edit-resource",), + (resource_id,))[resource_id]: + raise AuthorisationError( + "You are not authorised to link data to resource with id " + f"{resource_id}") + resource = with_db_connection(partial( resource_by_id, user=user, resource_id=resource_id)) return { @@ -329,6 +336,64 @@ def link_data_to_resource( "phenotype": __link_pheno_data_to_resource__, }[dataset_type.lower()](conn, resource, dataset_id) +def __unlink_mrna_data_to_resource__( + conn: db.DbConnection, resource: Resource, dataset_id: str) -> dict: + """Unlink data from mRNA Assay resources""" + with db.cursor(conn) as cursor: + cursor.execute("DELETE FROM mrna_resources " + "WHERE resource_id=? AND dataset_id=?", + (str(resource.resource_id), dataset_id)) + return { + "resource_id": str(resource.resource_id), + "dataset_type": resource.resource_category.resource_category_key, + "dataset_id": dataset_id + } + +def __unlink_geno_data_to_resource__( + conn: db.DbConnection, resource: Resource, trait_id: str) -> dict: + """Unlink data from Genotype resources""" + with db.cursor(conn) as cursor: + cursor.execute("DELETE FROM genotype_resources " + "WHERE resource_id=? AND trait_id=?", + (str(resource.resource_id), trait_id)) + return { + "resource_id": str(resource.resource_id), + "dataset_type": resource.resource_category.resource_category_key, + "dataset_id": trait_id + } + +def __unlink_pheno_data_to_resource__( + conn: db.DbConnection, resource: Resource, trait_id: str) -> dict: + """Unlink data from Phenotype resources""" + with db.cursor(conn) as cursor: + cursor.execute("DELETE FROM phenotype_resources " + "WHERE resource_id=? AND trait_id=?", + (str(resource.resource_id), trait_id)) + return { + "resource_id": str(resource.resource_id), + "dataset_type": resource.resource_category.resource_category_key, + "dataset_id": trait_id + } + +def unlink_data_from_resource( + conn: db.DbConnection, user: User, resource_id: UUID, dataset_id: str): + """Unlink data from resource.""" + if not authorised_for( + conn, user, ("group:resource:edit-resource",), + (resource_id,))[resource_id]: + raise AuthorisationError( + "You are not authorised to link data to resource with id " + f"{resource_id}") + + resource = with_db_connection(partial( + resource_by_id, user=user, resource_id=resource_id)) + dataset_type = resource.resource_category.resource_category_key + return { + "mrna": __unlink_mrna_data_to_resource__, + "genotype": __unlink_geno_data_to_resource__, + "phenotype": __unlink_pheno_data_to_resource__, + }[dataset_type.lower()](conn, resource, dataset_id) + def organise_resources_by_category(resources: Sequence[Resource]) -> dict[ ResourceCategory, tuple[Resource]]: """Organise the `resources` by their categories.""" diff --git a/gn3/auth/authorisation/resources/views.py b/gn3/auth/authorisation/resources/views.py index b2773a8..cac904c 100644 --- a/gn3/auth/authorisation/resources/views.py +++ b/gn3/auth/authorisation/resources/views.py @@ -7,7 +7,8 @@ from gn3.auth.db_utils import with_db_connection from .models import ( resource_by_id, resource_categories, link_data_to_resource, - resource_category_by_id, create_resource as _create_resource) + resource_category_by_id, unlink_data_from_resource, + create_resource as _create_resource) from ..errors import InvalidData @@ -73,3 +74,23 @@ def link_data(): return jsonify(with_db_connection(__link__)) except AssertionError as aserr: raise InvalidData(aserr.args[0]) from aserr + + + +@resources.route("/data/unlink", methods=["POST"]) +@require_oauth("profile group resource") +def unlink_data(): + """Unlink data bound to a specific resource.""" + try: + form = request.form + assert "resource_id" in form, "Resource ID not provided." + assert "dataset_id" in form, "Dataset ID not provided." + + with require_oauth.acquire("profile group resource") as the_token: + def __unlink__(conn: db.DbConnection): + return unlink_data_from_resource( + conn, the_token.user, uuid.UUID(form["resource_id"]), + form["dataset_id"]) + return jsonify(with_db_connection(__unlink__)) + except AssertionError as aserr: + raise InvalidData(aserr.args[0]) from aserr -- cgit v1.2.3