@@ -94,6 +94,21 @@ def has_permission(self, request, view):
9494 return request .user .is_superuser
9595
9696
97+ class IsAdminOrSafeMethod (permissions .BasePermission ):
98+ """
99+ View permission to allow only admins to use unsafe methods
100+ including POST, PUT, DELETE.
101+
102+ This allows
103+ """
104+
105+ def has_permission (self , request , view ):
106+ """
107+ Return `True` if permission is granted, `False` otherwise.
108+ """
109+ return request .method in permissions .SAFE_METHODS or request .user .is_superuser
110+
111+
97112class UserRegistrationView (viewsets .GenericViewSet ,
98113 viewsets .mixins .CreateModelMixin ):
99114 model = User
@@ -187,13 +202,18 @@ def update(self, request, *args, **kwargs):
187202 return super (FlavorViewSet , self ).update (request , * args , ** kwargs )
188203
189204
190- class FormationViewSet (OwnerViewSet ):
205+ class FormationViewSet (viewsets . ModelViewSet ):
191206 """RESTful views for :class:`~api.models.Formation`."""
192207
193208 model = models .Formation
194209 serializer_class = serializers .FormationSerializer
210+ permission_classes = (permissions .IsAuthenticated , IsAdminOrSafeMethod )
195211 lookup_field = 'id'
196212
213+ def pre_save (self , obj ):
214+ if not hasattr (obj , 'owner' ):
215+ obj .owner = self .request .user
216+
197217 def post_save (self , formation , created = False , ** kwargs ):
198218 if created :
199219 formation .build ()
@@ -246,14 +266,18 @@ def destroy(self, request, **kwargs):
246266 return Response (status = status .HTTP_204_NO_CONTENT )
247267
248268
249- class FormationScopedViewSet (OwnerViewSet ):
269+ class FormationScopedViewSet (viewsets .ModelViewSet ):
270+
271+ permission_classes = (permissions .IsAuthenticated , IsAdmin )
272+
273+ def pre_save (self , obj ):
274+ if not hasattr (obj , 'owner' ):
275+ obj .owner = self .request .user
250276
251277 def get_queryset (self , ** kwargs ):
252- formations = models .Formation .objects .filter (
253- owner = self .request .user )
278+ formations = models .Formation .objects .all ()
254279 formation = get_object_or_404 (formations , id = self .kwargs ['id' ])
255- return self .model .objects .filter (owner = self .request .user ,
256- formation = formation )
280+ return self .model .objects .filter (formation = formation )
257281
258282
259283class FormationLayerViewSet (FormationScopedViewSet ):
@@ -269,15 +293,14 @@ def get_object(self, *args, **kwargs):
269293
270294 def create (self , request , ** kwargs ):
271295 request ._data = request .DATA .copy ()
272- formation = models .Formation .objects .get (
273- owner = self .request .user , id = self .kwargs ['id' ])
296+ formation = models .Formation .objects .get (id = self .kwargs ['id' ])
274297 request .DATA ['formation' ] = formation .id
275298 if not 'ssh_private_key' in request .DATA and not 'ssh_public_key' in request .DATA :
276299 # SECURITY: figure out best way to get keys with proper entropy
277300 key = RSA .generate (2048 )
278301 request .DATA ['ssh_private_key' ] = key .exportKey ('PEM' )
279302 request .DATA ['ssh_public_key' ] = key .exportKey ('OpenSSH' )
280- return OwnerViewSet . create ( self , request , ** kwargs )
303+ return super ( FormationLayerViewSet , self ). create ( request , ** kwargs )
281304
282305 def post_save (self , layer , created = False , ** kwargs ):
283306 if created :
@@ -302,10 +325,8 @@ def get_object(self, *args, **kwargs):
302325
303326 def add (self , request , ** kwargs ):
304327 fqdn = request .DATA ['fqdn' ]
305- formation = models .Formation .objects .get (
306- owner = self .request .user , id = self .kwargs ['id' ])
307- layer = models .Layer .objects .get (
308- owner = self .request .user , id = request .DATA ['layer' ])
328+ formation = models .Formation .objects .get (id = self .kwargs ['id' ])
329+ layer = models .Layer .objects .get (id = request .DATA ['layer' ])
309330 if self .model .objects .filter (fqdn = fqdn , formation = formation , layer = layer ).exists ():
310331 msg = "A node with fqdn={} already exists in the {} formation" .format (fqdn , formation )
311332 return Response (data = msg , status = status .HTTP_409_CONFLICT )
@@ -394,7 +415,7 @@ class NodeViewSet(FormationNodeViewSet):
394415 """RESTful views for :class:`~api.models.Node`."""
395416
396417 def get_queryset (self , ** kwargs ):
397- return self .model .objects .filter ( owner = self . request . user )
418+ return self .model .objects .all ( )
398419
399420 def converge (self , request , ** kwargs ):
400421 node = self .get_object ()
0 commit comments