Skip to content

Commit

Permalink
Factor out permissions filter and add logical test
Browse files Browse the repository at this point in the history
  • Loading branch information
Fingel committed Feb 6, 2025
1 parent a8be0ca commit 076898f
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 16 deletions.
53 changes: 52 additions & 1 deletion tom_targets/tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from datetime import datetime
import responses

from django.contrib.auth.models import User, Group
from django.contrib.auth.models import AnonymousUser, User, Group
from django.contrib.messages import get_messages
from django.contrib.messages.constants import SUCCESS, WARNING
from django.core.files.uploadedfile import SimpleUploadedFile
Expand All @@ -18,6 +18,7 @@
from tom_targets.models import Target, TargetExtra, TargetList, TargetName
from tom_targets.utils import import_targets
from tom_targets.merge import target_merge
from tom_targets.views import target_permission_filter
from tom_dataproducts.models import ReducedDatum, DataProduct
from tom_observations.models import ObservationRecord
from guardian.shortcuts import assign_perm, get_perms
Expand Down Expand Up @@ -1946,3 +1947,53 @@ def test_seed_targets_unauthenticated(self):
response = self.client.post(reverse('targets:seed'))
self.assertEqual(response.status_code, 302)
self.assertFalse(Target.objects.exists())


class TestTargetPermissionFiltering(TestCase):
def setUp(self):
self.user = User.objects.create(username='testuser')
self.group = Group.objects.create(name='testgroup')
self.open_target = SiderealTargetFactory.create(permissions=Target.Permissions.OPEN)
self.public_target = SiderealTargetFactory.create(permissions=Target.Permissions.PUBLIC)
self.private_group_target = SiderealTargetFactory.create(permissions=Target.Permissions.PRIVATE)
self.private_user_target = SiderealTargetFactory.create(permissions=Target.Permissions.PRIVATE)

def test_open_targets_visible(self):
result = target_permission_filter(AnonymousUser(), Target.objects.all())
self.assertIn(self.open_target, result)
self.assertNotIn(self.public_target, result)
self.assertNotIn(self.private_group_target, result)
self.assertNotIn(self.private_user_target, result)

def test_public_targets_visible(self):
result = target_permission_filter(self.user, Target.objects.all())
self.assertIn(self.open_target, result)
self.assertIn(self.public_target, result)
self.assertNotIn(self.private_group_target, result)
self.assertNotIn(self.private_user_target, result)

def test_private_group_permission(self):
self.group.user_set.add(self.user)
assign_perm('tom_targets.view_target', self.group, self.private_group_target)
result = target_permission_filter(self.user, Target.objects.all())
self.assertIn(self.open_target, result)
self.assertIn(self.public_target, result)
self.assertIn(self.private_group_target, result)
self.assertNotIn(self.private_user_target, result)

def test_private_user_permission(self):
assign_perm('tom_targets.view_target', self.user, self.private_user_target)
result = target_permission_filter(self.user, Target.objects.all())
self.assertIn(self.open_target, result)
self.assertIn(self.public_target, result)
self.assertNotIn(self.private_group_target, result)
self.assertIn(self.private_user_target, result)

def test_superuser_permission(self):
self.user.is_superuser = True
self.user.save()
result = target_permission_filter(self.user, Target.objects.all())
self.assertIn(self.open_target, result)
self.assertIn(self.public_target, result)
self.assertIn(self.private_group_target, result)
self.assertIn(self.private_user_target, result)
29 changes: 14 additions & 15 deletions tom_targets/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,19 @@
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

def target_permission_filter(user, qs):
if user.is_authenticated:
if user.is_superuser:
# Do not filter the queryset by permissions at all
return qs
else:
# Exclude targets that are private except for those that the user has explicit permissions to view
private_targets = qs.filter(permissions=Target.Permissions.PRIVATE)
public_targets = qs.exclude(permissions=Target.Permissions.PRIVATE)
return public_targets | get_objects_for_user(user, f'{Target._meta.app_label}.view_target', private_targets)
else:
# Only allow open targets
return qs.exclude(permissions__in=[Target.Permissions.PUBLIC, Target.Permissions.PRIVATE])

class TargetListView(FilterView):
"""
Expand Down Expand Up @@ -94,21 +107,7 @@ def get_context_data(self, *args, **kwargs):

def get_queryset(self, *args, **kwargs):
qs = super().get_queryset(*args, **kwargs)

if self.request.user.is_authenticated:
if self.request.user.is_superuser:
# Do not filter the queryset by permissions at all
return qs
else:
# Exclude targets that are private except for those that the user has explicit permissions to view
private_targets = qs.filter(permissions=Target.Permissions.PRIVATE)
public_targets = qs.exclude(permissions=Target.Permissions.PRIVATE)
return public_targets | get_objects_for_user(self.request.user, f'{Target._meta.app_label}.view_target', private_targets)
else:
# Only allow open targets
return qs.exclude(permissions__in=[Target.Permissions.PUBLIC, Target.Permissions.PRIVATE])


return target_permission_filter(self.request.user, qs)


class TargetNameSearchView(RedirectView):
Expand Down

0 comments on commit 076898f

Please sign in to comment.