From 85c790728f6d2ffa7d2ce51ebb3c0fede39377f5 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 9 Nov 2022 11:19:40 +0100 Subject: [PATCH] core: simplify group serializer for user API endpoint (#3899) * core/api: Adding simple group serializer to improve user retrieval performance Due to the exhaustive use of the user_obj the performance suffers greatly if the users are assigned to large groups. This simple fix adds a new serializer that does not expose the user_obj within a group. * core/api: Update schema Update to the schema based on the new SimpleGroupSerializer * core/api: Fix black and pylint * make naming consistent, remove unnecessary fields Signed-off-by: Jens Langhammer Signed-off-by: Jens Langhammer Co-authored-by: Jens Langhammer --- authentik/core/api/users.py | 23 ++++++++++++++-- schema.yml | 55 ++++++++++++++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/authentik/core/api/users.py b/authentik/core/api/users.py index 475c9666c..a46706b41 100644 --- a/authentik/core/api/users.py +++ b/authentik/core/api/users.py @@ -46,7 +46,6 @@ from structlog.stdlib import get_logger from authentik.admin.api.metrics import CoordinateSerializer from authentik.api.decorators import permission_required -from authentik.core.api.groups import GroupSerializer from authentik.core.api.used_by import UsedByMixin from authentik.core.api.utils import LinkSerializer, PassiveSerializer, is_dict from authentik.core.middleware import ( @@ -74,6 +73,26 @@ from authentik.tenants.models import Tenant LOGGER = get_logger() +class UserGroupSerializer(ModelSerializer): + """Simplified Group Serializer for user's groups""" + + attributes = JSONField(required=False) + parent_name = CharField(source="parent.name", read_only=True) + + class Meta: + + model = Group + fields = [ + "pk", + "num_pk", + "name", + "is_superuser", + "parent", + "parent_name", + "attributes", + ] + + class UserSerializer(ModelSerializer): """User Serializer""" @@ -83,7 +102,7 @@ class UserSerializer(ModelSerializer): groups = PrimaryKeyRelatedField( allow_empty=True, many=True, source="ak_groups", queryset=Group.objects.all() ) - groups_obj = ListSerializer(child=GroupSerializer(), read_only=True, source="ak_groups") + groups_obj = ListSerializer(child=UserGroupSerializer(), read_only=True, source="ak_groups") uid = CharField(read_only=True) username = CharField(max_length=150) diff --git a/schema.yml b/schema.yml index c9f0a1b06..68392fe92 100644 --- a/schema.yml +++ b/schema.yml @@ -37477,7 +37477,7 @@ components: groups_obj: type: array items: - $ref: '#/components/schemas/Group' + $ref: '#/components/schemas/UserGroup' readOnly: true email: type: string @@ -37579,6 +37579,59 @@ components: - username - upn type: string + UserGroup: + type: object + description: Simplified Group Serializer for user's groups + properties: + pk: + type: string + format: uuid + readOnly: true + title: Group uuid + num_pk: + type: integer + readOnly: true + name: + type: string + maxLength: 80 + is_superuser: + type: boolean + description: Users added to this group will be superusers. + parent: + type: string + format: uuid + nullable: true + parent_name: + type: string + readOnly: true + attributes: + type: object + additionalProperties: {} + required: + - name + - num_pk + - parent_name + - pk + UserGroupRequest: + type: object + description: Simplified Group Serializer for user's groups + properties: + name: + type: string + minLength: 1 + maxLength: 80 + is_superuser: + type: boolean + description: Users added to this group will be superusers. + parent: + type: string + format: uuid + nullable: true + attributes: + type: object + additionalProperties: {} + required: + - name UserLoginStage: type: object description: UserLoginStage Serializer