You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by ma...@apache.org on 2021/07/01 14:12:13 UTC

[airavata-django-portal] branch AIRAVATA-3319-handle-missing-name-and-email-attributes-from-cilo updated: AIRAVATA-3319 Admin API for updating a user's username

This is an automated email from the ASF dual-hosted git repository.

machristie pushed a commit to branch AIRAVATA-3319-handle-missing-name-and-email-attributes-from-cilo
in repository https://gitbox.apache.org/repos/asf/airavata-django-portal.git


The following commit(s) were added to refs/heads/AIRAVATA-3319-handle-missing-name-and-email-attributes-from-cilo by this push:
     new 26a192d  AIRAVATA-3319 Admin API for updating a user's username
26a192d is described below

commit 26a192de4f73f1a4c56f5cc1ce48c49d7983277f
Author: Marcus Christie <ma...@apache.org>
AuthorDate: Thu Jul 1 10:11:54 2021 -0400

    AIRAVATA-3319 Admin API for updating a user's username
---
 django_airavata/apps/api/views.py             | 12 ++++++++++
 django_airavata/apps/auth/iam_admin_client.py | 34 +++++++++++++++++++++++++++
 2 files changed, 46 insertions(+)

diff --git a/django_airavata/apps/api/views.py b/django_airavata/apps/api/views.py
index dcfb209..769473c 100644
--- a/django_airavata/apps/api/views.py
+++ b/django_airavata/apps/api/views.py
@@ -1773,6 +1773,18 @@ class IAMUserViewSet(mixins.RetrieveModelMixin,
                                            context={'request': request})
         return Response(serializer.data)
 
+    @action(methods=['put'], detail=True)
+    def update_username(self, request, user_id=None):
+        serializer = self.get_serializer(data=request.data)
+        serializer.is_valid(raise_exception=True)
+        old_username = user_id
+        new_username = serializer.validated_data['userId']
+        iam_admin_client.update_username(old_username, new_username)
+        instance = self.get_instance(new_username)
+        serializer = self.serializer_class(instance=instance,
+                                           context={'request': request})
+        return Response(serializer.data)
+
     def _convert_user_profile(self, user_profile):
         user_profile_client = self.request.profile_service['user_profile']
         group_manager_client = self.request.profile_service['group_manager']
diff --git a/django_airavata/apps/auth/iam_admin_client.py b/django_airavata/apps/auth/iam_admin_client.py
index 113d2a8..3d2b29f 100644
--- a/django_airavata/apps/auth/iam_admin_client.py
+++ b/django_airavata/apps/auth/iam_admin_client.py
@@ -3,6 +3,10 @@ Wrapper around the IAM Admin Services client.
 """
 
 import logging
+from urllib.parse import urlparse
+
+import requests
+from django.conf import settings
 
 from django_airavata.utils import iamadmin_client_pool
 
@@ -61,3 +65,33 @@ def reset_user_password(username, new_password):
     authz_token = utils.get_service_account_authz_token()
     return iamadmin_client_pool.resetUserPassword(
         authz_token, username, new_password)
+
+
+def update_username(username, new_username):
+    # make sure that new_username is available
+    if not is_username_available(new_username):
+        raise Exception(f"Can't change username of {username} to {new_username} because it is not available")
+    # fetch user representation
+    authz_token = utils.get_service_account_authz_token()
+    headers = {'Authorization': f'Bearer {authz_token.accessToken}'}
+    parsed = urlparse(settings.KEYCLOAK_AUTHORIZE_URL)
+    r = requests.get(f"{parsed.scheme}://{parsed.netloc}/auth/admin/realms/{settings.GATEWAY_ID}/users",
+                     params={'username': username},
+                     headers=headers)
+    r.raise_for_status()
+    user_list = r.json()
+    user = None
+    # The users search finds partial matches. Loop to find the exact match.
+    for u in user_list:
+        if u['username'] == username:
+            user = u
+            break
+    if user is None:
+        raise Exception(f"Could not find user {username}")
+
+    # update username
+    user['username'] = new_username
+    r = requests.put(f"{parsed.scheme}://{parsed.netloc}/auth/admin/realms/{settings.GATEWAY_ID}/users/{user['id']}",
+                     json=user,
+                     headers=headers)
+    r.raise_for_status()