Skip to content

Commit

Permalink
Ensure permissions are applied correctly for users who don't have acc…
Browse files Browse the repository at this point in the history
…ess to attachments
  • Loading branch information
FrankApiyo committed Feb 21, 2023
1 parent e2c7b55 commit 33ec005
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 10 deletions.
50 changes: 48 additions & 2 deletions onadata/apps/api/tests/viewsets/test_dataview_viewset.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,17 +179,63 @@ def test_dataview_with_attachment_field(self):
attachment_list_view = AttachmentViewSet.as_view({"get": "list"})
request = self.factory.get("/?dataview=" + str(self.data_view.pk), **self.extra)
response = attachment_list_view(request)
attachments = Attachment.objects.filter(
instance__xform=self.data_view.xform)
self.assertEqual(1, len(response.data))
self.assertEqual(self.data_view.query,
[{'value': 'no', 'column': 'pizza_fan', 'filter': '='}])
serialized_attachments = AttachmentSerializer(
Attachment.objects.filter(
instance__xform=self.data_view.xform),
attachments,
many=True, context={'request': request}).data
self.assertEqual(
serialized_attachments,
response.data)

# create profile for alice
alice_data = {'username': 'alice', 'email': '[email protected]',
'password1': 'alice', 'password2': 'alice',
'first_name': 'Alice', 'last_name': 'A',
'city': 'Nairobi', 'country': 'KE'}
alice_profile = self._create_user_profile(extra_post_data=alice_data)

# check that user with no permisisons can not list attachment objects
request = self.factory.get("/?dataview=" + str(self.data_view.pk), **self.extra)
request.user = alice_profile.user
response = attachment_list_view(request, user=alice_profile.user)
attachments = Attachment.objects.filter(
instance__xform=self.data_view.xform)
self.assertEqual(0, len(response.data))
self.assertEqual(self.data_view.query,
[{'value': 'no', 'column': 'pizza_fan', 'filter': '='}])
self.assertEqual(
[],
response.data)

# check that user with no permisisons can not view a specific attachment object
attachment_list_view = AttachmentViewSet.as_view({"get": "retrieve"})
request = self.factory.get("/?dataview=" + str(self.data_view.pk), **self.extra)
request.user = alice_profile.user
response = attachment_list_view(
request, pk=attachments.first().pk, user=alice_profile.user)
self.assertEqual(self.data_view.query,
[{'value': 'no', 'column': 'pizza_fan', 'filter': '='}])
self.assertEqual(response.status_code, 404)
response_data = json.loads(json.dumps(response.data))
self.assertEqual(response_data, {'detail': 'Not found.'})

# a user with permissions can view a specific attachment object
attachment_list_view = AttachmentViewSet.as_view({"get": "retrieve"})
request = self.factory.get("/?dataview=" + str(self.data_view.pk), **self.extra)
response = attachment_list_view(
request, pk=attachments.first().pk, user=self.user)
self.assertEqual(self.data_view.query,
[{'value': 'no', 'column': 'pizza_fan', 'filter': '='}])
self.assertEqual(response.status_code, 200)
serialized_attachment = AttachmentSerializer(
attachments.first(),
context={'request': request}).data
self.assertEqual(response.data, serialized_attachment)

# pylint: disable=invalid-name
def test_get_dataview_form_definition(self):
self._create_dataview()
Expand Down
16 changes: 8 additions & 8 deletions onadata/libs/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,19 +337,16 @@ def _xform_filter(self, request, view, keyword):
"Invalid value for dataview ID. It must be a positive integer."
)
self.dataview = get_object_or_404(DataView, pk=dataview)
kwargs = self._add_instance_prefix_to_dataview_filter_kwargs(
# filter with fitlered dataset query
dataview_kwargs = self._add_instance_prefix_to_dataview_filter_kwargs(
get_filter_kwargs(self.dataview.query))
return {
**kwargs,
**{f"{keyword}": self.dataview.xform}
}
xform_qs = XForm.objects.filter(pk=self.dataview.xform.pk)
if merged_xform:
int_or_parse_error(
merged_xform,
"Invalid value for Merged Dataset ID. It must be a positive integer.")
self.merged_xform = get_object_or_404(MergedXForm, pk=merged_xform)
xforms = self.merged_xform.xforms.all()
return {f"{keyword}__in": xforms}
xform_qs = self.merged_xform.xforms.all()
if xform:
int_or_parse_error(
xform, "Invalid value for formid. It must be a positive integer."
Expand All @@ -365,7 +362,10 @@ def _xform_filter(self, request, view, keyword):
xforms = xform_qs.filter(shared_data=True)
else:
xforms = super().filter_queryset(request, xform_qs, view) | public_forms
return {f"{keyword}__in": xforms}
return {
**{f"{keyword}__in": xforms},
**(dataview_kwargs or {})
}

def _xform_filter_queryset(self, request, queryset, view, keyword):
kwarg = self._xform_filter(request, view, keyword)
Expand Down

0 comments on commit 33ec005

Please sign in to comment.