From ed2ff492bb782a44f0e8b3e6de33095e865f8151 Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Fri, 3 Mar 2023 14:00:21 +0300 Subject: auth: Enable viewing group role details. --- gn3/auth/authorisation/groups/models.py | 42 +++++++++++++++++++++++++++++++++ gn3/auth/authorisation/groups/views.py | 20 ++++++++++++++-- 2 files changed, 60 insertions(+), 2 deletions(-) (limited to 'gn3/auth/authorisation') diff --git a/gn3/auth/authorisation/groups/models.py b/gn3/auth/authorisation/groups/models.py index 2a6f840..777e2d0 100644 --- a/gn3/auth/authorisation/groups/models.py +++ b/gn3/auth/authorisation/groups/models.py @@ -1,6 +1,7 @@ """Handle the management of resource/user groups.""" import json from uuid import UUID, uuid4 +from functools import reduce from typing import Any, Sequence, Iterable, Optional, NamedTuple from flask import g @@ -301,3 +302,44 @@ def accept_reject_join_request( raise AuthorisationError( "You cannot act on other groups join requests") raise NotFoundError(f"Could not find request with ID '{request_id}'") + +def __organise_privileges__(acc, row): + role_id = UUID(row["role_id"]) + role = acc.get(role_id, False) + if role: + return { + **acc, + role_id: Role(role.role_id, role.role_name, role.privileges + ( + Privilege(row["privilege_id"], row["privilege_description"]),)) + } + return { + **acc, + role_id: Role(UUID(row["role_id"]), row["role_name"], ( + Privilege(row["privilege_id"], row["privilege_description"]),)) + } + +# @authorised_p(("group:role:view",), +# "Insufficient privileges to view role", +# oauth2_scope="profile group role") +def group_role_by_id( + conn: db.DbConnection, group: Group, group_role_id: UUID) -> GroupRole: + """Retrieve GroupRole from id by its `group_role_id`.""" + ## TODO: do privileges check before running actual query + ## the check commented out above doesn't work correctly + with db.cursor(conn) as cursor: + cursor.execute( + "SELECT gr.group_role_id, r.*, p.* " + "FROM group_roles AS gr " + "INNER JOIN roles AS r ON gr.role_id=r.role_id " + "INNER JOIN role_privileges AS rp ON rp.role_id=r.role_id " + "INNER JOIN privileges AS p ON p.privilege_id=rp.privilege_id " + "WHERE gr.group_role_id=? AND gr.group_id=?", + (str(group_role_id), str(group.group_id))) + rows = cursor.fetchall() + if rows: + roles: tuple[Role,...] = tuple(reduce( + __organise_privileges__, rows, {}).values()) + assert len(roles) == 1 + return GroupRole(group_role_id, group, roles[0]) + raise NotFoundError( + f"Group role with ID '{group_role_id}' does not exist.") diff --git a/gn3/auth/authorisation/groups/views.py b/gn3/auth/authorisation/groups/views.py index 4da6781..8b7adef 100644 --- a/gn3/auth/authorisation/groups/views.py +++ b/gn3/auth/authorisation/groups/views.py @@ -15,8 +15,9 @@ from gn3.auth.db_utils import with_db_connection from .data import link_data_to_group, retrieve_ungrouped_data from .models import ( user_group, all_groups, DUMMY_GROUP, GroupRole, group_by_id, join_requests, - GroupCreationError, accept_reject_join_request, group_users as _group_users, - create_group as _create_group, create_group_role as _create_group_role) + group_role_by_id, GroupCreationError, accept_reject_join_request, + group_users as _group_users, create_group as _create_group, + create_group_role as _create_group_role) from ..roles.models import Role from ..checks import authorised_p @@ -302,3 +303,18 @@ def create_group_role(): return _create_group_role(conn, group, role_name, privileges) return jsonify(with_db_connection(__create__)) + +@groups.route("/role/", methods=["GET"]) +def view_group_role(group_role_id: uuid.UUID): + """Return the details of the given role.""" + with require_oauth.acquire("profile group role") as the_token: + def __group_role__(conn: db.DbConnection) -> GroupRole: + with db.cursor(conn) as cursor: + group = user_group(cursor, the_token.user).maybe(#type: ignore[misc] + DUMMY_GROUP, lambda grp: grp) + + if group == DUMMY_GROUP: + raise AuthorisationError( + "A user without a group cannot view group roles.") + return group_role_by_id(conn, group, group_role_id) + return jsonify(dictify(with_db_connection(__group_role__))) -- cgit v1.2.3