Skip to content

Commit 490e8e0

Browse files
committed
Implemented app, formation, superuser sharing permissions.
1 parent ddbcf73 commit 490e8e0

14 files changed

Lines changed: 665 additions & 15 deletions

api/admin.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from __future__ import unicode_literals
99

1010
from django.contrib import admin
11+
from guardian.admin import GuardedModelAdmin
1112

1213
from .models import App
1314
from .models import Build
@@ -22,7 +23,7 @@
2223
from .models import Release
2324

2425

25-
class AppAdmin(admin.ModelAdmin):
26+
class AppAdmin(GuardedModelAdmin):
2627
"""Set presentation options for :class:`~api.models.App` models
2728
in the Django admin.
2829
"""
@@ -72,7 +73,7 @@ class FlavorAdmin(admin.ModelAdmin):
7273
admin.site.register(Flavor, FlavorAdmin)
7374

7475

75-
class FormationAdmin(admin.ModelAdmin):
76+
class FormationAdmin(GuardedModelAdmin):
7677
"""Set presentation options for :class:`~api.models.Formation` models
7778
in the Django admin.
7879
"""

api/fixtures/test_auth.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[
2+
{
3+
"pk": 7,
4+
"model": "auth.user",
5+
"fields": {
6+
"username": "autotest",
7+
"first_name": "Otto",
8+
"last_name": "Test",
9+
"is_active": true,
10+
"is_superuser": true,
11+
"is_staff": true,
12+
"last_login": "2013-05-10T16:08:09.357Z",
13+
"groups": [],
14+
"user_permissions": [],
15+
"password": "pbkdf2_sha256$10000$5Uoq7dl61vnN$gQhDpc2q2Rkn16VdPC+pNNEQcKpy+LGe29Zkad+2/m4=",
16+
"email": "autotest@opdemand.com",
17+
"date_joined": "2013-05-10T16:08:09.357Z"
18+
}
19+
}
20+
]

api/fixtures/test_sharing.json

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
[
2+
{
3+
"pk": -1,
4+
"model": "auth.user",
5+
"fields": {
6+
"username": "AnonymousUser",
7+
"first_name": "",
8+
"last_name": "",
9+
"is_active": true,
10+
"is_superuser": false,
11+
"is_staff": false,
12+
"last_login": "2013-11-25T21:33:19.120Z",
13+
"groups": [],
14+
"user_permissions": [],
15+
"password": "",
16+
"email": "",
17+
"date_joined": "2013-11-25T21:33:19.120Z"
18+
}
19+
},
20+
{
21+
"pk": 2,
22+
"model": "auth.user",
23+
"fields": {
24+
"username": "autotest-1",
25+
"first_name": "",
26+
"last_name": "",
27+
"is_active": true,
28+
"is_superuser": false,
29+
"is_staff": false,
30+
"last_login": "2013-11-25T21:58:47.420Z",
31+
"groups": [],
32+
"user_permissions": [],
33+
"password": "pbkdf2_sha256$10000$SLr4X1T9L3QA$NB4d4a0d+3NZuAwLbdnKGb2z3P/hQrKQHVaGG3zAaMw=",
34+
"email": "autotest@opdemand.com",
35+
"date_joined": "2013-11-25T21:58:46.208Z"
36+
}
37+
},
38+
{
39+
"pk": 3,
40+
"model": "auth.user",
41+
"fields": {
42+
"username": "autotest-2",
43+
"first_name": "",
44+
"last_name": "",
45+
"is_active": true,
46+
"is_superuser": false,
47+
"is_staff": false,
48+
"last_login": "2013-11-25T21:59:31.404Z",
49+
"groups": [],
50+
"user_permissions": [],
51+
"password": "pbkdf2_sha256$10000$FrfwTVAtWPMD$HUfDokMeY37YshdyS3uhDZ+d/r8galU7kNuBfZxJl2s=",
52+
"email": "autotest@opdemand.com",
53+
"date_joined": "2013-11-25T21:59:30.760Z"
54+
}
55+
},
56+
{
57+
"pk": "3daa9d07-d6b8-40c2-869d-792e2438140d",
58+
"model": "api.flavor",
59+
"fields": {
60+
"updated": "2013-11-25T21:58:46.672Z",
61+
"created": "2013-11-25T21:58:46.671Z",
62+
"params": "{}",
63+
"provider": "d879d3c5-1953-4b1e-92ef-e14ab3d52cf8",
64+
"owner": 2,
65+
"id": "mock-west"
66+
}
67+
},
68+
{
69+
"pk": "79121781-9cbb-4300-94ac-59131a0bc487",
70+
"model": "api.flavor",
71+
"fields": {
72+
"updated": "2013-11-25T21:59:31.237Z",
73+
"created": "2013-11-25T21:59:31.237Z",
74+
"params": "{}",
75+
"provider": "1f251c8b-c72b-4616-9c92-126890bf1567",
76+
"owner": 3,
77+
"id": "mock-west"
78+
}
79+
},
80+
{
81+
"pk": "1f251c8b-c72b-4616-9c92-126890bf1567",
82+
"model": "api.provider",
83+
"fields": {
84+
"updated": "2013-11-25T21:59:31.227Z",
85+
"created": "2013-11-25T21:59:31.227Z",
86+
"owner": 3,
87+
"type": "mock",
88+
"id": "mock",
89+
"creds": "{}"
90+
}
91+
},
92+
{
93+
"pk": "d879d3c5-1953-4b1e-92ef-e14ab3d52cf8",
94+
"model": "api.provider",
95+
"fields": {
96+
"updated": "2013-11-25T21:58:46.658Z",
97+
"created": "2013-11-25T21:58:46.658Z",
98+
"owner": 2,
99+
"type": "mock",
100+
"id": "mock",
101+
"creds": "{}"
102+
}
103+
},
104+
{
105+
"pk": "f74ab47c-d20e-4cb5-893a-9bcda9f40f08",
106+
"model": "api.layer",
107+
"fields": {
108+
"updated": "2013-11-25T22:09:38.150Z",
109+
"created": "2013-11-25T22:09:38.150Z",
110+
"ssh_port": 22,
111+
"ssh_username": "ubuntu",
112+
"formation": "2345a3e0-867e-4839-928b-449380dd99f7",
113+
"proxy": true,
114+
"owner": 2,
115+
"ssh_public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDUnuepSvLVxC1XUbZE2LAMdu4tqOSJFx9aZ2HMY7xmeYovHVUFOb8+AGgwhOfHuAh7E1N3dB4/HbbUoO/l6eyU6RHiQn7eq0OltaGn1WgGLNSjDRZwf/4MoFAKGZr3BUGQ6cN9O65K8FsnK0urQTRoTmA5m/QtFGBC9AJLu1/XWIYs/IHs/HrVWecsAMdM/6ulgdrsosammhkv89mfBSJHY5Wuy1Eg1EArG/cv5Bi0LRDuzz3j1sASKZIug82N5QfVZ4xRPz0ZEpotFOAu7KC4r078XQakBH+arphTunyScTZO30ysak2SACBT9kprbIW8FXwf23e19ygAFDo8l1/J",
116+
"flavor": "3daa9d07-d6b8-40c2-869d-792e2438140d",
117+
"runtime": true,
118+
"config": "{}",
119+
"id": "runtime",
120+
"ssh_private_key": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEA1J7nqUry1cQtV1G2RNiwDHbuLajkiRcfWmdhzGO8ZnmKLx1V\nBTm/PgBoMITnx7gIexNTd3QePx221KDv5enslOkR4kJ+3qtDpbWhp9VoBizUow0W\ncH/+DKBQChma9wVBkOnDfTuuSvBbJytLq0E0aE5gOZv0LRRgQvQCS7tf11iGLPyB\n7Px61VnnLADHTP+rpYHa7KLGppoZL/PZnwUiR2OVrstRINRAKxv3L+QYtC0Q7s89\n49bAEimSLoPNjeUH1WeMUT89GRKaLRTgLuyguK9O/F0GpAR/mq6YU7p8knE2Tt9M\nrGpNkgAgU/ZKa2yFvBV8H9t3tfcoABQ6PJdfyQIDAQABAoIBADZuwAwdPfHwGVOD\nfdA+UUO/ptZVqLxYCRTR5r22wuLRNsk9DykZUZaD8CiLvfLpcHJhzjqEpcGuz8G7\nue74ZjLxQDzWnThQTC8+QrZ+8fSywXVEwnvmqJl+6T7Ms1mOJOz+i6eiAcr5obxz\nXxnmxY32krfs7yQjVUmOwo+01qKAdadfnOoOCLTGc/UG7IEsutjtu18x7nkvDs0s\nj12t/osJ8OBWXpwbitYYxSUkVPrivyvO8W5yvKPRpsSrSD7yDLr1SHNp1OHqZbed\nDZJHx8eXdZxmthxRW4Vb8H2nDRZznpUs3VDuevghaD5VmoLgeYf15ogtoMApqjaw\ncXF5MckCgYEA3QJz7jWKWQ3774FWDT6Q8kHoJdYDEr4k6S545v9pHt0H0YeN2AGG\nOBmDIca5CBN37nwT0UR8eXZYxLw6RaEiF1VC7Ld6j4L9k3USYVCYJm/epESh+b8X\nm1MrKbqzc7auJF647VQ/1DmdZ68l+df8D0i5m28w2vJ69sDSPARUe38CgYEA9khz\nVVi9X4f3ore24R2UiIm0zRcnOuT8b3IAyIm9NiXnQcDmhKZtkiEa74DjIvMLV4Hd\nzA5GupeRxxgceaPK+Fu8sccUmGlyr5hSfahyx3/4KrwuXPPyiid6zFl/9XUvuOkM\nTdyb70AWypdbwrrCdBBP6GjUOOMvYKIevq+46LcCgYAS09Wqclcx1PYkZiE9iZnx\neVncd0nVu+sLDlFwZEvBPFUhLWoQ/7g+aTX5l6NFo9rwrxNFHY95DXLsd5iDPAHa\neQH1hn/jX+ZYPH3vWl1L0PXnio096GCLc99Wc7g74FEfeg5I8YdqfeoB3jLfAN5R\nMwHU0vkXfdap1K1UPY4w4wKBgGwFgRi5EG67S2GCZOM+PyzYAYZHFnzdfN9AyJks\n2OHMJC+R9UnPWZXTkWXlSTrGEX5zRp4+0MT8wALsT2kG73qZeh0bravf7F6aV+wn\nmxhnx6iu20MH+KSiBlllFBvMJ39aMHxiO77nhFedpbC2i52une3ZNOQyuVAQK54F\novvnAoGBAKqCEF0HCEmDIMyWy4dZhwA+9+I6q1hmXVuVZxSk1iTO7S4rKT590jAl\nWcRw/kS3rdrmLZvoBYnIOUJk356TCVNOVDwp3CXmD9/P/GIXzhWQtScZdBd91ekU\n4h+84S5yGdaF3SEJz1+UIdlh1lWxndBVyFucuSI0RF/FOB9jK7iE\n-----END RSA PRIVATE KEY-----"
121+
}
122+
},
123+
{
124+
"pk": "2345a3e0-867e-4839-928b-449380dd99f7",
125+
"model": "api.formation",
126+
"fields": {
127+
"updated": "2013-11-25T22:09:36.726Z",
128+
"created": "2013-11-25T22:09:36.726Z",
129+
"domain": null,
130+
"owner": 2,
131+
"nodes": "{}",
132+
"id": "autotest-1"
133+
}
134+
},
135+
{
136+
"pk": "5a09a1e0-a27e-4839-928b-449310ed90f0",
137+
"model": "api.app",
138+
"fields": {
139+
"updated": "2013-11-25T22:09:36.726Z",
140+
"created": "2013-11-25T22:09:36.726Z",
141+
"formation": "2345a3e0-867e-4839-928b-449380dd99f7",
142+
"owner": 2,
143+
"containers": "{}",
144+
"id": "autotest-1-app"
145+
}
146+
}
147+
]

api/models.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ class Formation(UuidAuditedModel):
174174
nodes = JSONField(default='{}', blank=True)
175175

176176
class Meta:
177+
permissions = (('use_formation', 'Can use formation'),)
177178
unique_together = (('owner', 'id'),)
178179

179180
def __str__(self):
@@ -456,9 +457,11 @@ class App(UuidAuditedModel):
456457
owner = models.ForeignKey(settings.AUTH_USER_MODEL)
457458
id = models.SlugField(max_length=64, unique=True)
458459
formation = models.ForeignKey('Formation')
459-
460460
containers = JSONField(default='{}', blank=True)
461461

462+
class Meta:
463+
permissions = (('use_app', 'Can use app'),)
464+
462465
def __str__(self):
463466
return self.id
464467

api/serializers.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,15 @@ def data(self):
4444
return d
4545

4646

47+
class AdminUserSerializer(serializers.ModelSerializer):
48+
"""Serialize admin status for a :class:`~api.models.User` model."""
49+
50+
class Meta:
51+
model = User
52+
fields = ('username', 'is_superuser')
53+
read_only_fields = ('username', )
54+
55+
4756
class KeySerializer(serializers.ModelSerializer):
4857
"""Serialize a :class:`~api.models.Key` model."""
4958

api/tests/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,6 @@ def send_patch(self, path, data='', content_type='application/octet-stream',
3737
from .test_key import * # noqa
3838
from .test_layer import * # noqa
3939
from .test_node import * # noqa
40+
from .test_perm import * # noqa
4041
from .test_provider import * # noqa
4142
from .test_release import * # noqa

api/tests/test_auth.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
class AuthTest(TestCase):
1717

18+
fixtures = ['test_auth.json']
19+
1820
"""Tests user registration, authentication and authorization"""
1921

2022
def test_auth(self):
@@ -37,7 +39,7 @@ def test_auth(self):
3739
'first_name': first_name,
3840
'last_name': last_name,
3941
'email': email,
40-
# try to abuse superuser/staff level perms
42+
# try to abuse superuser/staff level perms (not the first signup!)
4143
'is_superuser': True,
4244
'is_staff': True,
4345
}

0 commit comments

Comments
 (0)