🔒️(backend) remove accesses list from room serializer for non-admins

Restrict access to room user permissions data by excluding this information
from room serializer response for non-admin/owner users. Previously all
members could see complete access lists. Change enforces stricter information
access control based on user role.

Spotted in #YWH-PGM14336-5.
This commit is contained in:
lebaudantoine
2025-04-29 16:45:55 +02:00
committed by aleb_the_flash
parent 462c6c50e5
commit 422f838899
2 changed files with 6 additions and 38 deletions

View File

@@ -120,7 +120,7 @@ class RoomSerializer(serializers.ModelSerializer):
role = instance.get_role(request.user) role = instance.get_role(request.user)
is_admin = models.RoleChoices.check_administrator_role(role) is_admin = models.RoleChoices.check_administrator_role(role)
if role is not None: if is_admin:
access_serializer = NestedResourceAccessSerializer( access_serializer = NestedResourceAccessSerializer(
instance.accesses.select_related("resource", "user").all(), instance.accesses.select_related("resource", "user").all(),
context=self.context, context=self.context,

View File

@@ -338,22 +338,20 @@ def test_api_rooms_retrieve_authenticated():
) )
def test_api_rooms_retrieve_members(mock_token, django_assert_num_queries, settings): def test_api_rooms_retrieve_members(mock_token, django_assert_num_queries, settings):
""" """
Users who are members of a room should be allowed to see related users. Users who are members of a room should not be allowed to see related users.
""" """
settings.TIME_ZONE = "UTC" settings.TIME_ZONE = "UTC"
user = UserFactory() user = UserFactory()
other_user = UserFactory() other_user = UserFactory()
room = RoomFactory() room = RoomFactory()
user_access = UserResourceAccessFactory(resource=room, user=user, role="member") UserResourceAccessFactory(resource=room, user=user, role="member")
other_user_access = UserResourceAccessFactory( UserResourceAccessFactory(resource=room, user=other_user, role="member")
resource=room, user=other_user, role="member"
)
client = APIClient() client = APIClient()
client.force_login(user) client.force_login(user)
with django_assert_num_queries(4): with django_assert_num_queries(3):
response = client.get( response = client.get(
f"/api/v1.0/rooms/{room.id!s}/", f"/api/v1.0/rooms/{room.id!s}/",
) )
@@ -361,37 +359,7 @@ def test_api_rooms_retrieve_members(mock_token, django_assert_num_queries, setti
assert response.status_code == 200 assert response.status_code == 200
content_dict = response.json() content_dict = response.json()
assert sorted(content_dict.pop("accesses"), key=lambda x: x["id"]) == sorted( assert "accesses" not in content_dict
[
{
"id": str(user_access.id),
"user": {
"id": str(user_access.user.id),
"email": user_access.user.email,
"full_name": user_access.user.full_name,
"short_name": user_access.user.short_name,
"timezone": "UTC",
"language": user_access.user.language,
},
"resource": str(room.id),
"role": user_access.role,
},
{
"id": str(other_user_access.id),
"user": {
"id": str(other_user_access.user.id),
"email": other_user_access.user.email,
"full_name": other_user_access.user.full_name,
"short_name": other_user_access.user.short_name,
"timezone": "UTC",
"language": other_user_access.user.language,
},
"resource": str(room.id),
"role": other_user_access.role,
},
],
key=lambda x: x["id"],
)
expected_name = str(room.id) expected_name = str(room.id)
assert content_dict == { assert content_dict == {