Skip to content

Commit 20dfccc

Browse files
add current_user_role to project details endpoint
1 parent 3fcff85 commit 20dfccc

File tree

3 files changed

+48
-13
lines changed

3 files changed

+48
-13
lines changed

onadata/apps/api/tests/viewsets/test_project_viewset.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
from onadata.libs.serializers.metadata_serializer import MetaDataSerializer
6262
from onadata.libs.serializers.project_serializer import (
6363
BaseProjectSerializer,
64+
ProjectPrivateSerializer,
6465
ProjectSerializer,
6566
)
6667
from onadata.libs.utils.cache_tools import PROJ_OWNER_CACHE, safe_key
@@ -309,11 +310,14 @@ def test_projects_get(self):
309310
self.assertEqual(response.status_code, 200)
310311

311312
# test serialized data
312-
serializer = ProjectSerializer(self.project, context={"request": request})
313-
self.assertEqual(response.data, serializer.data)
313+
public_data = ProjectSerializer(self.project, context={"request": request}).data
314+
private_data = ProjectPrivateSerializer(
315+
self.project, context={"request": request}
316+
).data
317+
self.assertEqual(response.data, {**public_data, **private_data})
314318

315319
self.assertIsNotNone(self.project_data)
316-
self.assertEqual(response.data, self.project_data)
320+
self.assertEqual(response.data, {**self.project_data, **private_data})
317321
res_user_props = list(response.data["users"][0])
318322
res_user_props.sort()
319323
self.assertEqual(res_user_props, user_props)
@@ -1678,7 +1682,10 @@ def test_cache_updated_on_project_update(self):
16781682
self.assertEqual(response.status_code, 200)
16791683
self.assertEqual(False, response.data.get("public"))
16801684
cached_project = cache.get(f"{PROJ_OWNER_CACHE}{self.project.pk}")
1681-
self.assertEqual(cached_project, response.data)
1685+
# Response without user specific fields
1686+
res_wo_private = {**response.data}
1687+
res_wo_private.pop("current_user_role")
1688+
self.assertEqual(cached_project, res_wo_private)
16821689

16831690
projectid = self.project.pk
16841691
data = {"public": True}
@@ -1694,7 +1701,10 @@ def test_cache_updated_on_project_update(self):
16941701
self.assertEqual(response.status_code, 200)
16951702
self.assertEqual(True, response.data.get("public"))
16961703
cached_project = cache.get(f"{PROJ_OWNER_CACHE}{self.project.pk}")
1697-
self.assertEqual(cached_project, response.data)
1704+
# Response without user specific fields
1705+
res_wo_private = {**response.data}
1706+
res_wo_private.pop("current_user_role")
1707+
self.assertEqual(cached_project, res_wo_private)
16981708

16991709
def test_project_put_updates(self):
17001710
self._project_create()

onadata/apps/api/viewsets/project_viewset.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
)
3636
from onadata.libs.serializers.project_serializer import (
3737
BaseProjectSerializer,
38+
ProjectPrivateSerializer,
3839
ProjectSerializer,
3940
)
4041
from onadata.libs.serializers.share_project_serializer import (
@@ -124,14 +125,18 @@ def update(self, request, *args, **kwargs):
124125

125126
def retrieve(self, request, *args, **kwargs):
126127
"""Retrieve single project"""
127-
project_id = kwargs.get("pk")
128-
project = safe_cache_get(f"{PROJ_OWNER_CACHE}{project_id}")
129-
if project:
130-
return Response(project)
131-
# pylint: disable=attribute-defined-outside-init
132-
self.object = self.get_object()
133-
serializer = ProjectSerializer(self.object, context={"request": request})
134-
return Response(serializer.data)
128+
project = self.get_object()
129+
public_data = safe_cache_get(f"{PROJ_OWNER_CACHE}{project.pk}")
130+
131+
if not public_data:
132+
public_data = ProjectSerializer(project, context={"request": request}).data
133+
134+
# Inject user specific fields
135+
private_data = ProjectPrivateSerializer(
136+
project, context={"request": request}
137+
).data
138+
139+
return Response({**public_data, **private_data})
135140

136141
def list(self, request, *args, **kwargs):
137142
"""Returns a list of projects"""

onadata/libs/serializers/project_serializer.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,3 +669,23 @@ def get_data_views(self, obj):
669669
safe_cache_set(project_dataview_cache_key, data_views)
670670

671671
return data_views
672+
673+
674+
class ProjectPrivateSerializer(serializers.ModelSerializer):
675+
"""User specific fields for a Project"""
676+
677+
current_user_role = serializers.SerializerMethodField()
678+
679+
def get_current_user_role(self, obj):
680+
"""
681+
Return the role of the request user in the project.
682+
"""
683+
if self.context["request"].user.is_anonymous:
684+
return None
685+
686+
perms = get_perms(self.context["request"].user, obj)
687+
return get_role(perms, obj)
688+
689+
class Meta:
690+
model = Project
691+
fields = ("current_user_role",)

0 commit comments

Comments
 (0)