about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFrederick Muriuki Muriithi2024-07-17 14:08:13 -0500
committerFrederick Muriuki Muriithi2024-07-17 14:08:13 -0500
commit2aa4d3f683733899edd58831ed6c413349167725 (patch)
tree34daccfc89d2d9ade14b7605e20e208af8162361
parent3b36aa4d99835e8fc9fb677d729def178a0c9e54 (diff)
downloadgn-auth-2aa4d3f683733899edd58831ed6c413349167725.tar.gz
Add non-interactive script to assign make data public by default.
-rw-r--r--gn_auth/auth/authorisation/resources/groups/models.py8
-rw-r--r--scripts/batch_assign_data_to_default_admin.py89
2 files changed, 97 insertions, 0 deletions
diff --git a/gn_auth/auth/authorisation/resources/groups/models.py b/gn_auth/auth/authorisation/resources/groups/models.py
index ee77654..3263e37 100644
--- a/gn_auth/auth/authorisation/resources/groups/models.py
+++ b/gn_auth/auth/authorisation/resources/groups/models.py
@@ -5,6 +5,7 @@ from functools import reduce
 from dataclasses import dataclass
 from typing import Any, Sequence, Iterable, Optional
 
+import sqlite3
 from flask import g
 from pymonad.maybe import Just, Maybe, Nothing
 
@@ -63,6 +64,13 @@ class MembershipError(AuthorisationError):
         super().__init__(f"{type(self).__name__}: {error_description}.")
 
 
+def db_row_to_group(row: sqlite3.Row) -> Group:
+    """Convert a database row into a group."""
+    return Group(UUID(row["group_id"]),
+                 row["group_name"],
+                 json.loads(row["group_metadata"]))
+
+
 def user_membership(conn: db.DbConnection, user: User) -> Sequence[Group]:
     """Returns all the groups that a member belongs to"""
     query = (
diff --git a/scripts/batch_assign_data_to_default_admin.py b/scripts/batch_assign_data_to_default_admin.py
new file mode 100644
index 0000000..1f6c9c9
--- /dev/null
+++ b/scripts/batch_assign_data_to_default_admin.py
@@ -0,0 +1,89 @@
+"""
+Similar to the 'assign_data_to_default_admin' script but without user
+interaction.
+"""
+import sys
+import logging
+from pathlib import Path
+
+import click
+from MySQLdb.cursors import DictCursor
+from pymonad.maybe import Just, Maybe, Nothing
+from pymonad.tools import curry, monad_from_none_or_value
+
+from gn_auth.auth.db import mariadb as biodb
+from gn_auth.auth.db import sqlite3 as authdb
+from gn_auth.auth.authentication.users import User
+from gn_auth.auth.authorisation.resources.groups.models import (
+    Group, db_row_to_group)
+
+from scripts.assign_data_to_default_admin import (
+    default_resources, assign_data_to_resource)
+
+
+def resources_group(conn: authdb.DbConnection) -> Maybe:
+    """Retrieve resources' group"""
+    with authdb.cursor(conn) as cursor:
+        cursor.execute(
+            "SELECT g.* FROM resources AS r "
+            "INNER JOIN resource_ownership AS ro "
+            "ON r.resource_id=ro.resource_id "
+            "INNER JOIN groups AS g ON ro.group_id=g.group_id "
+            "WHERE resource_name='mRNA-euhrin'")
+        return monad_from_none_or_value(
+            Nothing, Just, cursor.fetchone()).then(
+                db_row_to_group)
+
+
+def resource_owner(conn: authdb.DbConnection) -> Maybe:
+    """Retrieve the resource owner."""
+    with authdb.cursor(conn) as cursor:
+        cursor.execute(
+            "SELECT u.* FROM users AS u WHERE u.user_id IN "
+            "(SELECT ur.user_id FROM resources AS rsc "
+            "INNER JOIN user_roles AS ur ON rsc.resource_id=ur.resource_id "
+            "INNER JOIN roles AS r on ur.role_id=r.role_id "
+            "WHERE resource_name='mRNA-euhrin' "
+            "AND r.role_name='resource-owner')")
+        return monad_from_none_or_value(
+            Nothing, Just, cursor.fetchone()).then(
+                User.from_sqlite3_row)
+
+
+
+def assign_data(authconn: authdb.DbConnection, bioconn, group: Group):
+    """Do actual data assignments."""
+    try:
+        for resource in default_resources(authconn, group):
+            assign_data_to_resource(authconn, bioconn, resource, group)
+
+        return 1
+    except Exception as _exc:
+        logging.error("Failed to assign some data!", exc_info=True)
+        return 1
+    
+
+if __name__ == "__main__":
+    @click.command()
+    @click.argument("authdbpath") # "Path to the Auth(entic|oris)ation database"
+    @click.argument("mysqldburi") # "URI to the MySQL database with the biology data"
+    @click.option("--loglevel",
+                  default="WARNING",
+                  show_default=True,
+                  type=click.Choice([
+                      "CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"]))
+    def run(authdbpath, mysqldburi, loglevel):
+        """Script entry point."""
+        _logger = logging.getLogger()
+        _logger.setLevel(loglevel)
+        if Path(authdbpath).exists():
+            with (authdb.connection(authdbpath) as authconn,
+                  biodb.database_connection(mysqldburi) as bioconn):
+                return resources_group(authconn).maybe(
+                    1,
+                    lambda group: assign_data(authconn, bioconn, group))
+
+        logging.error("There is no such SQLite3 database file.")
+        return 1
+
+    sys.exit(run())