about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--gn_auth/auth/authorisation/resources/groups/models.py24
-rw-r--r--gn_auth/auth/authorisation/resources/groups/views.py32
2 files changed, 56 insertions, 0 deletions
diff --git a/gn_auth/auth/authorisation/resources/groups/models.py b/gn_auth/auth/authorisation/resources/groups/models.py
index 8b1df90..34f9b93 100644
--- a/gn_auth/auth/authorisation/resources/groups/models.py
+++ b/gn_auth/auth/authorisation/resources/groups/models.py
@@ -655,3 +655,27 @@ def group_leaders(conn: db.DbConnection, group_id: UUID) -> Iterable[User]:
             "AND roles.role_name='group-leader'",
             (str(group_id),))
         yield from (User.from_sqlite3_row(row) for row in cursor.fetchall())
+
+
+def delete_group(conn: db.DbConnection, group_id: UUID):
+    """
+    Delete the group with the given ID
+
+    Parameters:
+        conn (db.DbConnection): an open connection to an SQLite3 database.
+        group_id (uuid.UUID): The identifier for the group to delete.
+
+    Returns:
+        None: It does not return a value.
+
+    Raises:
+        sqlite3.IntegrityError: if the group has members or linked resources, or
+        both.
+    """
+    with db.cursor(conn) as cursor:
+        cursor.execute("DELETE FROM group_join_requests WHERE group_id=?",
+                       (str(group_id),))
+        cursor.execute("DELETE FROM group_resources WHERE group_id=?",
+                       (str(group_id),))
+        cursor.execute("DELETE FROM groups WHERE group_id=?",
+                       (str(group_id),))
diff --git a/gn_auth/auth/authorisation/resources/groups/views.py b/gn_auth/auth/authorisation/resources/groups/views.py
index bfb4c80..2aa115a 100644
--- a/gn_auth/auth/authorisation/resources/groups/views.py
+++ b/gn_auth/auth/authorisation/resources/groups/views.py
@@ -6,6 +6,7 @@ import datetime
 from functools import partial
 from dataclasses import asdict
 
+import sqlite3
 from MySQLdb.cursors import DictCursor
 from flask import jsonify, Response, Blueprint, current_app
 
@@ -41,6 +42,7 @@ from .models import (Group,
                      add_privilege_to_group_role,
                      group_users as _group_users,
                      create_group as _create_group,
+                     delete_group as _delete_group,
                      delete_privilege_from_group_role)
 
 groups = Blueprint("groups", __name__)
@@ -460,3 +462,33 @@ def remove_group_member(group_id: uuid.UUID):
             })
             response.status_code = 400
             return response
+
+
+@groups.route("/<uuid:group_id>/delete", methods=["DELETE"])
+@require_oauth("profile group")
+def delete_group(group_id: uuid.UUID) -> Response:
+    """Delete group with the specified `group_id`."""
+    with (require_oauth.acquire("profile group") as _token,
+          db.connection(current_app.config["AUTH_DB"]) as conn):
+        group = group_by_id(conn, group_id)
+        grp_resource = resource_from_group(conn, group)
+        if not authorised_for_spec(
+                conn,
+                _token.user.user_id,
+                grp_resource.resource_id,
+                "(AND system:group:delete-group)"):
+            raise AuthorisationError(
+                "You do not have appropriate privileges to delete this group.")
+        try:
+            _delete_group(conn, group.group_id)
+            return Response(status=204)
+        except sqlite3.IntegrityError as _s3ie:
+            response = jsonify({
+                "error": "IntegrityError",
+                "error-description": (
+                    "A group that has members, linked resources, or both, "
+                    "cannot be deleted from the system. Remove any members and "
+                    "unlink any linked resources, and try again.")
+            })
+            response.status_code = 400
+            return response