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

yasithdev pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airavata-portals.git


The following commit(s) were added to refs/heads/main by this push:
     new 64b157fa1 refactor(portal): make group + user-profile + sharing 
serializers proto-native (Track D, D5) (#204)
64b157fa1 is described below

commit 64b157fa11ec603a748452e1f2409e3f443e7940
Author: Yasith Jayawardana <[email protected]>
AuthorDate: Tue Jun 9 04:59:06 2026 -0400

    refactor(portal): make group + user-profile + sharing serializers 
proto-native (Track D, D5) (#204)
    
    Rewrite GroupSerializer and UserProfileSerializer to read the gRPC 
GroupModel /
    UserProfile protobuf directly, and repoint the entity-sharing + IAM 
consumers.
    
    - GroupSerializer: proto-native read + write; the update diff lists the view
      needs (added/removed members/admins) are stashed on the serializer 
instance
      (a proto message can't carry the old Thrift `_added_*` attrs). 
GroupViewSet
      reads them from the serializer.
    - UserProfileSerializer: preserves the Thrift quirks byte-for-byte — `State`
      (capitalised, Thrift int), `orginationAffiliation` (the misspelling), and
      `labeledURI` (a Thrift list field fed the proto string, so the old 
ListField
      iterated it character by character); nsfDemographics/customDashboard 
render null.
    - Repoint UserProfileViewSet, SharedEntityViewSet 
(_load_user_profile/_load_group
      + the update diff that reads proto names and builds proto 
UserProfile/GroupModel),
      IAMUserViewSet._convert_user_profile / 
_get_unverified_email_user_profiles (read
      proto fields + proto Status), and the group write path to pass protobuf 
through.
    - Remove grpc_adapters.group / user_profile + grpc_requests.group and the
      now-unused Thrift GroupModel/UserProfile/Status imports.
    
    Validated byte-for-byte (group incl. method flags, user profile incl. the
    labeledURI char-split + State int) vs the old adapter+serializer path; 
group write
    produces an equivalent proto. manage.py check green; api test failures 
unchanged.
---
 .../django_airavata/apps/api/grpc_adapters.py      |  50 ------
 .../django_airavata/apps/api/grpc_requests.py      |  12 --
 .../django_airavata/apps/api/serializers.py        | 167 ++++++++++++++++-----
 .../django_airavata/apps/api/views.py              | 121 +++++++--------
 4 files changed, 186 insertions(+), 164 deletions(-)

diff --git a/airavata-django-portal/django_airavata/apps/api/grpc_adapters.py 
b/airavata-django-portal/django_airavata/apps/api/grpc_adapters.py
index 829a76c98..ec7b3746f 100644
--- a/airavata-django-portal/django_airavata/apps/api/grpc_adapters.py
+++ b/airavata-django-portal/django_airavata/apps/api/grpc_adapters.py
@@ -88,56 +88,6 @@ _JOB_SUBMISSION_PROTOCOL = {
     'LOCAL_FORK': _ThriftJobSubmissionProtocol.LOCAL_FORK,
 }
 
-def group(pb):
-    """gRPC ``GroupModel`` -> ``GroupSerializer`` shape."""
-    return SimpleNamespace(
-        id=pb.id,
-        name=pb.name,
-        ownerId=pb.owner_id,
-        description=pb.description or None,
-        members=list(pb.members),
-        admins=list(pb.admins),
-    )
-
-
-def user_profile(pb):
-    """gRPC ``UserProfile`` -> ``UserProfileSerializer`` shape.
-
-    Note the Thrift attribute quirks the serializer expects: ``State`` 
(capital),
-    ``orginationAffiliation`` (Thrift's spelling), ``labeledURI``. The nested
-    ``nsfDemographics``/``customDashboard`` structs are not surfaced in the
-    sharing UI, so they render null.
-    """
-    return SimpleNamespace(
-        userModelVersion=pb.user_model_version or None,
-        airavataInternalUserId=pb.airavata_internal_user_id,
-        userId=pb.user_id,
-        gatewayId=pb.gateway_id,
-        emails=list(pb.emails),
-        firstName=pb.first_name or None,
-        lastName=pb.last_name or None,
-        middleName=pb.middle_name or None,
-        namePrefix=pb.name_prefix or None,
-        nameSuffix=pb.name_suffix or None,
-        orcidId=pb.orcid_id or None,
-        phones=list(pb.phones),
-        country=pb.country or None,
-        nationality=list(pb.nationality),
-        homeOrganization=pb.home_organization or None,
-        orginationAffiliation=pb.origination_affiliation or None,
-        creationTime=pb.creation_time or None,
-        lastAccessTime=pb.last_access_time or None,
-        validUntil=pb.valid_until or None,
-        State=_thrift_enum_prefixed(pb, 'state', _ThriftStatus, 'STATUS_'),
-        comments=pb.comments or None,
-        labeledURI=pb.labeled_uri or None,
-        gpgKey=pb.gpg_key or None,
-        timeZone=pb.time_zone or None,
-        nsfDemographics=None,
-        customDashboard=None,
-    )
-
-
 # --- User storage file/directory listings -----------------------------------
 # The storage serializers (UserStorageFileSerializer / 
UserStorageDirectorySerializer)
 # read plain dicts keyed the way the legacy user_storage.listdir produced. The 
gRPC
diff --git a/airavata-django-portal/django_airavata/apps/api/grpc_requests.py 
b/airavata-django-portal/django_airavata/apps/api/grpc_requests.py
index cf040d581..0411a667f 100644
--- a/airavata-django-portal/django_airavata/apps/api/grpc_requests.py
+++ b/airavata-django-portal/django_airavata/apps/api/grpc_requests.py
@@ -223,18 +223,6 @@ def group_resource_profile(t):
     )
 
 
-def group(t):
-    """Thrift ``GroupModel`` -> proto ``GroupModel`` request message."""
-    return _pb2("group.group_manager_pb2").GroupModel(
-        id=t.id or '',
-        name=t.name or '',
-        owner_id=t.ownerId or '',
-        description=t.description or '',
-        members=list(t.members or []),
-        admins=list(t.admins or []),
-    )
-
-
 def data_product_for_upload(*, gateway_id, owner_name, product_name, file_path,
                             storage_resource_id, content_type=None, 
product_size=0):
     """Build a proto ``DataProductModel`` to register for a freshly uploaded 
file.
diff --git a/airavata-django-portal/django_airavata/apps/api/serializers.py 
b/airavata-django-portal/django_airavata/apps/api/serializers.py
index 1ad7103f5..f609d1308 100644
--- a/airavata-django-portal/django_airavata/apps/api/serializers.py
+++ b/airavata-django-portal/django_airavata/apps/api/serializers.py
@@ -15,11 +15,10 @@ from airavata.model.appcatalog.groupresourceprofile.ttypes 
import (
     AwsComputeResourcePreference
 )
 from airavata.model.appcatalog.parser.ttypes import IOType as _ThriftIOType
-from airavata.model.group.ttypes import GroupModel, ResourcePermissionType
+from airavata.model.group.ttypes import ResourcePermissionType
 from airavata.model.status.ttypes import (
     ExperimentState
 )
-from airavata.model.user.ttypes import UserProfile
 from airavata_django_portal_sdk import (
     experiment_util
 )
@@ -407,7 +406,30 @@ class OrderedListField(serializers.ListField):
         return validated_data
 
 
-class GroupSerializer(thrift_utils.create_serializer_class(GroupModel)):
+def _group_manager_pb2():
+    from airavata_sdk.generated.org.apache.airavata.model.group import (
+        group_manager_pb2,
+    )
+    return group_manager_pb2
+
+
+class GroupSerializer(serializers.Serializer):
+    """Proto-native serializer for the gRPC ``GroupModel`` message.
+
+    On update the added/removed member/admin diffs the view needs are stashed 
on
+    the serializer instance (``self.added_members`` etc.) — a protobuf message
+    can't carry arbitrary attributes the way the old Thrift instance did.
+    """
+
+    id = serializers.CharField(read_only=True)
+    name = serializers.CharField()
+    ownerId = serializers.CharField(source='owner_id', read_only=True)
+    description = serializers.CharField(
+        allow_blank=True, allow_null=True, required=False)
+    members = serializers.ListField(
+        child=serializers.CharField(), required=False)
+    admins = serializers.ListField(
+        child=serializers.CharField(), required=False)
     url = FullyEncodedHyperlinkedIdentityField(
         view_name='django_airavata_api:group-detail',
         lookup_field='id',
@@ -419,39 +441,43 @@ class 
GroupSerializer(thrift_utils.create_serializer_class(GroupModel)):
     isReadOnlyGatewayAdminsGroup = serializers.SerializerMethodField()
     isDefaultGatewayUsersGroup = serializers.SerializerMethodField()
 
-    class Meta:
-        required = ('name',)
-        read_only = ('ownerId',)
+    def to_representation(self, instance):
+        ret = super().to_representation(instance)
+        if ret.get('description') == '':
+            ret['description'] = None
+        return ret
 
     def create(self, validated_data):
-        group = super().create(validated_data)
-        group.ownerId = self.context['request'].user.username + \
-            "@" + settings.GATEWAY_ID
-        return group
+        return _group_manager_pb2().GroupModel(
+            name=validated_data.get('name', '') or '',
+            description=validated_data.get('description', '') or '',
+            members=list(validated_data.get('members', []) or []),
+            admins=list(validated_data.get('admins', []) or []),
+            owner_id=(self.context['request'].user.username + "@" +
+                      settings.GATEWAY_ID),
+        )
 
     def update(self, instance, validated_data):
-        instance.name = validated_data.get('name', instance.name)
-        instance.description = validated_data.get(
-            'description', instance.description)
-        # Calculate added and removed members
+        if 'name' in validated_data:
+            instance.name = validated_data['name'] or ''
+        if 'description' in validated_data:
+            instance.description = validated_data['description'] or ''
+        # Calculate added and removed members/admins; stash on the serializer 
for
+        # the view (a proto message can't carry the old Thrift ``_added_*`` 
attrs).
         old_members = set(instance.members)
         new_members = set(validated_data.get('members', instance.members))
-        removed_members = old_members - new_members
-        added_members = new_members - old_members
-        instance._removed_members = list(removed_members)
-        instance._added_members = list(added_members)
-        instance.members = validated_data.get('members', instance.members)
-        # Calculate added and removed admins
+        self.removed_members = list(old_members - new_members)
+        self.added_members = list(new_members - old_members)
+        instance.members[:] = list(validated_data.get('members', 
instance.members))
         old_admins = set(instance.admins)
         new_admins = set(validated_data.get('admins', instance.admins))
-        removed_admins = old_admins - new_admins
-        added_admins = new_admins - old_admins
-        instance._removed_admins = list(removed_admins)
-        instance._added_admins = list(added_admins)
-        instance.admins = validated_data.get('admins', instance.admins)
-        # Add new admins that aren't members to the added_members list
-        instance._added_members.extend(list(added_admins - new_members))
-        instance.members.extend(list(added_admins - new_members))
+        self.removed_admins = list(old_admins - new_admins)
+        self.added_admins = list(new_admins - old_admins)
+        instance.admins[:] = list(validated_data.get('admins', 
instance.admins))
+        # Add new admins that aren't members to the added_members list.
+        extra = list(new_admins - new_members)
+        self.added_members.extend(extra)
+        instance.members.extend(extra)
         return instance
 
     def get_isAdmin(self, group):
@@ -462,9 +488,9 @@ class 
GroupSerializer(thrift_utils.create_serializer_class(GroupModel)):
 
     def get_isOwner(self, group):
         request = self.context['request']
-        return group.ownerId == (request.user.username +
-                                 "@" +
-                                 settings.GATEWAY_ID)
+        return group.owner_id == (request.user.username +
+                                  "@" +
+                                  settings.GATEWAY_ID)
 
     def get_isMember(self, group):
         request = self.context['request']
@@ -1916,10 +1942,73 @@ class 
ExperimentSummarySerializer(BaseExperimentSummarySerializer):
             self.context['request'], experiment.experiment_id)
 
 
-class UserProfileSerializer(
-        thrift_utils.create_serializer_class(UserProfile)):
-    creationTime = UTCPosixTimestampDateTimeField()
-    lastAccessTime = UTCPosixTimestampDateTimeField()
+def _user_profile_pb2():
+    from airavata_sdk.generated.org.apache.airavata.model.user import (
+        user_profile_pb2,
+    )
+    return user_profile_pb2
+
+
+def _user_status_field(**kwargs):
+    from airavata.model.user.ttypes import Status as _T
+    return proto_enum_int_field(
+        _user_profile_pb2().Status.DESCRIPTOR, _T, proto_prefix='STATUS_',
+        **kwargs)
+
+
+class UserProfileSerializer(serializers.Serializer):
+    """Proto-native serializer for the gRPC ``UserProfile`` message.
+
+    Preserves the Thrift serializer's attribute quirks byte-for-byte: ``State``
+    (capitalised), ``orginationAffiliation`` (the Thrift misspelling), and
+    ``labeledURI`` — a Thrift *list* field fed the proto string, so the old
+    auto-generated ListField iterated it character by character; reproduced 
here.
+    The ``nsfDemographics``/``customDashboard`` structs render null.
+    """
+
+    userModelVersion = serializers.CharField(source='user_model_version', 
allow_blank=True, allow_null=True, required=False)
+    airavataInternalUserId = 
serializers.CharField(source='airavata_internal_user_id', allow_blank=True, 
allow_null=True, required=False)
+    userId = serializers.CharField(source='user_id', allow_blank=True, 
allow_null=True, required=False)
+    gatewayId = serializers.CharField(source='gateway_id', allow_blank=True, 
allow_null=True, required=False)
+    emails = serializers.ListField(child=serializers.CharField(), 
required=False)
+    firstName = serializers.CharField(source='first_name', allow_blank=True, 
allow_null=True, required=False)
+    lastName = serializers.CharField(source='last_name', allow_blank=True, 
allow_null=True, required=False)
+    middleName = serializers.CharField(source='middle_name', allow_blank=True, 
allow_null=True, required=False)
+    namePrefix = serializers.CharField(source='name_prefix', allow_blank=True, 
allow_null=True, required=False)
+    nameSuffix = serializers.CharField(source='name_suffix', allow_blank=True, 
allow_null=True, required=False)
+    orcidId = serializers.CharField(source='orcid_id', allow_blank=True, 
allow_null=True, required=False)
+    phones = serializers.ListField(child=serializers.CharField(), 
required=False)
+    country = serializers.CharField(allow_blank=True, allow_null=True, 
required=False)
+    nationality = serializers.ListField(child=serializers.CharField(), 
required=False)
+    homeOrganization = serializers.CharField(source='home_organization', 
allow_blank=True, allow_null=True, required=False)
+    orginationAffiliation = 
serializers.CharField(source='origination_affiliation', allow_blank=True, 
allow_null=True, required=False)
+    creationTime = ProtoTimestampField(source='creation_time', 
null_if_zero=True)
+    lastAccessTime = ProtoTimestampField(source='last_access_time', 
null_if_zero=True)
+    validUntil = ProtoIntOrNoneField(source='valid_until')
+    State = _user_status_field(source='state', required=False, allow_null=True)
+    comments = serializers.CharField(allow_blank=True, allow_null=True, 
required=False)
+    labeledURI = serializers.ListField(source='labeled_uri', 
child=serializers.CharField(), required=False)
+    gpgKey = serializers.CharField(source='gpg_key', allow_blank=True, 
allow_null=True, required=False)
+    timeZone = serializers.CharField(source='time_zone', allow_blank=True, 
allow_null=True, required=False)
+    nsfDemographics = serializers.SerializerMethodField()
+    customDashboard = serializers.SerializerMethodField()
+
+    def to_representation(self, instance):
+        ret = super().to_representation(instance)
+        # The old adapter mapped optional proto strings to None when empty.
+        for f in ('userModelVersion', 'firstName', 'lastName', 'middleName',
+                  'namePrefix', 'nameSuffix', 'orcidId', 'country',
+                  'homeOrganization', 'orginationAffiliation', 'comments',
+                  'gpgKey', 'timeZone'):
+            if ret.get(f) == '':
+                ret[f] = None
+        return ret
+
+    def get_nsfDemographics(self, instance):
+        return None
+
+    def get_customDashboard(self, instance):
+        return None
 
 
 class ComputeResourceReservationSerializer(
@@ -2850,10 +2939,10 @@ class SharedEntitySerializer(serializers.Serializer):
         # Compute lists of ids to grant/revoke READ/WRITE/MANAGE_SHARING
         # permission
         existing_user_permissions = {
-            user['user'].airavataInternalUserId: user['permissionType']
+            user['user'].airavata_internal_user_id: user['permissionType']
             for user in instance['userPermissions']}
         new_user_permissions = {
-            user['user']['airavataInternalUserId']:
+            user['user']['airavata_internal_user_id']:
                 user['permissionType']
             for user in validated_data['userPermissions']}
 
@@ -2873,6 +2962,8 @@ class SharedEntitySerializer(serializers.Serializer):
         new_group_permissions = {
             group['group']['id']: group['permissionType']
             for group in validated_data['groupPermissions']}
+        UserProfile = _user_profile_pb2().UserProfile
+        GroupModel = _group_manager_pb2().GroupModel
 
         (
             group_grant_read_permission,
@@ -2972,7 +3063,7 @@ class SharedEntitySerializer(serializers.Serializer):
 
     def get_isOwner(self, shared_entity):
         request = self.context['request']
-        return shared_entity['owner'].userId == request.user.username
+        return shared_entity['owner'].user_id == request.user.username
 
     def get_hasSharingPermission(self, shared_entity):
         request = self.context['request']
diff --git a/airavata-django-portal/django_airavata/apps/api/views.py 
b/airavata-django-portal/django_airavata/apps/api/views.py
index 682882a85..4c24a4877 100644
--- a/airavata-django-portal/django_airavata/apps/api/views.py
+++ b/airavata-django-portal/django_airavata/apps/api/views.py
@@ -15,7 +15,6 @@ from airavata.model.appcatalog.groupresourceprofile.ttypes 
import (
     ResourceType
 )
 from airavata.model.group.ttypes import ResourcePermissionType
-from airavata.model.user.ttypes import Status
 from airavata_django_portal_sdk import (
     experiment_util,
     queue_settings_calculators
@@ -129,43 +128,39 @@ class GroupViewSet(APIBackedViewSet):
 
         class GroupResultsIterator(APIResultIterator):
             def get_results(self, limit=-1, offset=0):
-                groups = [
-                    grpc_adapters.group(g)
-                    for g in view.request.airavata.sharing.gm_get_groups()
-                ]
+                groups = list(view.request.airavata.sharing.gm_get_groups())
                 end = offset + limit if limit > 0 else len(groups)
                 return groups[offset:end] if groups else []
 
         return GroupResultsIterator()
 
     def get_instance(self, lookup_value):
-        return grpc_adapters.group(
-            self.request.airavata.sharing.gm_get_group(lookup_value))
+        return self.request.airavata.sharing.gm_get_group(lookup_value)
 
     def perform_create(self, serializer):
         group = serializer.save()
-        group_id = self.request.airavata.sharing.gm_create_group(
-            grpc_requests.group(group))
+        group_id = self.request.airavata.sharing.gm_create_group(group)
         group.id = group_id
-        users_added_to_group = set(group.members) - {group.ownerId}
+        users_added_to_group = set(group.members) - {group.owner_id}
         self._send_users_added_to_group(users_added_to_group, group)
 
     def perform_update(self, serializer):
         group = serializer.save()
         sharing = self.request.airavata.sharing
-        if len(group._added_members) > 0:
-            sharing.gm_add_users_to_group(group._added_members, group.id)
-            self._send_users_added_to_group(group._added_members, group)
-        if len(group._removed_members) > 0:
-            sharing.gm_remove_users_from_group(group._removed_members, 
group.id)
-        if len(group._added_admins) > 0:
-            sharing.gm_add_group_admins(group.id, group._added_admins)
-        if len(group._removed_admins) > 0:
-            sharing.gm_remove_group_admins(group.id, group._removed_admins)
-        sharing.gm_update_group(grpc_requests.group(group))
+        if len(serializer.added_members) > 0:
+            sharing.gm_add_users_to_group(serializer.added_members, group.id)
+            self._send_users_added_to_group(serializer.added_members, group)
+        if len(serializer.removed_members) > 0:
+            sharing.gm_remove_users_from_group(
+                serializer.removed_members, group.id)
+        if len(serializer.added_admins) > 0:
+            sharing.gm_add_group_admins(group.id, serializer.added_admins)
+        if len(serializer.removed_admins) > 0:
+            sharing.gm_remove_group_admins(group.id, serializer.removed_admins)
+        sharing.gm_update_group(group)
 
     def perform_destroy(self, group):
-        self.request.airavata.sharing.gm_delete_group(group.id, group.ownerId)
+        self.request.airavata.sharing.gm_delete_group(group.id, group.owner_id)
 
     def _send_users_added_to_group(self, internal_user_ids, group):
         for internal_user_id in internal_user_ids:
@@ -955,16 +950,12 @@ class UserProfileViewSet(mixins.RetrieveModelMixin,
     serializer_class = serializers.UserProfileSerializer
 
     def get_list(self):
-        return [
-            grpc_adapters.user_profile(p)
-            for p in 
self.request.airavata.iam.get_all_user_profiles_in_gateway(
-                self.gateway_id, 0, -1)
-        ]
+        return list(self.request.airavata.iam.get_all_user_profiles_in_gateway(
+            self.gateway_id, 0, -1))
 
     def get_instance(self, lookup_value):
-        return grpc_adapters.user_profile(
-            self.request.airavata.iam.get_user_profile_by_id(
-                self.request.user.username, self.gateway_id))
+        return self.request.airavata.iam.get_user_profile_by_id(
+            self.request.user.username, self.gateway_id)
 
 
 class GroupResourceProfileViewSet(APIBackedViewSet):
@@ -1223,9 +1214,8 @@ class SharedEntityViewSet(mixins.RetrieveModelMixin,
 
     def _load_user_profile(self, user_id):
         username = user_id[0:user_id.rindex('@')]
-        return grpc_adapters.user_profile(
-            self.request.airavata.iam.get_user_profile_by_id(
-                username, settings.GATEWAY_ID))
+        return self.request.airavata.iam.get_user_profile_by_id(
+            username, settings.GATEWAY_ID)
 
     def _load_accessible_groups(self, entity_id, permission_type):
         groups = self.request.airavata.sharing.get_all_accessible_groups(
@@ -1238,8 +1228,7 @@ class SharedEntityViewSet(mixins.RetrieveModelMixin,
         return {group_id: permission_type for group_id in groups}
 
     def _load_group(self, group_id):
-        return grpc_adapters.group(
-            self.request.airavata.sharing.gm_get_group(group_id))
+        return self.request.airavata.sharing.gm_get_group(group_id)
 
     def perform_update(self, serializer):
         shared_entity = serializer.save()
@@ -1840,7 +1829,7 @@ class IAMUserViewSet(mixins.RetrieveModelMixin,
         user_id = managed_user_profile['airavataInternalUserId']
         added_groups = []
         for group_id in managed_user_profile['_added_group_ids']:
-            group = grpc_adapters.group(sharing.gm_get_group(group_id))
+            group = sharing.gm_get_group(group_id)
             sharing.gm_add_users_to_group([user_id], group_id)
             added_groups.append(group)
         if len(added_groups) > 0:
@@ -1887,31 +1876,31 @@ class IAMUserViewSet(mixins.RetrieveModelMixin,
         return Response(serializer.data)
 
     def _convert_user_profile(self, user_profile):
-        # iam_admin_client returns a protobuf UserProfile; adapt it to the 
Thrift
-        # attribute shape so the field reads and ``State`` comparison below are
-        # unchanged.
-        user_profile = grpc_adapters.user_profile(user_profile)
+        # iam_admin_client returns a protobuf UserProfile; read proto fields
+        # directly and build the dict the IAMUserProfile serializer consumes.
+        from airavata_sdk.generated.org.apache.airavata.model.user import (
+            user_profile_pb2,
+        )
+        Status = user_profile_pb2.Status
         airavata_user_profile_exists = 
self.request.airavata.iam.does_user_exist(
-            user_profile.userId, self.gateway_id)
+            user_profile.user_id, self.gateway_id)
         groups = []
         if airavata_user_profile_exists:
-            groups = [
-                grpc_adapters.group(g)
-                for g in 
self.request.airavata.sharing.gm_get_all_groups_user_belongs(
-                    user_profile.airavataInternalUserId)
-            ]
+            groups = list(
+                self.request.airavata.sharing.gm_get_all_groups_user_belongs(
+                    user_profile.airavata_internal_user_id))
         return {
-            'airavataInternalUserId': user_profile.airavataInternalUserId,
-            'userId': user_profile.userId,
-            'gatewayId': user_profile.gatewayId,
+            'airavataInternalUserId': user_profile.airavata_internal_user_id,
+            'userId': user_profile.user_id,
+            'gatewayId': user_profile.gateway_id,
             'email': user_profile.emails[0],
-            'firstName': user_profile.firstName,
-            'lastName': user_profile.lastName,
-            'enabled': user_profile.State == Status.ACTIVE,
-            'emailVerified': (user_profile.State == Status.CONFIRMED or
-                              user_profile.State == Status.ACTIVE),
+            'firstName': user_profile.first_name,
+            'lastName': user_profile.last_name,
+            'enabled': user_profile.state == Status.ACTIVE,
+            'emailVerified': (user_profile.state == Status.CONFIRMED or
+                              user_profile.state == Status.ACTIVE),
             'airavataUserProfileExists': airavata_user_profile_exists,
-            'creationTime': user_profile.creationTime,
+            'creationTime': user_profile.creation_time,
             'groups': groups
         }
 
@@ -1985,6 +1974,10 @@ class UnverifiedEmailUserViewSet(mixins.ListModelMixin,
 
     def _get_unverified_email_user_profiles(
             self, limit=-1, offset=0, username=None):
+        from airavata_sdk.generated.org.apache.airavata.model.user import (
+            user_profile_pb2,
+        )
+        Status = user_profile_pb2.Status
         unverified_emails = EmailVerification.objects.filter(
             verified=False).order_by('username').values('username').distinct()
         if username is not None:
@@ -1996,23 +1989,23 @@ class UnverifiedEmailUserViewSet(mixins.ListModelMixin,
             unverified_username = unverified_email['username']
             if iam_admin_client.is_user_exist(unverified_username):
                 user_profile = iam_admin_client.get_user(unverified_username)
-                if (user_profile.State == Status.CONFIRMED or
-                        user_profile.State == Status.ACTIVE):
+                if (user_profile.state == Status.CONFIRMED or
+                        user_profile.state == Status.ACTIVE):
                     # TODO: test this
                     EmailVerification.objects.filter(
                         username=unverified_username).update(
                         verified=True)
                     continue
                 results.append({
-                    'userId': user_profile.userId,
-                    'gatewayId': user_profile.gatewayId,
+                    'userId': user_profile.user_id,
+                    'gatewayId': user_profile.gateway_id,
                     'email': user_profile.emails[0],
-                    'firstName': user_profile.firstName,
-                    'lastName': user_profile.lastName,
-                    'enabled': user_profile.State == Status.ACTIVE,
-                    'emailVerified': (user_profile.State == Status.CONFIRMED or
-                                      user_profile.State == Status.ACTIVE),
-                    'creationTime': user_profile.creationTime,
+                    'firstName': user_profile.first_name,
+                    'lastName': user_profile.last_name,
+                    'enabled': user_profile.state == Status.ACTIVE,
+                    'emailVerified': (user_profile.state == Status.CONFIRMED or
+                                      user_profile.state == Status.ACTIVE),
+                    'creationTime': user_profile.creation_time,
                 })
             else:
                 # Delete the EmailVerification records since that user no

Reply via email to