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)