From 533817849a85f69f7e22343d63c22f4b8443083c Mon Sep 17 00:00:00 2001 From: Jorrit Schaap <schaap@astron.nl> Date: Thu, 24 Mar 2022 13:29:15 +0100 Subject: [PATCH] TMSS-1628: Implemented a reverse lookup from unique-email to multiple-persons-with-that-email, and pick the 'best' user display name from that. Show the list of best names in the api --- .../src/tmss/tmssapp/adapters/keycloak.py | 36 +++++++++++++++++++ .../tmss/tmssapp/viewsets/specification.py | 4 +-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/adapters/keycloak.py b/SAS/TMSS/backend/src/tmss/tmssapp/adapters/keycloak.py index 00641dc862f..e162fd5632a 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/adapters/keycloak.py +++ b/SAS/TMSS/backend/src/tmss/tmssapp/adapters/keycloak.py @@ -131,3 +131,39 @@ def get_user_mapping(): user_map['%s, %s' % (user['lastName'], user['firstName'])] = user['email'] return user_map + + +@cachetools.func.ttl_cache(ttl=600) +def get_email_to_name_mapping(): + # first create a reverse map of unique-email to multiple-usernames-for-the-same-person + reverse_users_map = {} + for name, email in get_user_mapping().items(): + if email not in reverse_users_map: + reverse_users_map[email] = [] + reverse_users_map[email].append(name) + email_to_name_map = {} + for email, names in reverse_users_map.items(): + if len(names) == 1: + # just one username for this unique email address, so use it + email_to_name_map[email] = names[0] + elif len(names) > 1: + # multiple usernames for this unique email address, so determine the 'best' one + # filter out the 'ugly' local ldap name + names2 = [n for n in names if 'cn=' not in n] + if names2: + # pick the first not 'ugly' local ldap name + email_to_name_map[email] = names2[0] + else: + # just pick the first, we have to choose something + email_to_name_map[email] = names[0] + return email_to_name_map + + +def get_names_by_role_in_project(role, project): + """ + returns the list of user display names that have the specified role in the specified project + """ + emails = get_users_by_role_in_project(role, project) + map = get_email_to_name_mapping() + return [map.get(email, email) for email in emails] + diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/specification.py b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/specification.py index 6e074f536e3..b288ccf0013 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/specification.py +++ b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/specification.py @@ -29,7 +29,7 @@ from lofar.sas.tmss.tmss.tmssapp.viewsets.lofar_viewset import LOFARViewSet, LOF from lofar.sas.tmss.tmss.tmssapp import models from lofar.sas.tmss.tmss.tmssapp import serializers from lofar.sas.tmss.tmss.tmssapp.adapters.reports import create_cycle_report, create_project_report -from lofar.sas.tmss.tmss.tmssapp.adapters.keycloak import get_users_by_role_in_project +from lofar.sas.tmss.tmss.tmssapp.adapters.keycloak import get_names_by_role_in_project from django.http import JsonResponse from datetime import datetime @@ -484,7 +484,7 @@ class ProjectViewSet(LOFARViewSet): @action(methods=['get'], detail=True, url_name="friend", name="Friend(s) of this project") def friend(self, request, pk=None): project = get_object_or_404(models.Project, pk=pk) - result = get_users_by_role_in_project(models.ProjectRole.Choices.FRIEND_OF_PROJECT.value, project.name) + result = get_names_by_role_in_project(models.ProjectRole.Choices.FRIEND_OF_PROJECT.value, project.name) return Response(result, status=status.HTTP_200_OK) @swagger_auto_schema(responses={200: 'List of roles that the requesting user has in this project', -- GitLab