From da81bd858c167e261e42caa934b5e7879daba249 Mon Sep 17 00:00:00 2001 From: dettlaff Date: Thu, 12 Dec 2024 23:53:41 +0400 Subject: [PATCH] feat: add groups query --- selfprivacy_api/actions/users.py | 5 +-- .../graphql/common_types/groups.py | 33 +++++++++++++++++++ selfprivacy_api/graphql/queries/groups.py | 23 +++++++++++++ selfprivacy_api/graphql/queries/users.py | 5 --- selfprivacy_api/models/group.py | 13 ++++++++ .../users/kanidm_user_repository.py | 21 ++++++++++-- 6 files changed, 90 insertions(+), 10 deletions(-) create mode 100644 selfprivacy_api/graphql/common_types/groups.py create mode 100644 selfprivacy_api/graphql/queries/groups.py create mode 100644 selfprivacy_api/models/group.py diff --git a/selfprivacy_api/actions/users.py b/selfprivacy_api/actions/users.py index 28b1b44..bc74ce4 100644 --- a/selfprivacy_api/actions/users.py +++ b/selfprivacy_api/actions/users.py @@ -6,6 +6,7 @@ import logging from typing import Optional from selfprivacy_api import PLEASE_UPDATE_APP_TEXT +from selfprivacy_api.models.group import Group from selfprivacy_api.models.user import UserDataUser, UserDataUserOrigin from selfprivacy_api.utils import is_username_forbidden @@ -189,8 +190,8 @@ def generate_password_reset_link(username: str) -> str: return ACTIVE_USERS_PROVIDER.generate_password_reset_link(username=username) -def groups_list() -> list: +def get_groups() -> list[Group]: if isinstance(ACTIVE_USERS_PROVIDER, JsonUserRepository): raise ApiUsingWrongUserRepository - return ACTIVE_USERS_PROVIDER.groups_list() + return ACTIVE_USERS_PROVIDER.get_groups() diff --git a/selfprivacy_api/graphql/common_types/groups.py b/selfprivacy_api/graphql/common_types/groups.py new file mode 100644 index 0000000..cbca140 --- /dev/null +++ b/selfprivacy_api/graphql/common_types/groups.py @@ -0,0 +1,33 @@ +from typing import Optional + +import strawberry + +from selfprivacy_api.actions.users import get_groups as actions_get_groups + + +@strawberry.type +class Group: + name: str + group_class: list + member: Optional[list[str]] = strawberry.field(default_factory=list) + memberof: Optional[list[str]] = strawberry.field(default_factory=list) + directmemberof: Optional[list[str]] = strawberry.field(default_factory=list) + spn: Optional[str] = None + description: Optional[str] = None + + +def get_groups() -> list[Group]: + """Get groups""" + groups = actions_get_groups() + return [ + Group( + name=group.name, + group_class=getattr(group, "group_class", []), + member=getattr(group, "member", []), + memberof=getattr(group, "memberof", []), + directmemberof=getattr(group, "directmemberof", []), + spn=getattr(group, "spn", None), + description=getattr(group, "description", None), + ) + for group in groups + ] diff --git a/selfprivacy_api/graphql/queries/groups.py b/selfprivacy_api/graphql/queries/groups.py new file mode 100644 index 0000000..1d63e58 --- /dev/null +++ b/selfprivacy_api/graphql/queries/groups.py @@ -0,0 +1,23 @@ +"""Groups""" + +# pylint: disable=too-few-public-methods +import typing +import strawberry + +from selfprivacy_api.graphql.common_types.groups import ( + Group, + get_groups, +) +from selfprivacy_api.graphql import IsAuthenticated +from selfprivacy_api.actions.users import get_groups as action_get_groups + + +@strawberry.type +class Groups: + all_groups: typing.List[Group] = strawberry.field( + permission_classes=[IsAuthenticated], resolver=get_groups + ) + + @strawberry.field(permission_classes=[IsAuthenticated]) + def get_groups() -> list: + return action_get_groups() diff --git a/selfprivacy_api/graphql/queries/users.py b/selfprivacy_api/graphql/queries/users.py index 5b1f2cb..afa1868 100644 --- a/selfprivacy_api/graphql/queries/users.py +++ b/selfprivacy_api/graphql/queries/users.py @@ -11,7 +11,6 @@ from selfprivacy_api.graphql.common_types.user import ( ) from selfprivacy_api.graphql import IsAuthenticated from selfprivacy_api.repositories.users.exceptions import UserNotFound -from selfprivacy_api.actions.users import groups_list as action_groups_list @strawberry.type @@ -28,7 +27,3 @@ class Users: all_users: typing.List[User] = strawberry.field( permission_classes=[IsAuthenticated], resolver=get_users ) - - @strawberry.field(permission_classes=[IsAuthenticated]) - def groups_list() -> list: - return action_groups_list() diff --git a/selfprivacy_api/models/group.py b/selfprivacy_api/models/group.py new file mode 100644 index 0000000..3775b4c --- /dev/null +++ b/selfprivacy_api/models/group.py @@ -0,0 +1,13 @@ +from typing import Optional + +from pydantic import BaseModel + + +class Group(BaseModel): + name: str + group_class: Optional[list[str]] = [] + member: Optional[list[str]] = [] + memberof: Optional[list[str]] = [] + directmemberof: Optional[list[str]] = [] + spn: Optional[str] = None + description: Optional[str] = None diff --git a/selfprivacy_api/repositories/users/kanidm_user_repository.py b/selfprivacy_api/repositories/users/kanidm_user_repository.py index 2286366..19369f6 100644 --- a/selfprivacy_api/repositories/users/kanidm_user_repository.py +++ b/selfprivacy_api/repositories/users/kanidm_user_repository.py @@ -4,6 +4,7 @@ import requests import re import logging +from selfprivacy_api.models.group import Group from selfprivacy_api.repositories.users.exceptions import ( NoPasswordResetLinkFoundInResponse, UserAlreadyExists, @@ -484,14 +485,28 @@ class KanidmUserRepository(AbstractUserRepository): raise NoPasswordResetLinkFoundInResponse @staticmethod - def groups_list() -> list: + def get_groups() -> list[Group]: groups_list_data = KanidmUserRepository._send_query( endpoint="/v1/group", method="GET", ) KanidmUserRepository._check_response_type_and_not_empty( - data_type="list", response_data=groups_list_data + data_type="dict", response_data=groups_list_data ) - return groups_list_data # type: ignore + groups = [] + for group_data in groups_list_data: + attrs = group_data.get("attrs", {}) + group = Group( + name=attrs["name"], + group_class=attrs.get("class", []), + member=attrs.get("member", []), + memberof=attrs.get("memberof", []), + directmemberof=attrs.get("directmemberof", []), + spn=attrs.get("spn", [None])[0], + description=attrs.get("description", [None])[0], + ) + groups.append(group) + + return groups