Files
RasadDam_Backend/apps/authorization/api/v1/serializers.py

188 lines
5.8 KiB
Python
Raw Normal View History

import typing
2025-10-25 12:09:00 +03:30
from collections import defaultdict
2025-10-25 12:09:00 +03:30
from django.db.models.query import QuerySet
from rest_framework import serializers
2025-10-25 12:09:00 +03:30
from apps.authentication.api.v1.serializers import serializer as auth_serializer
from apps.authorization.models import (
Role,
Permissions,
UserRelations,
Page
)
class PageSerializer(serializers.ModelSerializer):
2025-06-02 15:26:49 +03:30
""" Serialize every front-end page """
class Meta:
model = Page
fields = [
'id',
'name',
'code',
'is_active'
]
def to_representation(self, instance):
""" custom output of serializer """
representation = super().to_representation(instance)
representation['permissions'] = PermissionSerializer(
Permissions.objects.filter(page=instance),
many=True
).data
return representation
class PermissionSerializer(serializers.ModelSerializer):
2025-06-02 15:26:49 +03:30
""" Serialize permissions """
class Meta:
model = Permissions
fields = [
'id',
'name',
'description',
'category',
'page',
2025-11-03 12:54:08 +03:30
'is_active',
'modify_state'
]
def to_representation(self, instance):
representation = super().to_representation(instance)
2025-06-02 15:26:49 +03:30
representation['page'] = instance.page.name
return representation
@classmethod
2025-10-25 12:09:00 +03:30
def permissions_structure_output(cls, permissions) -> typing.List[dict]:
""" set a structure for permissions """
2025-06-08 14:36:57 +03:30
2025-10-25 12:09:00 +03:30
if isinstance(permissions, QuerySet):
permissions = permissions.select_related('page')
grouped = defaultdict(set)
2025-11-03 16:44:35 +03:30
modifier_states = defaultdict(set)
2025-10-25 12:09:00 +03:30
for permission in permissions:
if getattr(permission, 'is_active', True):
2025-10-25 12:09:00 +03:30
page_name = getattr(permission.page, 'name', None)
2025-10-25 12:09:00 +03:30
if page_name:
grouped[page_name].add(permission.name)
grouped[f'modify_state_{page_name}'].add(permission.modify_state)
2025-11-03 16:44:35 +03:30
modifier_states[page_name].add(permission.modify_state)
structure = []
for page, access in grouped.items():
if page.startswith('modify_state_'):
continue
modify_states = grouped.get(f'modify_state_{page}', set())
2025-11-03 16:44:35 +03:30
if False not in modify_states:
continue
structure.append({
2025-11-03 16:50:16 +03:30
'page_name': page,
'page_access': sorted(list(access)),
})
return structure
class RoleSerializer(serializers.ModelSerializer):
2025-06-02 15:26:49 +03:30
""" Serialize roles of user """
class Meta:
model = Role
fields = [
'id',
'role_name',
2025-10-28 09:09:06 +03:30
'parent_role',
'description',
'type',
2025-10-25 15:35:38 +03:30
'permissions' # noqa
]
extra_kwargs = {
2025-10-25 15:35:38 +03:30
'permissions': {'required': False} # permissions not required for some roles # noqa
}
def to_representation(self, instance):
"""
using @to_representation for many_to_many permissions in response
"""
representation = super().to_representation(instance)
representation['type'] = auth_serializer.OrganizationTypeSerializer(instance.type).data
2025-11-08 10:42:20 +03:30
representation['permissions'] = PermissionSerializer(instance.permissions, many=True).data
2025-10-28 09:15:39 +03:30
if instance.parent_role:
representation['parent_role'] = {'name': instance.parent_role.role_name, 'id': instance.parent_role.id}
return representation
class UserRelationSerializer(serializers.ModelSerializer):
2025-06-02 15:26:49 +03:30
""" Serialize relations of user like: organizations, roles, permissions """
class Meta:
model = UserRelations
fields = [
'id',
'user',
'organization',
'role',
2025-10-25 15:35:38 +03:30
'permissions', # noqa
]
2025-06-09 16:17:06 +03:30
extra_kwargs = {
'organization': {
'required': False
},
2025-10-25 15:35:38 +03:30
'permissions': { # noqa
2025-06-09 16:17:06 +03:30
'required': False
},
'role': {
'required': False
}
2025-06-09 16:09:50 +03:30
}
def to_representation(self, instance):
""" custom output for serializer """
representation = super().to_representation(instance)
if isinstance(instance, UserRelations):
if instance.user:
representation['user'] = auth_serializer.UserSerializer(instance.user).data
if instance.organization:
2025-11-09 10:10:22 +03:30
representation['organization'] = {"id": instance.organization.id, "name": instance.organization.name}
if instance.role:
2025-11-10 11:31:27 +03:30
representation['role'] = {
"id": instance.role.id, "role_name": instance.role.role_name, 'type': {
'key': instance.role.type.key
}
}
if instance.permissions: # noqa
# set permissions by a default structure like:
# 'page permission':[element permissions]
permissions = instance.permissions.filter(is_active=True)
2025-10-25 12:09:00 +03:30
representation['permissions'] = PermissionSerializer.permissions_structure_output(
list(permissions) + list(instance.role.permissions.all())
2025-08-07 13:16:10 +03:30
)
return representation
def update(self, instance, validated_data):
""" update user relation object """
2025-08-07 13:16:10 +03:30
instance.role = validated_data.get('role', instance.role)
instance.organization = validated_data.get('organization', instance.organization)
instance.save()
if validated_data.get('permissions'):
instance.permissions.clear()
instance.permissions.add(*(validated_data.get('permissions', instance.permissions)))
return instance