Skip to content
This repository has been archived by the owner on Sep 16, 2022. It is now read-only.

Commit

Permalink
Merge pull request #458 from CSCfi/CSCMETAX-599-allower-projects-fix
Browse files Browse the repository at this point in the history
CSCMETAX-599: [FIX|REF] allowed_projects: Further improve handling. R…
  • Loading branch information
hannu40k authored Jul 1, 2019
2 parents b66b610 + 27bff67 commit 209b64f
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 6 deletions.
6 changes: 2 additions & 4 deletions src/metax_api/api/rest/base/views/file_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,13 @@ def update_bulk(self, request, *args, **kwargs):
Checks that all files belongs to project in allowed_projects query parameter
if given.
"""
allowed_projects = request.query_params.get('allowed_projects', None)
allowed_projects = CommonService.get_list_query_param(request, 'allowed_projects')

if allowed_projects is not None:
if not isinstance(request.data, list):
return Response(data={ 'detail': 'request.data is not a list'}, status=status.HTTP_400_BAD_REQUEST)

file_ids = [f['identifier'] for f in request.data]
allowed_projects = set( project.strip() for project in allowed_projects.split(',') )

if not FileService.verify_allowed_projects(allowed_projects, file_identifiers=file_ids):
return Response(data={"detail": "You do not have permission to update these files"},
Expand All @@ -117,7 +116,7 @@ def partial_update_bulk(self, request, *args, **kwargs):
Checks that all files belongs to project in allowed_projects query parameter
if given.
"""
allowed_projects = request.query_params.get('allowed_projects', None)
allowed_projects = CommonService.get_list_query_param(request, 'allowed_projects')

if allowed_projects is not None:
if not isinstance(request.data, list):
Expand All @@ -128,7 +127,6 @@ def partial_update_bulk(self, request, *args, **kwargs):
return Response(data={"detail": "File identifier is missing"},
status=status.HTTP_400_BAD_REQUEST)

allowed_projects = set( project.strip() for project in allowed_projects.split(',') )
if not FileService.verify_allowed_projects(allowed_projects, file_identifiers=file_ids):
return Response(data={"detail": "You do not have permission to update these files"},
status=status.HTTP_403_FORBIDDEN)
Expand Down
4 changes: 3 additions & 1 deletion src/metax_api/models/catalog_record.py
Original file line number Diff line number Diff line change
Expand Up @@ -1335,9 +1335,11 @@ def _check_changed_files_permissions(self, file_changes):
projects_removed = file_changes['changed_projects'].get('files_removed', set())
project_changes = projects_added.union(projects_removed)

allowed_projects = self.request.query_params.get('allowed_projects', None)
from metax_api.services import CommonService
allowed_projects = CommonService.get_list_query_param(self.request, 'allowed_projects')

if allowed_projects is not None:

if not all(p in allowed_projects for p in project_changes):
raise Http403({'detail': [
'Unable to update dataset %s. You do not have permissions to all of the files and directories.'
Expand Down
17 changes: 17 additions & 0 deletions src/metax_api/services/common_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,23 @@ def get_boolean_query_param(request, param_name):
'boolean value must be true or false. received value was %s' % value
]})

@staticmethod
def get_list_query_param(request, param_name):
"""
Retrieve an optional comma-separated list of string values from a query param.
Note: Returns set, not a list!
Note: In case method is needed before dispatch() is called, see what is done in
method get_boolean_query_param().
"""
value = request.query_params.get(param_name, None)
if value is not None:
values_list = set( v.strip() for v in value.split(',') )
if values_list:
return values_list
return None

@classmethod
def create_bulk(cls, request, serializer_class, **kwargs):
"""
Expand Down
12 changes: 11 additions & 1 deletion src/metax_api/tests/api/rest/base/views/datasets/write.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,13 +261,23 @@ def test_create_catalog_record_allowed_projects_ok(self):
self.assertEqual(response.status_code, status.HTTP_201_CREATED, response.data)

def test_create_catalog_record_allowed_projects_fail(self):
# dataset file not in allowed projects
response = self.client.post('/rest/datasets?allowed_projects=no,permission', self.cr_test_data, format="json")
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN, response.data)

def test_create_catalog_record_allowed_projects_empty_value(self):
# ensure list is properly handled (separated by comma, end result should be list)
response = self.client.post('/rest/datasets?allowed_projects=no_good_project_x,another',
self.cr_test_data, format="json")
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN, response.data)

# handle empty value
response = self.client.post('/rest/datasets?allowed_projects=', self.cr_test_data, format="json")
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN, response.data)

# Other trickery
response = self.client.post('/rest/datasets?allowed_projects=,', self.cr_test_data, format="json")
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN, response.data)

#
# create list operations
#
Expand Down

0 comments on commit 209b64f

Please sign in to comment.