Skip to content

Commit f64c010

Browse files
committed
Merge pull request #1602 from mboersma/1576-fix-deis-ps-perms
fix(controller): honor permissions on app-related views
2 parents 8eddaad + 423a55d commit f64c010

2 files changed

Lines changed: 32 additions & 11 deletions

File tree

controller/api/tests/test_perm.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,11 @@ def test_create(self):
154154
self.client.login(username='autotest-2', password='password'))
155155
response = self.client.get('/api/apps')
156156
self.assertEqual(len(response.data['results']), 0)
157+
# check that user 2 can't see any of the app's builds, configs,
158+
# containers, limits, or releases
159+
for model in ['builds', 'config', 'containers', 'limits', 'releases']:
160+
response = self.client.get("/api/apps/{}/{}/".format(app_id, model))
161+
self.assertEqual(response.data['detail'], 'Not found')
157162
# TODO: test that git pushing to the app fails
158163
# give user 2 permission to user 1's app
159164
self.assertTrue(
@@ -168,6 +173,12 @@ def test_create(self):
168173
response = self.client.get('/api/apps')
169174
self.assertEqual(response.status_code, 200)
170175
self.assertEqual(len(response.data['results']), 1)
176+
# check that user 2 sees (empty) results now for builds, containers,
177+
# and releases. (config and limit will still give 404s since we didn't
178+
# push a build here.)
179+
for model in ['builds', 'containers', 'releases']:
180+
response = self.client.get("/api/apps/{}/{}/".format(app_id, model))
181+
self.assertEqual(len(response.data['results']), 0)
171182
# TODO: check that user 2 can git push the app
172183

173184
def test_create_errors(self):

controller/api/views.py

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
from django.contrib.auth.models import AnonymousUser
1010
from django.contrib.auth.models import User
11+
from django.http import Http404
1112
from django.utils import timezone
1213
from guardian.shortcuts import assign_perm
1314
from guardian.shortcuts import get_objects_for_user
@@ -324,14 +325,17 @@ def pre_save(self, obj):
324325

325326
def get_queryset(self, **kwargs):
326327
app = get_object_or_404(models.App, id=self.kwargs['id'])
328+
try:
329+
self.check_object_permissions(self.request, app)
330+
except PermissionDenied:
331+
raise Http404("No {} matches the given query.".format(
332+
self.model._meta.object_name))
327333
return self.model.objects.filter(app=app)
328334

329335
def get_object(self, *args, **kwargs):
330336
obj = self.get_queryset().latest('created')
331-
user = self.request.user
332-
if user == obj.app.owner or user in get_users_with_perms(obj.app):
333-
return obj
334-
raise PermissionDenied()
337+
self.check_object_permissions(self.request, obj)
338+
return obj
335339

336340

337341
class AppBuildViewSet(BaseAppViewSet):
@@ -368,10 +372,12 @@ class AppConfigViewSet(BaseAppViewSet):
368372
def get_object(self, *args, **kwargs):
369373
"""Return the Config associated with the App's latest Release."""
370374
app = get_object_or_404(models.App, id=self.kwargs['id'])
371-
user = self.request.user
372-
if user == app.owner or user in get_users_with_perms(app):
375+
try:
376+
self.check_object_permissions(self.request, app)
373377
return app.release_set.latest().config
374-
raise PermissionDenied()
378+
except (PermissionDenied, models.Release.DoesNotExist):
379+
raise Http404("No {} matches the given query.".format(
380+
self.model._meta.object_name))
375381

376382
def post_save(self, config, created=False):
377383
if created:
@@ -409,7 +415,12 @@ class AppLimitViewSet(BaseAppViewSet):
409415
def get_object(self, *args, **kwargs):
410416
"""Return the Limit associated with the App's latest Release."""
411417
app = get_object_or_404(models.App, id=self.kwargs['id'])
412-
return app.release_set.latest().config.limit
418+
try:
419+
self.check_object_permissions(self.request, app)
420+
return app.release_set.latest().config.limit
421+
except (PermissionDenied, models.Release.DoesNotExist):
422+
raise Http404("No {} matches the given query.".format(
423+
self.model._meta.object_name))
413424

414425
def post_save(self, limit, created=False):
415426
if created:
@@ -481,15 +492,14 @@ def rollback(self, request, *args, **kwargs):
481492
return Response(response, status=status.HTTP_201_CREATED)
482493

483494

484-
class AppContainerViewSet(OwnerViewSet):
495+
class AppContainerViewSet(BaseAppViewSet):
485496
"""RESTful views for :class:`~api.models.Container`."""
486497

487498
model = models.Container
488499
serializer_class = serializers.ContainerSerializer
489500

490501
def get_queryset(self, **kwargs):
491-
app = get_object_or_404(models.App, id=self.kwargs['id'])
492-
qs = self.model.objects.filter(app=app)
502+
qs = super(AppContainerViewSet, self).get_queryset(**kwargs)
493503
container_type = self.kwargs.get('type')
494504
if container_type:
495505
qs = qs.filter(type=container_type)

0 commit comments

Comments
 (0)