about summary refs log tree commit diff
path: root/gn_auth/auth/authorisation/resources/models.py
diff options
context:
space:
mode:
Diffstat (limited to 'gn_auth/auth/authorisation/resources/models.py')
-rw-r--r--gn_auth/auth/authorisation/resources/models.py98
1 files changed, 62 insertions, 36 deletions
diff --git a/gn_auth/auth/authorisation/resources/models.py b/gn_auth/auth/authorisation/resources/models.py
index c1748f1..31371fd 100644
--- a/gn_auth/auth/authorisation/resources/models.py
+++ b/gn_auth/auth/authorisation/resources/models.py
@@ -4,8 +4,6 @@ from uuid import UUID, uuid4
 from functools import reduce, partial
 from typing import Dict, Sequence, Optional
 
-import sqlite3
-
 from gn_auth.auth.db import sqlite3 as db
 from gn_auth.auth.authentication.users import User
 from gn_auth.auth.db.sqlite3 import with_db_connection
@@ -15,10 +13,12 @@ from gn_auth.auth.authorisation.privileges import Privilege
 from gn_auth.auth.authorisation.checks import authorised_p
 from gn_auth.auth.errors import NotFoundError, AuthorisationError
 
-from .checks import authorised_for
+from .system.models import system_resource
+from .checks import authorised_for, authorised_for_spec
 from .base import Resource, ResourceCategory, resource_from_dbrow
-from .common import assign_resource_owner_role
+from .common import assign_resource_owner_role, grant_access_to_sysadmins
 from .groups.models import Group, is_group_leader
+from .inbredset.models import resource_data as inbredset_resource_data
 from .mrna import (
     resource_data as mrna_resource_data,
     attach_resources_data as mrna_attach_resources_data,
@@ -39,8 +39,8 @@ from .phenotypes.models import (
 @authorised_p(("group:resource:create-resource",),
               error_description="Insufficient privileges to create a resource",
               oauth2_scope="profile resource")
-def create_resource(# pylint: disable=[too-many-arguments]
-        cursor: sqlite3.Cursor,
+def create_resource(# pylint: disable=[too-many-arguments, too-many-positional-arguments]
+        conn: db.DbConnection,
         resource_name: str,
         resource_category: ResourceCategory,
         user: User,
@@ -48,29 +48,48 @@ def create_resource(# pylint: disable=[too-many-arguments]
         public: bool
 ) -> Resource:
     """Create a resource item."""
-    resource = Resource(uuid4(), resource_name, resource_category, public)
-    cursor.execute(
-        "INSERT INTO resources VALUES (?, ?, ?, ?)",
-        (str(resource.resource_id),
-         resource_name,
-         str(resource.resource_category.resource_category_id),
-         1 if resource.public else 0))
-    # TODO: @fredmanglis,@rookie101
-    # 1. Move the actions below into a (the?) hooks system
-    # 2. Do more checks: A resource can have varying hooks depending on type
-    #    e.g. if mRNA, pheno or geno resource, assign:
-    #           - "resource-owner"
-    #         if inbredset-group, assign:
-    #           - "resource-owner",
-    #           - "inbredset-group-owner" etc.
-    #         if resource is of type "group", assign:
-    #           - group-leader
-    cursor.execute("INSERT INTO resource_ownership (group_id, resource_id) "
-                   "VALUES (?, ?)",
-                   (str(group.group_id), str(resource.resource_id)))
-    assign_resource_owner_role(cursor, resource.resource_id, user.user_id)
-
-    return resource
+    with db.cursor(conn) as cursor:
+        resource = Resource(uuid4(), resource_name, resource_category, public)
+        cursor.execute(
+            "INSERT INTO resources VALUES (?, ?, ?, ?)",
+            (str(resource.resource_id),
+             resource_name,
+             str(resource.resource_category.resource_category_id),
+             1 if resource.public else 0))
+        # TODO: @fredmanglis,@rookie101
+        # 1. Move the actions below into a (the?) hooks system
+        # 2. Do more checks: A resource can have varying hooks depending on type
+        #    e.g. if mRNA, pheno or geno resource, assign:
+        #           - "resource-owner"
+        #         if inbredset-group, assign:
+        #           - "resource-owner",
+        #           - "inbredset-group-owner" etc.
+        #         if resource is of type "group", assign:
+        #           - group-leader
+        cursor.execute("INSERT INTO resource_ownership (group_id, resource_id) "
+                       "VALUES (?, ?)",
+                       (str(group.group_id), str(resource.resource_id)))
+        assign_resource_owner_role(cursor, resource.resource_id, user.user_id)
+        grant_access_to_sysadmins(
+            cursor, resource.resource_id, system_resource(conn).resource_id)
+
+        return resource
+
+
+def delete_resource(conn: db.DbConnection, resource_id: UUID):
+    """Delete a resource."""
+    with db.cursor(conn) as cursor:
+        cursor.execute("DELETE FROM user_roles WHERE resource_id=?",
+                       (str(resource_id),))
+        cursor.execute("DELETE FROM resource_roles WHERE resource_id=?",
+                       (str(resource_id),))
+        cursor.execute("DELETE FROM group_resources WHERE resource_id=?",
+                       (str(resource_id),))
+        cursor.execute("DELETE FROM resource_ownership WHERE resource_id=?",
+                       (str(resource_id),))
+        cursor.execute("DELETE FROM resources WHERE resource_id=?",
+                       (str(resource_id),))
+
 
 def resource_category_by_id(
         conn: db.DbConnection, category_id: UUID) -> ResourceCategory:
@@ -159,7 +178,8 @@ def resource_data(conn, resource, offset: int = 0, limit: Optional[int] = None)
         "genotype-metadata": lambda *args: tuple(),
         "mrna-metadata": lambda *args: tuple(),
         "system": lambda *args: tuple(),
-        "group": lambda *args: tuple()
+        "group": lambda *args: tuple(),
+        "inbredset-group": inbredset_resource_data,
     }
     with db.cursor(conn) as cursor:
         return tuple(
@@ -187,9 +207,11 @@ def attach_resource_data(cursor: db.DbCursor, resource: Resource) -> Resource:
 def resource_by_id(
         conn: db.DbConnection, user: User, resource_id: UUID) -> Resource:
     """Retrieve a resource by its ID."""
-    if not authorised_for(
-            conn, user, ("group:resource:view-resource",),
-            (resource_id,))[resource_id]:
+    if not authorised_for_spec(
+            conn,
+            user.user_id,
+            resource_id,
+            "(OR group:resource:view-resource system:resource:view)"):
         raise AuthorisationError(
             "You are not authorised to access resource with id "
             f"'{resource_id}'.")
@@ -207,8 +229,12 @@ def resource_by_id(
     raise NotFoundError(f"Could not find a resource with id '{resource_id}'")
 
 def link_data_to_resource(
-        conn: db.DbConnection, user: User, resource_id: UUID, dataset_type: str,
-        data_link_id: UUID) -> dict:
+        conn: db.DbConnection,
+        user: User,
+        resource_id: UUID,
+        dataset_type: str,
+        data_link_ids: tuple[UUID, ...]
+) -> tuple[dict, ...]:
     """Link data to resource."""
     if not authorised_for(
             conn, user, ("group:resource:edit-resource",),
@@ -223,7 +249,7 @@ def link_data_to_resource(
         "mrna": mrna_link_data_to_resource,
         "genotype": genotype_link_data_to_resource,
         "phenotype": phenotype_link_data_to_resource,
-    }[dataset_type.lower()](conn, resource, data_link_id)
+    }[dataset_type.lower()](conn, resource, data_link_ids)
 
 def unlink_data_from_resource(
         conn: db.DbConnection, user: User, resource_id: UUID, data_link_id: UUID):