about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFrederick Muriuki Muriithi2024-06-10 16:40:44 -0500
committerFrederick Muriuki Muriithi2024-06-10 16:47:02 -0500
commit43a9bcb8182c4f470ad6d5b613e93db3833e3022 (patch)
tree1ca27bdb7bce19b21016985d773bde21f26106b0
parentf6479e5d018d3c082f02181288e25c90048fb490 (diff)
downloadgn-auth-43a9bcb8182c4f470ad6d5b613e93db3833e3022.tar.gz
Fetch a role by its ID.
-rw-r--r--gn_auth/auth/authorisation/resources/views.py20
-rw-r--r--gn_auth/auth/authorisation/roles/models.py24
2 files changed, 42 insertions, 2 deletions
diff --git a/gn_auth/auth/authorisation/resources/views.py b/gn_auth/auth/authorisation/resources/views.py
index 3300014..21737b3 100644
--- a/gn_auth/auth/authorisation/resources/views.py
+++ b/gn_auth/auth/authorisation/resources/views.py
@@ -20,6 +20,9 @@ from gn_auth.auth.authorisation.roles import Role
 from gn_auth.auth.authorisation.roles.models import db_rows_to_roles
 from gn_auth.auth.authorisation.privileges import Privilege
 from gn_auth.auth.errors import InvalidData, InconsistencyError, AuthorisationError
+from gn_auth.auth.authorisation.roles.models import (role_by_id,
+                                                     db_rows_to_roles,
+                                                     check_user_editable)
 
 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
@@ -495,3 +498,20 @@ def resource_role(resource_id: uuid.UUID, role_id: uuid.UUID):
         }), 500
 
     return asdict(_roles[0])
+
+
+@resources.route("/<uuid:resource_id>/role/<uuid:role_id>/unassign-privilege",
+                 methods=["POST"])
+@require_oauth("profile group resource")
+def unassign_resource_role_privilege(resource_id: uuid.UUID, role_id: uuid.UUID):
+    """Unassign a privilege from a resource role."""
+    with (require_oauth.acquire("profile group resource") as _token,
+          db.connection(app.config["AUTH_DB"]) as conn,
+          db.cursor(conn) as cursor):
+        # TODO: Check whether role is user editable
+        _role = role_by_id(conn, role_id)
+        check_user_editable(_role)
+        # TODO: Check whether user has correct permissions to edit role for this resource
+        pass
+
+    raise NotImplementedError("Not implemented.")
diff --git a/gn_auth/auth/authorisation/roles/models.py b/gn_auth/auth/authorisation/roles/models.py
index 94ad2d1..699e3b3 100644
--- a/gn_auth/auth/authorisation/roles/models.py
+++ b/gn_auth/auth/authorisation/roles/models.py
@@ -2,8 +2,7 @@
 from uuid import UUID, uuid4
 from functools import reduce
 from dataclasses import dataclass
-
-from typing import Sequence, Iterable
+from typing import Sequence, Iterable, Optional
 
 from pymonad.either import Left, Right, Either
 
@@ -219,3 +218,24 @@ def assign_user_role_by_name(
                 "role_id": role["role_id"],
                 "resource_id": str(resource_id)
             })
+
+
+def role_by_id(conn: db.DbConnection, role_id: UUID) -> Optional[Role]:
+    """Fetch a role from the database by its ID."""
+    with db.cursor(conn) as cursor:
+        cursor.execute(
+            "SELECT r.*, p.* FROM roles AS r 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 r.role_id=?",
+            (str(role_id),))
+        results = cursor.fetchall()
+
+    if not bool(results):
+        return None
+
+    _roles = db_rows_to_roles(results)
+    if len(_roles) > 1:
+        raise Exception("Data corruption: Expected a single role.")
+
+    return _roles[0]