Compare commits

...
4 changed files with 43 additions and 3 deletions
@@ -0,0 +1 @@
`GET /api/v1/users/me` membership relationships identify the active tenant with `meta.active` for JWT and API key authentication
@@ -1590,8 +1590,8 @@ class TestAPIKeyMultiTenantWorkflows:
tenant1 = tenants_fixture[0]
tenant2 = tenants_fixture[1]
Membership.objects.create(user=user, tenant=tenant1)
Membership.objects.create(user=user, tenant=tenant2)
membership1 = Membership.objects.create(user=user, tenant=tenant1)
membership2 = Membership.objects.create(user=user, tenant=tenant2)
role1 = Role.objects.create(
tenant_id=tenant1.id,
@@ -1646,6 +1646,27 @@ class TestAPIKeyMultiTenantWorkflows:
assert me_response1.json()["data"]["id"] == str(user.id)
assert me_response2.json()["data"]["id"] == str(user.id)
memberships1 = {
item["id"]: item["meta"]["active"]
for item in me_response1.json()["data"]["relationships"]["memberships"][
"data"
]
}
memberships2 = {
item["id"]: item["meta"]["active"]
for item in me_response2.json()["data"]["relationships"]["memberships"][
"data"
]
}
assert memberships1 == {
str(membership1.id): True,
str(membership2.id): False,
}
assert memberships2 == {
str(membership1.id): False,
str(membership2.id): True,
}
def test_api_key_cannot_access_different_tenant_resources(
self, tenants_fixture, aws_provider
):
+15
View File
@@ -329,6 +329,15 @@ class TokenSwitchTenantSerializer(BaseSerializerV1):
# Users
class ActiveMembershipRelatedField(SerializerMethodResourceRelatedField):
def to_representation(self, value):
representation = super().to_representation(value)
representation["meta"] = {
"active": str(value.tenant_id) == str(self.context["request"].tenant_id),
}
return representation
class UserSerializer(BaseModelSerializerV1):
"""
Serializer for the User model.
@@ -390,6 +399,12 @@ class UserSerializer(BaseModelSerializerV1):
)
class UserMeSerializer(UserSerializer):
memberships = ActiveMembershipRelatedField(
many=True, read_only=True, source="memberships", method_name="get_memberships"
)
class UserIncludeSerializer(UserSerializer):
class Meta:
model = User
+4 -1
View File
@@ -238,6 +238,7 @@ from api.v1.serializers import (
TokenSocialLoginSerializer,
TokenSwitchTenantSerializer,
UserCreateSerializer,
UserMeSerializer,
UserRoleRelationshipSerializer,
UserSerializer,
UserUpdateSerializer,
@@ -1113,6 +1114,8 @@ class UserViewSet(BaseUserViewset):
return UserCreateSerializer
elif self.action == "partial_update":
return UserUpdateSerializer
elif self.action == "me":
return UserMeSerializer
else:
return UserSerializer
@@ -1130,7 +1133,7 @@ class UserViewSet(BaseUserViewset):
@action(detail=False, methods=["get"], url_name="me")
def me(self, request):
user = self.request.user
serializer = UserSerializer(user, context=self.get_serializer_context())
serializer = self.get_serializer(user)
return Response(
data=serializer.data,
status=status.HTTP_200_OK,