Skip to content

Commit 3672b17

Browse files
authored
feat(api): identify active membership in current user response (#12388)
1 parent fd555e2 commit 3672b17

4 files changed

Lines changed: 43 additions & 3 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
`GET /api/v1/users/me` membership relationships identify the active tenant with `meta.active` for JWT and API key authentication

api/src/backend/api/tests/integration/test_authentication.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,8 +1590,8 @@ def test_user_with_multiple_tenant_memberships_api_keys(self, tenants_fixture):
15901590
tenant1 = tenants_fixture[0]
15911591
tenant2 = tenants_fixture[1]
15921592

1593-
Membership.objects.create(user=user, tenant=tenant1)
1594-
Membership.objects.create(user=user, tenant=tenant2)
1593+
membership1 = Membership.objects.create(user=user, tenant=tenant1)
1594+
membership2 = Membership.objects.create(user=user, tenant=tenant2)
15951595

15961596
role1 = Role.objects.create(
15971597
tenant_id=tenant1.id,
@@ -1646,6 +1646,27 @@ def test_user_with_multiple_tenant_memberships_api_keys(self, tenants_fixture):
16461646
assert me_response1.json()["data"]["id"] == str(user.id)
16471647
assert me_response2.json()["data"]["id"] == str(user.id)
16481648

1649+
memberships1 = {
1650+
item["id"]: item["meta"]["active"]
1651+
for item in me_response1.json()["data"]["relationships"]["memberships"][
1652+
"data"
1653+
]
1654+
}
1655+
memberships2 = {
1656+
item["id"]: item["meta"]["active"]
1657+
for item in me_response2.json()["data"]["relationships"]["memberships"][
1658+
"data"
1659+
]
1660+
}
1661+
assert memberships1 == {
1662+
str(membership1.id): True,
1663+
str(membership2.id): False,
1664+
}
1665+
assert memberships2 == {
1666+
str(membership1.id): False,
1667+
str(membership2.id): True,
1668+
}
1669+
16491670
def test_api_key_cannot_access_different_tenant_resources(
16501671
self, tenants_fixture, aws_provider
16511672
):

api/src/backend/api/v1/serializers.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,15 @@ def validate(self, attrs):
329329
# Users
330330

331331

332+
class ActiveMembershipRelatedField(SerializerMethodResourceRelatedField):
333+
def to_representation(self, value):
334+
representation = super().to_representation(value)
335+
representation["meta"] = {
336+
"active": str(value.tenant_id) == str(self.context["request"].tenant_id),
337+
}
338+
return representation
339+
340+
332341
class UserSerializer(BaseModelSerializerV1):
333342
"""
334343
Serializer for the User model.
@@ -390,6 +399,12 @@ def get_memberships(self, instance):
390399
)
391400

392401

402+
class UserMeSerializer(UserSerializer):
403+
memberships = ActiveMembershipRelatedField(
404+
many=True, read_only=True, source="memberships", method_name="get_memberships"
405+
)
406+
407+
393408
class UserIncludeSerializer(UserSerializer):
394409
class Meta:
395410
model = User

api/src/backend/api/v1/views.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@
238238
TokenSocialLoginSerializer,
239239
TokenSwitchTenantSerializer,
240240
UserCreateSerializer,
241+
UserMeSerializer,
241242
UserRoleRelationshipSerializer,
242243
UserSerializer,
243244
UserUpdateSerializer,
@@ -1113,6 +1114,8 @@ def get_serializer_class(self):
11131114
return UserCreateSerializer
11141115
elif self.action == "partial_update":
11151116
return UserUpdateSerializer
1117+
elif self.action == "me":
1118+
return UserMeSerializer
11161119
else:
11171120
return UserSerializer
11181121

@@ -1130,7 +1133,7 @@ def get_serializer_context(self):
11301133
@action(detail=False, methods=["get"], url_name="me")
11311134
def me(self, request):
11321135
user = self.request.user
1133-
serializer = UserSerializer(user, context=self.get_serializer_context())
1136+
serializer = self.get_serializer(user)
11341137
return Response(
11351138
data=serializer.data,
11361139
status=status.HTTP_200_OK,

0 commit comments

Comments
 (0)