Skip to content

Commit

Permalink
Allow collaborators on dbGaP applications to see info
Browse files Browse the repository at this point in the history
In addition to allowing PIs to see information about a dbGaP
application (DAR status, etc), also allow collaborators to see it.
Update the view mixin to check if a user is either a PI or a
collaborator, and then grant access appropriately.
  • Loading branch information
amstilp committed Jun 14, 2024
1 parent e72ccc6 commit d2cc1da
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 2 deletions.
72 changes: 71 additions & 1 deletion primed/dbgap/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1386,15 +1386,33 @@ def test_access_pi_of_dbgap_application(self):
response = self.client.get(self.get_url(self.obj.dbgap_project_id))
self.assertEqual(response.status_code, 200)

def test_access_collaborator_for_dbgap_application(self):
"""Returns successful response code when the user is a collaborator on the application."""
collaborator = UserFactory.create()
self.obj.collaborators.add(collaborator)
self.client.force_login(collaborator)
response = self.client.get(self.get_url(self.obj.dbgap_project_id))
self.assertEqual(response.status_code, 200)

def test_access_pi_of_other_dbgap_application(self):
"""Returns successful response code when the user is the PI of the application."""
"""Raises permission denied code when the user is a PI of a different dbGaP application."""
pi = self.obj.principal_investigator
other_application = factories.dbGaPApplicationFactory.create()
request = self.factory.get(self.get_url(other_application.dbgap_project_id))
request.user = pi
with self.assertRaises(PermissionDenied):
self.get_view()(request, dbgap_project_id=other_application.dbgap_project_id)

def test_access_collaborator_for_other_dbgap_application(self):
"""Raises permission denied code when the user is a collaborator on a different dbGaP application."""
collaborator = UserFactory.create()
self.obj.collaborators.add(collaborator)
other_application = factories.dbGaPApplicationFactory.create()
request = self.factory.get(self.get_url(other_application.dbgap_project_id))
request.user = collaborator
with self.assertRaises(PermissionDenied):
self.get_view()(request, dbgap_project_id=other_application.dbgap_project_id)

def test_view_status_code_with_existing_object(self):
"""Returns a successful status code for an existing object pk."""
# Only clients load the template.
Expand Down Expand Up @@ -3290,6 +3308,14 @@ def test_access_pi_of_dbgap_application(self):
response = self.client.get(self.get_url(self.application.dbgap_project_id, self.snapshot.pk))
self.assertEqual(response.status_code, 200)

def test_access_collaborator_for_dbgap_application(self):
"""Returns successful response code when the user is a collaborator on the application."""
collaborator = UserFactory.create()
self.application.collaborators.add(collaborator)
self.client.force_login(collaborator)
response = self.client.get(self.get_url(self.application.dbgap_project_id, self.snapshot.pk))
self.assertEqual(response.status_code, 200)

def test_access_pi_of_other_dbgap_application(self):
"""Returns successful response code when the user is the PI of the application."""
pi = self.application.principal_investigator
Expand All @@ -3303,6 +3329,20 @@ def test_access_pi_of_other_dbgap_application(self):
dbgap_data_access_snapshot_pk=other_snapshot.pk,
)

def test_access_collaborator_for_other_dbgap_application(self):
"""Raises permission denied code when the user is a collaborator on a different dbGaP application."""
collaborator = UserFactory.create()
self.application.collaborators.add(collaborator)
other_snapshot = factories.dbGaPDataAccessSnapshotFactory.create()
request = self.factory.get(self.get_url(other_snapshot.dbgap_application.dbgap_project_id, other_snapshot.pk))
request.user = collaborator
with self.assertRaises(PermissionDenied):
self.get_view()(
request,
dbgap_project_id=other_snapshot.dbgap_application.dbgap_project_id,
dbgap_data_access_snapshot_pk=other_snapshot.pk,
)

def test_access_without_user_permission(self):
"""Raises permission denied if user has no permissions."""
user_no_perms = User.objects.create_user(username="test-none", password="test-none")
Expand Down Expand Up @@ -3647,6 +3687,17 @@ def test_access_pi_of_dbgap_application(self):
)
self.assertEqual(response.status_code, 200)

def test_access_collaborator_for_dbgap_application(self):
"""Returns successful response code when the user is a collaborator on the application."""
dar = factories.dbGaPDataAccessRequestFactory.create(dbgap_dar_id=1)
collaborator = UserFactory.create()
dar.dbgap_data_access_snapshot.dbgap_application.collaborators.add(collaborator)
self.client.force_login(collaborator)
response = self.client.get(
self.get_url(dar.dbgap_data_access_snapshot.dbgap_application.dbgap_project_id, dar.dbgap_dar_id)
)
self.assertEqual(response.status_code, 200)

def test_access_pi_of_other_dbgap_application(self):
"""Returns successful response code when the user is the PI of the application."""
dar = factories.dbGaPDataAccessRequestFactory.create(dbgap_dar_id=1)
Expand All @@ -3665,6 +3716,25 @@ def test_access_pi_of_other_dbgap_application(self):
other_dar.dbgap_dar_id,
)

def test_access_collaborator_for_other_dbgap_application(self):
"""Raises permission denied code when the user is a collaborator on a different dbGaP application."""
dar = factories.dbGaPDataAccessRequestFactory.create(dbgap_dar_id=1)
collaborator = UserFactory.create()
dar.dbgap_data_access_snapshot.dbgap_application.collaborators.add(collaborator)
other_dar = factories.dbGaPDataAccessRequestFactory.create()
request = self.factory.get(
self.get_url(
other_dar.dbgap_data_access_snapshot.dbgap_application.dbgap_project_id, other_dar.dbgap_dar_id
)
)
request.user = collaborator
with self.assertRaises(PermissionDenied):
self.get_view()(
request,
other_dar.dbgap_data_access_snapshot.dbgap_application.dbgap_project_id,
other_dar.dbgap_dar_id,
)

def test_dbgap_dar_id_does_not_exist(self):
"""Raises permission denied if user has no permissions."""
request = self.factory.get(self.get_url(1, 2))
Expand Down
4 changes: 3 additions & 1 deletion primed/dbgap/viewmixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ def test_func(self):
self.dbgap_application = self.get_dbgap_application()
if not self.dbgap_application:
is_pi = False
is_collaborator = False
else:
is_pi = self.dbgap_application.principal_investigator == self.request.user
return has_acm_permission or is_pi
is_collaborator = self.request.user in self.dbgap_application.collaborators.all()
return has_acm_permission or is_pi or is_collaborator

0 comments on commit d2cc1da

Please sign in to comment.