Skip to content

Commit 8113664

Browse files
author
Matthew Fisher
committed
test(controller): verify that admins are gods
1 parent d5e8926 commit 8113664

11 files changed

Lines changed: 235 additions & 26 deletions

File tree

controller/api/fixtures/test_sharing.json

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
"first_name": "",
2626
"last_name": "",
2727
"is_active": true,
28-
"is_superuser": false,
29-
"is_staff": false,
28+
"is_superuser": true,
29+
"is_staff": true,
3030
"last_login": "2013-11-25T21:58:47.420Z",
3131
"groups": [],
3232
"user_permissions": [],
@@ -77,5 +77,16 @@
7777
"owner": 2,
7878
"id": "autotest-1-app"
7979
}
80+
},
81+
{
82+
"pk": "5a09a1e0-a27e-4839-928b-449310ed90f1",
83+
"model": "api.app",
84+
"fields": {
85+
"updated": "2013-11-25T22:09:36.726Z",
86+
"created": "2013-11-25T22:09:36.726Z",
87+
"cluster": "80e9db5a-d394-41c7-b153-3ea0314dc8ca",
88+
"owner": 3,
89+
"id": "autotest-2-app"
90+
}
8091
}
8192
]

controller/api/permissions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from rest_framework import permissions
22
from django.conf import settings
3-
from django.contrib.auth.models import AnonymousUser, User
3+
from django.contrib.auth.models import AnonymousUser
44

55
from api import models
66

controller/api/tests/test_app.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ def test_app_actions(self):
9090
response = self.client.post(url)
9191
self.assertEqual(response.status_code, 200)
9292
self.assertEqual(response.data, FAKE_LOG_DATA)
93+
os.remove(path)
9394
# test run
9495
url = '/api/apps/{app_id}/run'.format(**locals())
9596
body = {'command': 'ls -al'}
@@ -136,6 +137,55 @@ def test_app_errors(self):
136137
response = self.client.get(url)
137138
self.assertEquals(response.status_code, 404)
138139

140+
def test_admin_can_manage_other_apps(self):
141+
"""Administrators of Deis should be able to manage all applications.
142+
"""
143+
# log in as non-admin user and create an app
144+
self.assertTrue(
145+
self.client.login(username='autotest2', password='password'))
146+
app_id = 'autotest'
147+
url = '/api/apps'
148+
body = {'cluster': 'autotest', 'id': app_id}
149+
response = self.client.post(url, json.dumps(body), content_type='application/json')
150+
# log in as admin, check to see if they have access
151+
self.assertTrue(
152+
self.client.login(username='autotest', password='password'))
153+
url = '/api/apps/{}'.format(app_id)
154+
response = self.client.get(url)
155+
self.assertEqual(response.status_code, 200)
156+
# check app logs
157+
url = '/api/apps/{app_id}/logs'.format(**locals())
158+
response = self.client.post(url)
159+
self.assertEqual(response.status_code, 200)
160+
self.assertIn('autotest2 created initial release', response.data)
161+
# run one-off commands
162+
url = '/api/apps/{app_id}/run'.format(**locals())
163+
body = {'command': 'ls -al'}
164+
response = self.client.post(url, json.dumps(body), content_type='application/json')
165+
self.assertEqual(response.status_code, 200)
166+
self.assertEqual(response.data[0], 0)
167+
# delete the app
168+
url = '/api/apps/{}'.format(app_id)
169+
response = self.client.delete(url)
170+
self.assertEqual(response.status_code, 204)
171+
172+
def test_admin_can_see_other_apps(self):
173+
"""If a user creates an application, the administrator should be able
174+
to see it.
175+
"""
176+
# log in as non-admin user and create an app
177+
self.assertTrue(
178+
self.client.login(username='autotest2', password='password'))
179+
app_id = 'autotest'
180+
url = '/api/apps'
181+
body = {'cluster': 'autotest', 'id': app_id}
182+
response = self.client.post(url, json.dumps(body), content_type='application/json')
183+
# log in as admin
184+
self.assertTrue(
185+
self.client.login(username='autotest', password='password'))
186+
response = self.client.get(url)
187+
self.assertEqual(response.data['count'], 1)
188+
139189

140190
FAKE_LOG_DATA = """
141191
2013-08-15 12:41:25 [33454] [INFO] Starting gunicorn 17.5

controller/api/tests/test_build.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,3 +179,25 @@ def test_build_str(self):
179179
build = Build.objects.get(uuid=response.data['uuid'])
180180
self.assertEqual(str(build), "{}-{}".format(
181181
response.data['app'], response.data['uuid'][:7]))
182+
183+
@mock.patch('requests.post', mock_import_repository_task)
184+
def test_admin_can_create_builds_on_other_apps(self):
185+
"""If a user creates an application, an administrator should be able
186+
to push builds.
187+
"""
188+
# create app as non-admin
189+
self.client.login(username='autotest2', password='password')
190+
url = '/api/apps'
191+
body = {'cluster': 'autotest'}
192+
response = self.client.post(url, json.dumps(body), content_type='application/json')
193+
self.assertEqual(response.status_code, 201)
194+
app_id = response.data['id']
195+
# post a new build as admin
196+
self.client.login(username='autotest', password='password')
197+
url = "/api/apps/{app_id}/builds".format(**locals())
198+
body = {'image': 'autotest/example'}
199+
response = self.client.post(url, json.dumps(body), content_type='application/json')
200+
self.assertEqual(response.status_code, 201)
201+
build = Build.objects.get(uuid=response.data['uuid'])
202+
self.assertEqual(str(build), "{}-{}".format(
203+
response.data['app'], response.data['uuid'][:7]))

controller/api/tests/test_config.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,25 @@ def test_config_str(self):
134134
config = Config.objects.get(uuid=config5['uuid'])
135135
self.assertEqual(str(config), "{}-{}".format(config5['app'], config5['uuid'][:7]))
136136

137+
@mock.patch('requests.post', mock_import_repository_task)
138+
def test_admin_can_create_config_on_other_apps(self):
139+
"""If a non-admin creates an app, an administrator should be able to set config
140+
values for that app.
141+
"""
142+
self.client.login(username='autotest2', password='password')
143+
url = '/api/apps'
144+
body = {'cluster': 'autotest'}
145+
response = self.client.post(url, json.dumps(body), content_type='application/json')
146+
self.assertEqual(response.status_code, 201)
147+
app_id = response.data['id']
148+
self.client.login(username='autotest', password='password')
149+
url = "/api/apps/{app_id}/config".format(**locals())
150+
# set an initial config value
151+
body = {'values': json.dumps({'PORT': '5000'})}
152+
response = self.client.post(url, json.dumps(body), content_type='application/json')
153+
self.assertEqual(response.status_code, 201)
154+
self.assertIn('PORT', json.loads(response.data['values']))
155+
137156
@mock.patch('requests.post', mock_import_repository_task)
138157
def test_limit_memory(self):
139158
"""
@@ -348,4 +367,3 @@ def test_tags(self):
348367
self.assertEqual(self.client.put(url).status_code, 405)
349368
self.assertEqual(self.client.patch(url).status_code, 405)
350369
self.assertEqual(self.client.delete(url).status_code, 405)
351-
return tags4

controller/api/tests/test_container.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,3 +400,27 @@ def test_container_scale_errors(self):
400400
body = {'web': 1}
401401
response = self.client.post(url, json.dumps(body), content_type='application/json')
402402
self.assertEqual(response.status_code, 204)
403+
404+
def test_admin_can_manage_other_containers(self):
405+
"""If a non-admin user creates a container, an administrator should be able to
406+
manage it.
407+
"""
408+
self.client.login(username='autotest2', password='password')
409+
url = '/api/apps'
410+
body = {'cluster': 'autotest'}
411+
response = self.client.post(url, json.dumps(body), content_type='application/json')
412+
self.assertEqual(response.status_code, 201)
413+
app_id = response.data['id']
414+
# post a new build
415+
url = "/api/apps/{app_id}/builds".format(**locals())
416+
body = {'image': 'autotest/example', 'sha': 'a'*40,
417+
'procfile': json.dumps({'web': 'node server.js', 'worker': 'node worker.js'})}
418+
response = self.client.post(url, json.dumps(body), content_type='application/json')
419+
self.assertEqual(response.status_code, 201)
420+
# login as admin
421+
self.client.login(username='autotest', password='password')
422+
# scale up
423+
url = "/api/apps/{app_id}/scale".format(**locals())
424+
body = {'web': 4, 'worker': 2}
425+
response = self.client.post(url, json.dumps(body), content_type='application/json')
426+
self.assertEqual(response.status_code, 204)

controller/api/tests/test_domain.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,23 @@ def test_manage_domain_invalid_domain(self):
8989
self.assertEqual(response.status_code, 400)
9090

9191
def test_manage_domain_wildcard(self):
92-
# Wildcards are not allowed for now.
92+
"""Wildcards are not allowed for now."""
9393
url = '/api/apps/{app_id}/domains'.format(app_id=self.app_id)
9494
body = {'domain': '*.deis.example.com'}
9595
response = self.client.post(url, json.dumps(body), content_type='application/json')
9696
self.assertEqual(response.status_code, 400)
97+
98+
def test_admin_can_add_domains_to_other_apps(self):
99+
"""If a non-admin user creates an app, an administrator should be able to add
100+
domains to it.
101+
"""
102+
self.client.login(username='autotest2', password='password')
103+
url = '/api/apps'
104+
body = {'cluster': 'autotest'}
105+
response = self.client.post(url, json.dumps(body), content_type='application/json')
106+
self.assertEqual(response.status_code, 201)
107+
self.client.login(username='autotest', password='password')
108+
url = '/api/apps/{}/domains'.format(self.app_id)
109+
body = {'domain': 'example.deis.example.com'}
110+
response = self.client.post(url, json.dumps(body), content_type='application/json')
111+
self.assertEqual(response.status_code, 201)

controller/api/tests/test_hooks.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,3 +251,30 @@ def test_config_hook(self):
251251
self.assertEqual(response.status_code, 200)
252252
self.assertIn('values', response.data)
253253
self.assertEqual(values, response.data['values'])
254+
255+
def test_admin_can_hook(self):
256+
"""Administrator should be able to create build hooks on non-admin apps.
257+
"""
258+
"""Test creating a Push via the API"""
259+
self.client.login(username='autotest2', password='password')
260+
url = '/api/apps'
261+
body = {'cluster': 'autotest'}
262+
response = self.client.post(url, json.dumps(body), content_type='application/json')
263+
self.assertEqual(response.status_code, 201)
264+
app_id = response.data['id']
265+
self.client.login(username='autotest', password='password')
266+
# prepare a push body
267+
DOCKERFILE = """
268+
FROM busybox
269+
CMD /bin/true
270+
"""
271+
body = {'receive_user': 'autotest',
272+
'receive_repo': app_id,
273+
'image': '{app_id}:v2'.format(**locals()),
274+
'sha': 'ecdff91c57a0b9ab82e89634df87e293d259a3aa',
275+
'dockerfile': DOCKERFILE}
276+
url = '/api/hooks/builds'
277+
response = self.client.post(url, json.dumps(body), content_type='application/json',
278+
HTTP_X_DEIS_BUILDER_AUTH=settings.BUILDER_KEY)
279+
self.assertEqual(response.status_code, 200)
280+
self.assertEqual(response.data['release']['version'], 2)

controller/api/tests/test_perm.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -144,16 +144,16 @@ def setUp(self):
144144
self.client.login(username='autotest-1', password='password'))
145145

146146
def test_create(self):
147-
# check that user 1 sees her lone app
147+
# check that user 1 sees her lone app and user 2's app
148148
response = self.client.get('/api/apps')
149149
self.assertEqual(response.status_code, 200)
150-
self.assertEqual(len(response.data['results']), 1)
150+
self.assertEqual(len(response.data['results']), 2)
151151
app_id = response.data['results'][0]['id']
152-
# check that user 2 can't see any apps
152+
# check that user 2 can only see his app
153153
self.assertTrue(
154154
self.client.login(username='autotest-2', password='password'))
155155
response = self.client.get('/api/apps')
156-
self.assertEqual(len(response.data['results']), 0)
156+
self.assertEqual(len(response.data['results']), 1)
157157
# check that user 2 can't see any of the app's builds, configs,
158158
# containers, limits, or releases
159159
for model in ['builds', 'config', 'containers', 'limits', 'releases']:
@@ -172,7 +172,7 @@ def test_create(self):
172172
self.client.login(username='autotest-2', password='password'))
173173
response = self.client.get('/api/apps')
174174
self.assertEqual(response.status_code, 200)
175-
self.assertEqual(len(response.data['results']), 1)
175+
self.assertEqual(len(response.data['results']), 2)
176176
# check that user 2 sees (empty) results now for builds, containers,
177177
# and releases. (config and limit will still give 404s since we didn't
178178
# push a build here.)
@@ -203,12 +203,12 @@ def test_delete(self):
203203
body = {'username': 'autotest-2'}
204204
response = self.client.post(url, json.dumps(body), content_type='application/json')
205205
self.assertEqual(response.status_code, 201)
206-
# check that user 2 can see the app
206+
# check that user 2 can see the app as well as his own
207207
self.assertTrue(
208208
self.client.login(username='autotest-2', password='password'))
209209
response = self.client.get('/api/apps')
210210
self.assertEqual(response.status_code, 200)
211-
self.assertEqual(len(response.data['results']), 1)
211+
self.assertEqual(len(response.data['results']), 2)
212212
# try to delete the permission as user 2
213213
url = "/api/apps/{}/perms/{}".format(app_id, 'autotest-2')
214214
response = self.client.delete(url, content_type='application/json')
@@ -220,22 +220,22 @@ def test_delete(self):
220220
response = self.client.delete(url, content_type='application/json')
221221
self.assertEqual(response.status_code, 204)
222222
self.assertIsNone(response.data)
223-
# check that user 2 can't see any apps
223+
# check that user 2 can only see his app
224224
self.assertTrue(
225225
self.client.login(username='autotest-2', password='password'))
226226
response = self.client.get('/api/apps')
227-
self.assertEqual(len(response.data['results']), 0)
227+
self.assertEqual(len(response.data['results']), 1)
228228
# delete permission to user 1's app again, expecting an error
229229
self.assertTrue(
230230
self.client.login(username='autotest-1', password='password'))
231231
response = self.client.delete(url, content_type='application/json')
232232
self.assertEqual(response.status_code, 404)
233233

234234
def test_list(self):
235-
# check that user 1 sees her lone app
235+
# check that user 1 sees her lone app and user 2's app
236236
response = self.client.get('/api/apps')
237237
self.assertEqual(response.status_code, 200)
238-
self.assertEqual(len(response.data['results']), 1)
238+
self.assertEqual(len(response.data['results']), 2)
239239
app_id = response.data['results'][0]['id']
240240
# create a new object permission
241241
url = "/api/apps/{}/perms".format(app_id)
@@ -247,6 +247,12 @@ def test_list(self):
247247
"/api/apps/{}/perms".format(app_id), content_type='application/json')
248248
self.assertEqual(response.data, {'users': ['autotest-2']})
249249

250+
def test_admin_can_list(self):
251+
"""Check that an administrator can list an app's perms"""
252+
response = self.client.get('/api/apps')
253+
self.assertEqual(response.status_code, 200)
254+
self.assertEqual(len(response.data['results']), 2)
255+
250256
def test_list_errors(self):
251257
response = self.client.get('/api/apps')
252258
app_id = response.data['results'][0]['id']

controller/api/tests/test_release.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,3 +213,27 @@ def test_release_summary(self):
213213
release = Release.objects.get(uuid=release3['uuid'])
214214
# check that the release has push and env change messages
215215
self.assertIn('autotest deployed ', release.summary)
216+
217+
@mock.patch('requests.post', mock_import_repository_task)
218+
def test_admin_can_create_release(self):
219+
"""If a non-user creates an app, an admin should be able to create releases."""
220+
self.client.login(username='autotest2', password='password')
221+
url = '/api/apps'
222+
body = {'cluster': 'autotest'}
223+
response = self.client.post(url, json.dumps(body), content_type='application/json')
224+
self.assertEqual(response.status_code, 201)
225+
app_id = response.data['id']
226+
self.client.login(username='autotest', password='password')
227+
# check that updating config rolls a new release
228+
url = '/api/apps/{app_id}/config'.format(**locals())
229+
body = {'values': json.dumps({'NEW_URL1': 'http://localhost:8080/'})}
230+
response = self.client.post(
231+
url, json.dumps(body), content_type='application/json')
232+
self.assertEqual(response.status_code, 201)
233+
self.assertIn('NEW_URL1', json.loads(response.data['values']))
234+
# check to see that an initial release was created
235+
url = '/api/apps/{app_id}/releases'.format(**locals())
236+
response = self.client.get(url)
237+
self.assertEqual(response.status_code, 200)
238+
# account for the config release as well
239+
self.assertEqual(response.data['count'], 2)

0 commit comments

Comments
 (0)