1
1
from __future__ import unicode_literals
2
- from django .contrib .auth .models import User , Permission
2
+ from django .contrib .auth .models import User , Permission , Group
3
3
from django .db import models
4
4
from django .test import TestCase
5
5
from rest_framework import generics , status , permissions , authentication , HTTP_HEADER_ENCODING
6
6
from rest_framework .compat import guardian
7
7
from rest_framework .test import APIRequestFactory
8
8
from rest_framework .tests .models import BasicModel
9
- from rest_framework .settings import api_settings
10
9
import base64
11
10
12
11
factory = APIRequestFactory ()
@@ -142,67 +141,142 @@ def test_options_updateonly(self):
142
141
self .assertEqual (list (response .data ['actions' ].keys ()), ['PUT' ])
143
142
144
143
145
- class BasicPermModel (BasicModel ):
144
+ class BasicPermModel (models .Model ):
145
+ text = models .CharField (max_length = 100 )
146
146
147
147
class Meta :
148
148
app_label = 'tests'
149
149
permissions = (
150
- ('read_basicpermmodel' , " Can view basic perm model" ),
150
+ ('read_basicpermmodel' , ' Can view basic perm model' ),
151
151
# add, change, delete built in to django
152
152
)
153
153
154
154
class ObjectPermissionInstanceView (generics .RetrieveUpdateDestroyAPIView ):
155
- model = BasicModel
155
+ model = BasicPermModel
156
156
authentication_classes = [authentication .BasicAuthentication ]
157
157
permission_classes = [permissions .DjangoObjectLevelModelPermissions ]
158
158
159
-
160
159
object_permissions_view = ObjectPermissionInstanceView .as_view ()
161
160
161
+ class ObjectPermissionListView (generics .ListAPIView ):
162
+ model = BasicPermModel
163
+ authentication_classes = [authentication .BasicAuthentication ]
164
+ permission_classes = [permissions .DjangoObjectLevelModelPermissions ]
165
+
166
+ object_permissions_list_view = ObjectPermissionListView .as_view ()
F438
167
+
162
168
if guardian :
169
+ from guardian .shortcuts import assign_perm
170
+
163
171
class ObjectPermissionsIntegrationTests (TestCase ):
164
172
"""
165
173
Integration tests for the object level permissions API.
166
174
"""
175
+ @classmethod
176
+ def setUpClass (cls ):
177
+ # create users
178
+ create = User .objects .create_user
179
+ users = {
180
+ 'fullaccess' : create ('fullaccess' , 'fullaccess@example.com' , 'password' ),
181
+ 'readonly' : create ('readonly' , 'readonly@example.com' , 'password' ),
182
+ 'writeonly' : create ('writeonly' , 'writeonly@example.com' , 'password' ),
183
+ 'deleteonly' : create ('deleteonly' , 'deleteonly@example.com' , 'password' ),
184
+ }
185
+
186
+ # give everyone model level permissions, as we are not testing those
187
+ everyone = Group .objects .create (name = 'everyone' )
188
+ model_name = BasicPermModel ._meta .module_name
189
+ app_label = BasicPermModel ._meta .app_label
190
+ f = '{0}_{1}' .format
191
+ perms = {
192
+ 'read' : f ('read' , model_name ),
193
+ 'change' : f ('change' , model_name ),
194
+ 'delete' : f ('delete' , model_name )
195
+ }
196
+ for perm in perms .values ():
197
+ perm = '{0}.{1}' .format (app_label , perm )
198
+ assign_perm (perm , everyone )
199
+ everyone .user_set .add (* users .values ())
200
+
201
+ cls .perms = perms
202
+ cls .users = users
167
203
168
204
def setUp (self ):
169
- # create users
170
- User .objects .create_user ('no_permission' , 'no_permission@example.com' , 'password' )
171
- reader = User .objects .create_user ('reader' , 'reader@example.com' , 'password' )
172
- writer = User .objects .create_user ('writer' , 'writer@example.com' , 'password' )
173
- full_access = User .objects .create_user ('full_access' , 'full_access@example.com' , 'password' )
174
-
175
- model = BasicPermModel .objects .create (text = 'foo' )
205
+ perms = self .perms
206
+ users = self .users
176
207
177
- # assign permissions appropriately
178
- from guardian .shortcuts import assign_perm
208
+ # appropriate object level permissions
209
+ readers = Group .objects .create (name = 'readers' )
210
+ writers = Group .objects .create (name = 'writers' )
211
+ deleters = Group .objects .create (name = 'deleters' )
179
212
180
- read = "read_basicpermmodel"
181
- write = "change_basicpermmodel"
182
- delete = "delete_basicpermmodel"
183
- app_label = 'tests.'
184
- # model level permissions
185
- assign_perm (app_label + delete , full_access , obj = model )
186
- (assign_perm (app_label + write , user , obj = model ) for user in (writer , full_access ))
187
- (assign_perm (app_label + read , user , obj = model ) for user in (reader , writer , full_access ))
213
+ model = BasicPermModel .objects .create (text = 'foo' )
214
+
215
+ assign_perm (perms ['read' ], readers , model )
216
+ assign_perm (perms ['change' ], writers , model )
217
+ assign_perm (perms ['delete' ], deleters , model )
218
+
219
+ readers .user_set .add (users ['fullaccess' ], users ['readonly' ])
220
+ writers .user_set .add (users ['fullaccess' ], users ['writeonly' ])
221
+ deleters .user_set .add (users ['fullaccess' ], users ['deleteonly' ])
222
+
223
+ self .credentials = {}
224
+ for user in users .values ():
225
+ self .credentials [user .username ] = basic_auth_header (user .username , 'password' )
226
+
227
+ # Delete
228
+ def test_can_delete_permissions (self ):
229
+ request = factory .delete ('/1' , HTTP_AUTHORIZATION = self .credentials ['deleteonly' ])
230
+ object_permissions_view .cls .action = 'destroy'
231
+ response = object_permissions_view (request , pk = '1' )
232
+ self .assertEqual (response .status_code , status .HTTP_204_NO_CONTENT )
188
233
189
- # object level permissions
190
- assign_perm (delete , full_access , obj = model )
191
- (assign_perm (write , user , obj = model ) for user in (writer , full_access ))
192
- (assign_perm (read , user , obj = model ) for user in (reader , writer , full_access ))
234
+ def test_cannot_delete_permissions (self ):
235
+ request = factory .delete ('/1' , HTTP_AUTHORIZATION = self .credentials ['readonly' ])
236
+ object_permissions_view .cls .action = 'destroy'
237
+ response = object_permissions_view (request , pk = '1' )
238
+ self .assertEqual (response .status_code , status .HTTP_404_NOT_FOUND )
193
239
194
- self .no_permission_credentials = basic_auth_header ('no_permission' , 'password' )
195
- self .reader_credentials = basic_auth_header ('reader' , 'password' )
196
- self .writer_credentials = basic_auth_header ('writer' , 'password' )
197
- self .full_access_credentials = basic_auth_header ('full_access' , 'password' )
240
+ # Update
241
+ def test_can_update_permissions (self ):
242
+ request = factory .patch ('/1' , {'text' : 'foobar' }, format = 'json' ,
243
+ HTTP_AUTHORIZATION = self .credentials ['writeonly' ])
244
+ object_permissions_view .cls .action = 'partial_update'
245
+ response = object_permissions_view (request , pk = '1' )
246
+ self .assertEqual (response .status_code , status .HTTP_200_OK )
247
+ self .assertEqual (response .data .get ('text' ), 'foobar' )
198
248
249
+ def test_cannot_update_permissions (self ):
250
+ request = factory .patch ('/1' , {'text' : 'foobar' }, format = 'json' ,
251
+ HTTP_AUTHORIZATION = self .credentials ['deleteonly' ])
252
+ object_permissions_view .cls .action = 'partial_update'
253
+ response = object_permissions_view (request , pk = '1' )
254
+ self .assertEqual (response .status_code , status .HTTP_404_NOT_FOUND )
199
255
200
- def test_has_delete_permissions (self ):
201
- request = factory .delete ('/1' , HTTP_AUTHORIZATION = self .full_access_credentials )
256
+ # Read
257
+ def test_can_read_permissions (self ):
258
+ request = factory .get ('/1' , HTTP_AUTHORIZATION = self .credentials ['readonly' ])
259
+ object_permissions_view .cls .action = 'retrieve'
202
260
response = object_permissions_view (request , pk = '1' )
203
- self .assertEqual (response .status_code , status .HTTP_204_NO_CONTENT )
261
+ self .assertEqual (response .status_code , status .HTTP_200_OK )
204
262
205
- def test_no_delete_permissions (self ):
206
- request = factory .delete ('/1' , HTTP_AUTHORIZATION = self .writer_credentials )
263
+ def test_cannot_read_permissions (self ):
264
+ request = factory .get ('/1' , HTTP_AUTHORIZATION = self .credentials ['writeonly' ])
265
+ object_permissions_view .cls .action = 'retrieve'
207
266
response = object_permissions_view (request , pk = '1' )
208
267
self .assertEqual (response .status_code , status .HTTP_404_NOT_FOUND )
268
+
269
+ # Read list
270
+ def test_can_read_list_permissions (self ):
271
+ request = factory .get ('/' , HTTP_AUTHORIZATION = self .credentials ['readonly' ])
272
+ object_permissions_list_view .cls .action = 'list'
273
+ response = object_permissions_list_view (request )
274
+ self .assertEqual (response .status_code , status .HTTP_200_OK )
275
+ self .assertEqual (response .data [0 ].get ('id' ), 1 )
276
+
277
+ def test_cannot_read_list_permissions (self ):
278
+ request = factory .get ('/' , HTTP_AUTHORIZATION = self .credentials ['writeonly' ])
279
+ object_permissions_list_view .cls .action = 'list'
280
+ response = object_permissions_list_view (request )
281
+ self .assertEqual (response .status_code , status .HTTP_200_OK )
282
+ self .assertListEqual (response .data , [])
0 commit comments