Skip to content

Commit

Permalink
fix permissions on Bid v2 endpoint (#614)
Browse files Browse the repository at this point in the history
[#186384302]
  • Loading branch information
uraniumanchor authored Nov 1, 2023
1 parent 5e8dfcc commit 367c7d0
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 38 deletions.
71 changes: 37 additions & 34 deletions tests/apiv2/test_bids.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@

class TestBidViewSet(TestBidBase, APITestCase):
model_name = 'bid'
view_user_permissions = ['view_hidden_bid']
add_user_permissions = ['top_level_bid']

def setUp(self):
super().setUp()
self.client.force_authenticate(user=self.super_user)
self.client.force_authenticate(user=self.locked_user)

def test_detail(self):
serialized = BidSerializer(self.opened_parent_bid, tree=True)
Expand Down Expand Up @@ -174,9 +176,9 @@ def test_create(self):
serialized = BidSerializer(models.Bid.objects.get(pk=data['id']))
self.assertEqual(data, serialized.data)

with self.subTest('attach to locked event with permission'):
with self.subTest('attach to parent'):
data = self.post_new(
data={'name': 'New Locked Event Bid', 'event': self.locked_event.pk},
data={'name': 'New Child', 'parent': self.opened_parent_bid.pk},
)
serialized = BidSerializer(models.Bid.objects.get(pk=data['id']))
self.assertEqual(data, serialized.data)
Expand All @@ -188,27 +190,28 @@ def test_create(self):
serialized = BidSerializer(models.Bid.objects.get(pk=data['id']))
self.assertEqual(data, serialized.data)

with self.subTest('attach to locked speedrun with permission'):
with self.subTest('attach to chain'):
data = self.post_new(
data={'name': 'New Locked Run Bid', 'speedrun': self.locked_run.pk},
data={
'name': 'Chain Abyss',
'parent': self.chain_bottom.pk,
'goal': 50,
},
)
serialized = BidSerializer(models.Bid.objects.get(pk=data['id']))
self.assertEqual(data, serialized.data)

with self.subTest('attach to parent'):
with self.subTest('attach to locked event with permission'):
data = self.post_new(
data={'name': 'New Child', 'parent': self.opened_parent_bid.pk},
data={'name': 'New Locked Event Bid', 'event': self.locked_event.pk},
user=self.locked_user,
)
serialized = BidSerializer(models.Bid.objects.get(pk=data['id']))
self.assertEqual(data, serialized.data)

with self.subTest('attach to chain'):
with self.subTest('attach to locked speedrun with permission'):
data = self.post_new(
data={
'name': 'Chain Abyss',
'parent': self.chain_bottom.pk,
'goal': 50,
},
data={'name': 'New Locked Run Bid', 'speedrun': self.locked_run.pk},
)
serialized = BidSerializer(models.Bid.objects.get(pk=data['id']))
self.assertEqual(data, serialized.data)
Expand Down Expand Up @@ -248,28 +251,7 @@ def test_create(self):

self.client.force_authenticate(user=self.add_user)

with self.subTest('require top level permission for bids without parents'):
self.post_new(
data={'name': 'New Event Bid 2', 'event': self.event.pk},
status_code=403,
)

self.post_new(
data={
'name': 'New Child 2',
'parent': self.opened_parent_bid.pk,
},
status_code=201,
)

with self.subTest('require locked permission'):
self.add_user.user_permissions.add(
Permission.objects.get(codename='top_level_bid')
)
# TODO: maybe make a separate user for this
del self.add_user._perm_cache
del self.add_user._user_perm_cache

self.post_new(
data={
'name': 'New Locked Event Bid 2',
Expand All @@ -294,6 +276,27 @@ def test_create(self):
status_code=403,
)

with self.subTest('require top level permission for bids without parents'):
self.add_user.user_permissions.remove(
Permission.objects.get(codename='top_level_bid')
)
# TODO: maybe make a separate user for this
del self.add_user._perm_cache
del self.add_user._user_perm_cache

self.post_new(
data={'name': 'New Event Bid 2', 'event': self.event.pk},
status_code=403,
)

self.post_new(
data={
'name': 'New Child 2',
'parent': self.opened_parent_bid.pk,
},
status_code=201,
)

with self.subTest('anonymous'):
self.post_new(
data={
Expand Down
25 changes: 24 additions & 1 deletion tests/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ def test_nulls_removed(self):

class APITestCase(TransactionTestCase):
model_name = None
view_user_permissions = [] # trickles to add_user and locked_user
add_user_permissions = [] # trickles to locked_user
locked_user_permissions = []
encoder = DjangoJSONEncoder()

def parseJSON(self, response, status_code=200):
Expand Down Expand Up @@ -515,6 +518,7 @@ def setUp(self):
self.view_user.user_permissions.add(
Permission.objects.get(name=f'Can view {self.model_name}'),
)

self.add_user.user_permissions.add(
Permission.objects.get(name=f'Can add {self.model_name}'),
Permission.objects.get(name=f'Can change {self.model_name}'),
Expand All @@ -525,6 +529,25 @@ def setUp(self):
Permission.objects.get(name=f'Can change {self.model_name}'),
Permission.objects.get(name=f'Can view {self.model_name}'),
)
self.view_user.user_permissions.add(
*(Permission.objects.filter(codename__in=self.view_user_permissions))
)
self.add_user.user_permissions.add(
*(
Permission.objects.filter(
codename__in=self.view_user_permissions + self.add_user_permissions
)
)
)
self.locked_user.user_permissions.add(
*(
Permission.objects.filter(
codename__in=self.view_user_permissions
+ self.add_user_permissions
+ self.locked_user_permissions
)
)
)
self.super_user = User.objects.create(username='super', is_superuser=True)
self.maxDiff = None

Expand Down Expand Up @@ -581,7 +604,7 @@ def tearDown(self):
f'./test-results/TEST-{self.id()}.{int(time.time())}.png'
)
raise Exception(
f'data:image/png;base64,{self.webdriver.get_screenshot_as_base64()}'
f'{self.webdriver.current_url}\ndata:image/png;base64,{self.webdriver.get_screenshot_as_base64()}'
)

def tracker_login(self, username, password='password'):
Expand Down
6 changes: 3 additions & 3 deletions tracker/api/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class EventLockedPermission(DjangoModelPermissionsOrAnonReadOnly):
def has_permission(self, request: Request, view: t.Callable):
return super().has_permission(request, view) and (
request.method in SAFE_METHODS
or request.user.has_perm('tracker.edit_locked_events')
or request.user.has_perm('tracker.can_edit_locked_events')
or not view.is_event_locked(request)
)

Expand All @@ -59,7 +59,7 @@ def has_permission(self, request: Request, view: t.Callable):
return super().has_permission(request, view) and (
feed is None
or feed in self.PUBLIC_FEEDS
or request.user.has_perm('tracker.view_hidden_bids')
or request.user.has_perm('tracker.view_hidden_bid')
)


Expand All @@ -71,5 +71,5 @@ class BidStatePermission(BasePermission):
def has_object_permission(self, request: Request, view: t.Callable, obj: t.Any):
return super().has_object_permission(request, view, obj) and (
obj.state in self.PUBLIC_STATES
or request.user.has_perm('tracker.view_hidden_bids')
or request.user.has_perm('tracker.view_hidden_bid')
)

0 comments on commit 367c7d0

Please sign in to comment.