Skip to content
This repository was archived by the owner on May 6, 2020. It is now read-only.

Commit ffeb14a

Browse files
author
Matthew Fisher
authored
fix(api): ensure a 409 is raised when cancelling a user with downstream objects (#1147)
1 parent 4dd1a6c commit ffeb14a

2 files changed

Lines changed: 20 additions & 3 deletions

File tree

rootfs/api/tests/test_auth.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
from django.contrib.auth.models import User
77
from django.test.utils import override_settings
88
from rest_framework.authtoken.models import Token
9-
from api.tests import DeisTestCase
9+
from api.tests import TEST_ROOT, DeisTestCase
10+
from api.models import Certificate
1011

1112

1213
class AuthTest(DeisTestCase):
@@ -242,6 +243,18 @@ def test_cancel(self):
242243
HTTP_AUTHORIZATION='token {}'.format(self.admin_token))
243244
self.assertEqual(response.status_code, 409)
244245

246+
# user can not be deleted if it has a downstream object owned by them, like a certificate
247+
domain_name = 'foo.com'
248+
with open('{}/certs/{}.key'.format(TEST_ROOT, domain_name)) as f:
249+
key = f.read()
250+
with open('{}/certs/{}.cert'.format(TEST_ROOT, domain_name)) as f:
251+
cert = f.read()
252+
253+
Certificate.objects.create(owner=self.admin, certificate=cert, key=key)
254+
response = self.client.delete(url, {'username': str(self.admin)},
255+
HTTP_AUTHORIZATION='token {}'.format(self.admin_token))
256+
self.assertEqual(response.status_code, 409, response.data)
257+
245258
def test_passwd(self):
246259
"""Test that a registered user can change the password."""
247260
# test registration workflow

rootfs/api/views.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from guardian.shortcuts import assign_perm, get_objects_for_user, \
99
get_users_with_perms, remove_perm
1010
from django.views.generic import View
11+
from django.db.models.deletion import ProtectedError
1112
from rest_framework import mixins, renderers, status
1213
from rest_framework.exceptions import PermissionDenied, NotFound, AuthenticationFailed
1314
from rest_framework.permissions import IsAuthenticated
@@ -89,8 +90,11 @@ def destroy(self, request, **kwargs):
8990
msg = '{} still has applications assigned. Delete or transfer ownership'.format(str(target_obj)) # noqa
9091
raise AlreadyExists(msg)
9192

92-
target_obj.delete()
93-
return Response(status=status.HTTP_204_NO_CONTENT)
93+
try:
94+
target_obj.delete()
95+
return Response(status=status.HTTP_204_NO_CONTENT)
96+
except ProtectedError as e:
97+
raise AlreadyExists(e)
9498

9599
def passwd(self, request, **kwargs):
96100
if not request.data.get('new_password'):

0 commit comments

Comments
 (0)