diff --git a/jasmin_services/api/serializers.py b/jasmin_services/api/serializers.py index 92495dc..9203442 100644 --- a/jasmin_services/api/serializers.py +++ b/jasmin_services/api/serializers.py @@ -1,5 +1,7 @@ """Serializers for the jasmin_services api.""" +import logging + import django.contrib.auth import django_countries.serializers import rest_framework.serializers as rf_serial @@ -7,6 +9,8 @@ from .. import models +logger = logging.getLogger() + class ServiceUserSerializer(rf_serial.HyperlinkedModelSerializer): """Basic UserSerializer to provide a link to the full one.""" @@ -27,24 +31,59 @@ class Meta: fields = ["id", "user"] +class LdapGroupSerializer(rf_serial.Serializer): + cn = rf_serial.CharField(source="name") + dn = rf_serial.SerializerMethodField() + gidNumber = rf_serial.IntegerField() + + @staticmethod + def get_dn(obj) -> str: + """Build the dn from the name and the base.""" + return f"cn={obj.name},{obj.base_dn}" + + class RoleListSerializer(rf_serial.ModelSerializer): """Basic list of roles.""" user_count = rf_serial.IntegerField(read_only=True) + ldap_groups = rf_serial.SerializerMethodField(read_only=True) class Meta: model = models.Role - fields = ["id", "name", "user_count"] + fields = ["id", "name", "user_count", "ldap_groups"] + + @staticmethod + def _to_group(obj): + """Convert behaviours to LDAP Group Objects.""" + if isinstance(obj, models.behaviours.LdapGroupBehaviour): + try: + group = obj.get_ldap_group() + except django.core.exceptions.ObjectDoesNotExist: + logger.error( + "A LDAP group behaviour exists for %s : %s, but it does not exist in LDAP.", + obj.ldap_model, + obj.group_name, + ) + else: + return group + return None + + def get_ldap_groups(self, obj) -> LdapGroupSerializer(many=True): + """Return a list of LDAP groups for the role.""" + groups = [ + group for behaviour in obj.behaviours.all() if (group := self._to_group(behaviour)) + ] + return LdapGroupSerializer(groups, many=True).data -class RoleSerializer(rf_serial.ModelSerializer): +class RoleSerializer(RoleListSerializer): """Detail of role with holders.""" accesses = AccessSerializer(many=True) class Meta: model = models.Role - fields = ["id", "name", "accesses"] + fields = ["id", "name", "accesses", "user_count", "ldap_groups"] class CategoryListSerializer(rf_serial.HyperlinkedModelSerializer): diff --git a/jasmin_services/tests/test_api.py b/jasmin_services/tests/test_api.py index 3f30af7..cd7aa77 100644 --- a/jasmin_services/tests/test_api.py +++ b/jasmin_services/tests/test_api.py @@ -148,7 +148,7 @@ def test_services_detail(self): "url": "http://testserver/api/v1/categories/test_cat1/", "name": "test_cat1", }, - "roles": [{"id": 1, "name": "MANAGER"}], + "roles": [{"id": 1, "name": "MANAGER", "ldap_groups": []}], "summary": "First test category", "description": "This should be a long description.", "approver_message": "", @@ -184,7 +184,7 @@ def test_user(self): "summary": "First test category", "hidden": True, }, - "role": {"id": 1, "name": "MANAGER"}, + "role": {"id": 1, "name": "MANAGER", "ldap_groups": []}, "granted_at": self.manager_grant.granted_at.astimezone(DJANGO_TZ).strftime( f"%Y-%m-%dT%H:%M:%S.%f{utc_offset}" ), @@ -207,7 +207,7 @@ def test_user(self): "summary": "Another test category", "hidden": True, }, - "role": {"id": 2, "name": "DEPUTY"}, + "role": {"id": 2, "name": "DEPUTY", "ldap_groups": []}, "granted_at": self.deputy_grant.granted_at.astimezone(DJANGO_TZ).strftime( f"%Y-%m-%dT%H:%M:%S.%f{utc_offset}" ), @@ -242,7 +242,7 @@ def test_grants_filter_category(self): "summary": "First test category", "hidden": True, }, - "role": {"id": 1, "name": "MANAGER"}, + "role": {"id": 1, "name": "MANAGER", "ldap_groups": []}, "granted_at": self.manager_grant.granted_at.astimezone(DJANGO_TZ).strftime( f"%Y-%m-%dT%H:%M:%S.%f{utc_offset}" ), @@ -277,7 +277,7 @@ def test_grants_filter_service(self): "summary": "Another test category", "hidden": True, }, - "role": {"id": 2, "name": "DEPUTY"}, + "role": {"id": 2, "name": "DEPUTY", "ldap_groups": []}, "granted_at": self.deputy_grant.granted_at.astimezone(DJANGO_TZ).strftime( f"%Y-%m-%dT%H:%M:%S.%f{utc_offset}" ), @@ -312,7 +312,7 @@ def test_grants_filter_role(self): "summary": "First test category", "hidden": True, }, - "role": {"id": 1, "name": "MANAGER"}, + "role": {"id": 1, "name": "MANAGER", "ldap_groups": []}, "granted_at": self.manager_grant.granted_at.astimezone(DJANGO_TZ).strftime( f"%Y-%m-%dT%H:%M:%S.%f{utc_offset}" ), @@ -415,7 +415,7 @@ def test_category_services_detail(self): "url": "http://testserver/api/v1/categories/test_cat1/", "name": "test_cat1", }, - "roles": [{"id": 1, "name": "MANAGER"}], + "roles": [{"id": 1, "name": "MANAGER", "ldap_groups": []}], "summary": "First test category", "description": "This should be a long description.", "approver_message": "", @@ -440,6 +440,7 @@ def test_service_roles_by_id(self): { "id": 1, "name": "MANAGER", + "ldap_groups": [], "accesses": [ { "id": 1, @@ -467,6 +468,7 @@ def test_service_roles_by_category_and_name(self): { "id": 1, "name": "MANAGER", + "ldap_groups": [], "accesses": [ { "id": 1, @@ -544,7 +546,7 @@ def test_grants_list(self): "summary": "First test category", "hidden": True, }, - "role": {"id": 1, "name": "MANAGER"}, + "role": {"id": 1, "name": "MANAGER", "ldap_groups": []}, "user": { "id": self.user.id, "url": "http://testserver/api/v1/users/testuser/", @@ -573,7 +575,7 @@ def test_grants_list(self): "summary": "Another test category", "hidden": True, }, - "role": {"id": 2, "name": "DEPUTY"}, + "role": {"id": 2, "name": "DEPUTY", "ldap_groups": []}, "user": { "id": self.user.id, "url": "http://testserver/api/v1/users/testuser/", @@ -616,7 +618,7 @@ def test_category_grants_list(self): "summary": "First test category", "hidden": True, }, - "role": {"id": 1, "name": "MANAGER"}, + "role": {"id": 1, "name": "MANAGER", "ldap_groups": []}, "user": { "id": self.user.id, "url": "http://testserver/api/v1/users/testuser/", @@ -657,7 +659,7 @@ def test_category_grants_list_different_category(self): "summary": "Another test category", "hidden": True, }, - "role": {"id": 2, "name": "DEPUTY"}, + "role": {"id": 2, "name": "DEPUTY", "ldap_groups": []}, "user": { "id": self.user.id, "url": "http://testserver/api/v1/users/testuser/",