github.com/jiasir/deis@v1.12.2/controller/api/tests/test_perm.py (about)

     1  
     2  from __future__ import unicode_literals
     3  import json
     4  
     5  from django.contrib.auth.models import User
     6  from django.test import TestCase
     7  from rest_framework.authtoken.models import Token
     8  
     9  
    10  class TestAdminPerms(TestCase):
    11  
    12      def test_first_signup(self):
    13          # register a first user
    14          username, password = 'firstuser', 'password'
    15          email = 'autotest@deis.io'
    16          submit = {
    17              'username': username,
    18              'password': password,
    19              'email': email,
    20          }
    21          url = '/v1/auth/register'
    22          response = self.client.post(url, json.dumps(submit), content_type='application/json')
    23          self.assertEqual(response.status_code, 201)
    24          self.assertTrue(response.data['is_superuser'])
    25          # register a second user
    26          username, password = 'seconduser', 'password'
    27          email = 'autotest@deis.io'
    28          submit = {
    29              'username': username,
    30              'password': password,
    31              'email': email,
    32          }
    33          url = '/v1/auth/register'
    34          response = self.client.post(url, json.dumps(submit), content_type='application/json')
    35          self.assertEqual(response.status_code, 201)
    36          self.assertFalse(response.data['is_superuser'])
    37  
    38      def test_list(self):
    39          submit = {
    40              'username': 'firstuser',
    41              'password': 'password',
    42              'email': 'autotest@deis.io',
    43          }
    44          url = '/v1/auth/register'
    45          response = self.client.post(url, json.dumps(submit), content_type='application/json')
    46          self.assertEqual(response.status_code, 201)
    47          self.assertTrue(response.data['is_superuser'])
    48          user = User.objects.get(username='firstuser')
    49          token = Token.objects.get(user=user).key
    50          response = self.client.get('/v1/admin/perms', content_type='application/json',
    51                                     HTTP_AUTHORIZATION='token {}'.format(token))
    52          self.assertEqual(response.status_code, 200)
    53          self.assertEqual(len(response.data['results']), 1)
    54          self.assertEqual(response.data['results'][0]['username'], 'firstuser')
    55          self.assertTrue(response.data['results'][0]['is_superuser'])
    56          # register a non-superuser
    57          submit = {
    58              'username': 'seconduser',
    59              'password': 'password',
    60              'email': 'autotest@deis.io',
    61          }
    62          url = '/v1/auth/register'
    63          response = self.client.post(url, json.dumps(submit), content_type='application/json')
    64          self.assertEqual(response.status_code, 201)
    65          self.assertFalse(response.data['is_superuser'])
    66          user = User.objects.get(username='seconduser')
    67          token = Token.objects.get(user=user).key
    68          response = self.client.get('/v1/admin/perms', content_type='application/json',
    69                                     HTTP_AUTHORIZATION='token {}'.format(token))
    70          self.assertEqual(response.status_code, 403)
    71          self.assertIn('You do not have permission', response.data['detail'])
    72  
    73      def test_create(self):
    74          submit = {
    75              'username': 'first',
    76              'password': 'password',
    77              'email': 'autotest@deis.io',
    78          }
    79          url = '/v1/auth/register'
    80          response = self.client.post(url, json.dumps(submit), content_type='application/json')
    81          self.assertEqual(response.status_code, 201)
    82          self.assertTrue(response.data['is_superuser'])
    83          submit = {
    84              'username': 'second',
    85              'password': 'password',
    86              'email': 'autotest@deis.io',
    87          }
    88          url = '/v1/auth/register'
    89          response = self.client.post(url, json.dumps(submit), content_type='application/json')
    90          self.assertEqual(response.status_code, 201)
    91          self.assertFalse(response.data['is_superuser'])
    92          user = User.objects.get(username='first')
    93          token = Token.objects.get(user=user).key
    94          # grant user 2 the superuser perm
    95          url = '/v1/admin/perms'
    96          body = {'username': 'second'}
    97          response = self.client.post(url, json.dumps(body), content_type='application/json',
    98                                      HTTP_AUTHORIZATION='token {}'.format(token))
    99          self.assertEqual(response.status_code, 201)
   100          response = self.client.get(url, HTTP_AUTHORIZATION='token {}'.format(token))
   101          self.assertEqual(response.status_code, 200)
   102          self.assertEqual(len(response.data['results']), 2)
   103          self.assertIn('second', str(response.data['results']))
   104  
   105      def test_delete(self):
   106          submit = {
   107              'username': 'first',
   108              'password': 'password',
   109              'email': 'autotest@deis.io',
   110          }
   111          url = '/v1/auth/register'
   112          response = self.client.post(url, json.dumps(submit), content_type='application/json')
   113          self.assertEqual(response.status_code, 201)
   114          self.assertTrue(response.data['is_superuser'])
   115          submit = {
   116              'username': 'second',
   117              'password': 'password',
   118              'email': 'autotest@deis.io',
   119          }
   120          url = '/v1/auth/register'
   121          response = self.client.post(url, json.dumps(submit), content_type='application/json')
   122          self.assertEqual(response.status_code, 201)
   123          self.assertFalse(response.data['is_superuser'])
   124          user = User.objects.get(username='first')
   125          token = Token.objects.get(user=user).key
   126          # grant user 2 the superuser perm
   127          url = '/v1/admin/perms'
   128          body = {'username': 'second'}
   129          response = self.client.post(url, json.dumps(body), content_type='application/json',
   130                                      HTTP_AUTHORIZATION='token {}'.format(token))
   131          self.assertEqual(response.status_code, 201)
   132          # revoke the superuser perm
   133          response = self.client.delete(url + '/second', HTTP_AUTHORIZATION='token {}'.format(token))
   134          self.assertEqual(response.status_code, 204)
   135          response = self.client.get(url, HTTP_AUTHORIZATION='token {}'.format(token))
   136          self.assertEqual(response.status_code, 200)
   137          self.assertEqual(len(response.data['results']), 1)
   138          self.assertNotIn('two', str(response.data['results']))
   139  
   140  
   141  class TestAppPerms(TestCase):
   142  
   143      fixtures = ['test_sharing.json']
   144  
   145      def setUp(self):
   146          self.user = User.objects.get(username='autotest-1')
   147          self.token = Token.objects.get(user=self.user).key
   148          self.user2 = User.objects.get(username='autotest-2')
   149          self.token2 = Token.objects.get(user=self.user2).key
   150          self.user3 = User.objects.get(username='autotest-3')
   151          self.token3 = Token.objects.get(user=self.user3).key
   152  
   153      def test_create(self):
   154          # check that user 1 sees her lone app and user 2's app
   155          response = self.client.get('/v1/apps', HTTP_AUTHORIZATION='token {}'.format(self.token))
   156          self.assertEqual(response.status_code, 200)
   157          self.assertEqual(len(response.data['results']), 2)
   158          app_id = response.data['results'][0]['id']
   159          # check that user 2 can only see his app
   160          response = self.client.get('/v1/apps', HTTP_AUTHORIZATION='token {}'.format(self.token2))
   161          self.assertEqual(len(response.data['results']), 1)
   162          # check that user 2 can't see any of the app's builds, configs,
   163          # containers, limits, or releases
   164          for model in ['builds', 'config', 'containers', 'releases']:
   165              response = self.client.get("/v1/apps/{}/{}/".format(app_id, model),
   166                                         HTTP_AUTHORIZATION='token {}'.format(self.token2))
   167              msg = "Failed: status '%s', and data '%s'" % (response.status_code, response.data)
   168              self.assertEqual(response.status_code, 403, msg=msg)
   169              self.assertEqual(response.data['detail'],
   170                               'You do not have permission to perform this action.', msg=msg)
   171          # TODO: test that git pushing to the app fails
   172          # give user 2 permission to user 1's app
   173          url = "/v1/apps/{}/perms".format(app_id)
   174          body = {'username': 'autotest-2'}
   175          response = self.client.post(url, json.dumps(body), content_type='application/json',
   176                                      HTTP_AUTHORIZATION='token {}'.format(self.token))
   177          self.assertEqual(response.status_code, 201)
   178          # check that user 2 can see the app
   179          response = self.client.get('/v1/apps', HTTP_AUTHORIZATION='token {}'.format(self.token2))
   180          self.assertEqual(response.status_code, 200)
   181          self.assertEqual(len(response.data['results']), 2)
   182          # check that user 2 sees (empty) results now for builds, containers,
   183          # and releases. (config and limit will still give 404s since we didn't
   184          # push a build here.)
   185          for model in ['builds', 'containers', 'releases']:
   186              response = self.client.get("/v1/apps/{}/{}/".format(app_id, model),
   187                                         HTTP_AUTHORIZATION='token {}'.format(self.token2))
   188              self.assertEqual(len(response.data['results']), 0)
   189          # TODO:  check that user 2 can git push the app
   190  
   191      def test_create_errors(self):
   192          # check that user 1 sees her lone app
   193          response = self.client.get('/v1/apps', HTTP_AUTHORIZATION='token {}'.format(self.token))
   194          app_id = response.data['results'][0]['id']
   195          # check that user 2 can't create a permission
   196          url = "/v1/apps/{}/perms".format(app_id)
   197          body = {'username': 'autotest-2'}
   198          response = self.client.post(url, json.dumps(body), content_type='application/json',
   199                                      HTTP_AUTHORIZATION='token {}'.format(self.token2))
   200          self.assertEqual(response.status_code, 403)
   201  
   202      def test_delete(self):
   203          # give user 2 permission to user 1's app
   204          response = self.client.get('/v1/apps', HTTP_AUTHORIZATION='token {}'.format(self.token))
   205          app_id = response.data['results'][0]['id']
   206          url = "/v1/apps/{}/perms".format(app_id)
   207          body = {'username': 'autotest-2'}
   208          response = self.client.post(url, json.dumps(body), content_type='application/json',
   209                                      HTTP_AUTHORIZATION='token {}'.format(self.token))
   210          self.assertEqual(response.status_code, 201)
   211          # check that user 2 can see the app as well as his own
   212          response = self.client.get('/v1/apps', HTTP_AUTHORIZATION='token {}'.format(self.token2))
   213          self.assertEqual(response.status_code, 200)
   214          self.assertEqual(len(response.data['results']), 2)
   215          # delete permission to user 1's app
   216          url = "/v1/apps/{}/perms/{}".format(app_id, 'autotest-2')
   217          response = self.client.delete(url, content_type='application/json',
   218                                        HTTP_AUTHORIZATION='token {}'.format(self.token))
   219          self.assertEqual(response.status_code, 204)
   220          self.assertIsNone(response.data)
   221          # check that user 2 can only see his app
   222          response = self.client.get('/v1/apps', HTTP_AUTHORIZATION='token {}'.format(self.token2))
   223          self.assertEqual(len(response.data['results']), 1)
   224          # delete permission to user 1's app again, expecting an error
   225          response = self.client.delete(url, content_type='application/json',
   226                                        HTTP_AUTHORIZATION='token {}'.format(self.token))
   227          self.assertEqual(response.status_code, 403)
   228  
   229      def test_list(self):
   230          # check that user 1 sees her lone app and user 2's app
   231          response = self.client.get('/v1/apps', HTTP_AUTHORIZATION='token {}'.format(self.token))
   232          self.assertEqual(response.status_code, 200)
   233          self.assertEqual(len(response.data['results']), 2)
   234          app_id = response.data['results'][0]['id']
   235          # create a new object permission
   236          url = "/v1/apps/{}/perms".format(app_id)
   237          body = {'username': 'autotest-2'}
   238          response = self.client.post(url, json.dumps(body), content_type='application/json',
   239                                      HTTP_AUTHORIZATION='token {}'.format(self.token))
   240          self.assertEqual(response.status_code, 201)
   241          # list perms on the app
   242          response = self.client.get(
   243              "/v1/apps/{}/perms".format(app_id), content_type='application/json',
   244              HTTP_AUTHORIZATION='token {}'.format(self.token))
   245          self.assertEqual(response.data, {'users': ['autotest-2']})
   246  
   247      def test_admin_can_list(self):
   248          """Check that an administrator can list an app's perms"""
   249          response = self.client.get('/v1/apps', HTTP_AUTHORIZATION='token {}'.format(self.token))
   250          self.assertEqual(response.status_code, 200)
   251          self.assertEqual(len(response.data['results']), 2)
   252  
   253      def test_list_errors(self):
   254          response = self.client.get('/v1/apps', HTTP_AUTHORIZATION='token {}'.format(self.token))
   255          app_id = response.data['results'][0]['id']
   256          # login as user 2, list perms on the app
   257          response = self.client.get(
   258              "/v1/apps/{}/perms".format(app_id), content_type='application/json',
   259              HTTP_AUTHORIZATION='token {}'.format(self.token2))
   260          self.assertEqual(response.status_code, 403)
   261  
   262      def test_unauthorized_user_cannot_modify_perms(self):
   263          """
   264          An unauthorized user should not be able to modify other apps' permissions.
   265  
   266          Since an unauthorized user should not know about the application at all, these
   267          requests should return a 404.
   268          """
   269          app_id = 'autotest'
   270          url = '/v1/apps'
   271          body = {'id': app_id}
   272          response = self.client.post(url, json.dumps(body), content_type='application/json',
   273                                      HTTP_AUTHORIZATION='token {}'.format(self.token))
   274          unauthorized_user = self.user2
   275          unauthorized_token = self.token2
   276          url = '{}/{}/perms'.format(url, app_id)
   277          body = {'username': unauthorized_user.username}
   278          response = self.client.post(url, json.dumps(body), content_type='application/json',
   279                                      HTTP_AUTHORIZATION='token {}'.format(unauthorized_token))
   280          self.assertEqual(response.status_code, 403)
   281  
   282      def test_collaborator_cannot_share(self):
   283          """
   284          An collaborator should not be able to modify the app's permissions.
   285          """
   286          app_id = "autotest-1-app"
   287          owner_token = self.token
   288          collab = self.user2
   289          collab_token = self.token2
   290          url = '/v1/apps/{}/perms'.format(app_id)
   291          # Share app with collaborator
   292          body = {'username': collab.username}
   293          response = self.client.post(url, json.dumps(body), content_type='application/json',
   294                                      HTTP_AUTHORIZATION='token {}'.format(owner_token))
   295          self.assertEqual(response.status_code, 201)
   296          # Collaborator should fail to share app
   297          body = {'username': self.user3.username}
   298          response = self.client.post(url, json.dumps(body), content_type='application/json',
   299                                      HTTP_AUTHORIZATION='token {}'.format(collab_token))
   300          self.assertEqual(response.status_code, 403)
   301          # Collaborator can list
   302          response = self.client.get(url, content_type='application/json',
   303                                     HTTP_AUTHORIZATION='token {}'.format(collab_token))
   304          self.assertEqual(response.status_code, 200)
   305          # Share app with user 3 for rest of tests
   306          response = self.client.post(url, json.dumps(body), content_type='application/json',
   307                                      HTTP_AUTHORIZATION='token {}'.format(owner_token))
   308          self.assertEqual(response.status_code, 201)
   309          response = self.client.get(url, content_type='application/json',
   310                                     HTTP_AUTHORIZATION='token {}'.format(collab_token))
   311          self.assertEqual(response.status_code, 200)
   312          # Collaborator cannot delete other collaborator
   313          url += "/{}".format(self.user3.username)
   314          response = self.client.delete(url, HTTP_AUTHORIZATION='token {}'.format(collab_token))
   315          self.assertEqual(response.status_code, 403)
   316          # Collaborator can delete themselves
   317          url = '/v1/apps/{}/perms/{}'.format(app_id, collab.username)
   318          response = self.client.delete(url, HTTP_AUTHORIZATION='token {}'.format(collab_token))
   319          self.assertEqual(response.status_code, 204)