2013-03-22 23:22:30 +04:00
from django . http import HttpResponse
from django . views . decorators . csrf import csrf_exempt
from lib . main . models import *
from django . contrib . auth . models import User
from lib . main . serializers import *
from lib . main . rbac import *
from django . core . exceptions import PermissionDenied
from rest_framework import mixins
from rest_framework import generics
from rest_framework import permissions
from rest_framework . response import Response
from rest_framework import status
import exceptions
import datetime
# FIXME: machinery for auto-adding audit trail logs to all CREATE/EDITS
class BaseList ( generics . ListCreateAPIView ) :
def list_permissions_check ( self , request , obj = None ) :
''' determines some early yes/no access decisions, pre-filtering '''
if request . method == ' GET ' :
return True
if request . method == ' POST ' :
2013-03-23 22:31:36 +04:00
return self . __class__ . model . can_user_add ( request . user )
2013-03-22 23:22:30 +04:00
raise exceptions . NotImplementedError
def get_queryset ( self ) :
2013-03-24 00:03:17 +04:00
base = self . _get_queryset ( )
model = self . __class__ . model
if model == User :
return base . filter ( is_active = True )
elif model in [ Tag , AuditTrail ] :
return base
2013-03-23 23:34:16 +04:00
else :
return self . _get_queryset ( ) . filter ( active = True )
2013-03-22 23:22:30 +04:00
2013-03-23 00:52:44 +04:00
class BaseSubList ( BaseList ) :
''' used for subcollections with an overriden post '''
2013-03-23 22:31:36 +04:00
def list_permissions_check ( self , request , obj = None ) :
''' determines some early yes/no access decisions, pre-filtering '''
if request . method == ' GET ' :
return True
if request . method == ' POST ' :
# the can_user_attach methods will be called below
return True
raise exceptions . NotImplementedError
2013-03-23 00:52:44 +04:00
def post ( self , request , * args , * * kwargs ) :
2013-03-24 00:50:25 +04:00
postable = getattr ( self . __class__ , ' postable ' , False )
if not postable :
return Response ( status = status . HTTP_405_METHOD_NOT_ALLOWED )
2013-03-23 00:52:44 +04:00
parent_id = kwargs [ ' pk ' ]
sub_id = request . DATA . get ( ' id ' )
main = self . __class__ . parent_model . objects . get ( pk = parent_id )
subs = self . __class__ . model . objects . filter ( pk = sub_id )
if len ( subs ) != 1 :
return Response ( status = status . HTTP_400_BAD_REQUEST )
sub = subs [ 0 ]
relationship = getattr ( main , self . __class__ . relationship )
if not ' disassociate ' in request . DATA :
2013-03-23 23:08:02 +04:00
if not request . user . is_superuser and not self . __class__ . parent_model . can_user_attach ( request . user , main , sub , self . __class__ . relationship ) :
2013-03-23 00:52:44 +04:00
raise PermissionDenied ( )
if sub in relationship . all ( ) :
return Response ( status = status . HTTP_409_CONFLICT )
relationship . add ( sub )
else :
if not request . user . is_superuser and not self . __class__ . parent_model . can_user_unattach ( request . user , main , sub , self . __class__ . relationship ) :
raise PermissionDenied ( )
relationship . remove ( sub )
return Response ( status = status . HTTP_204_NO_CONTENT )
2013-03-22 23:22:30 +04:00
class BaseDetail ( generics . RetrieveUpdateDestroyAPIView ) :
def pre_save ( self , obj ) :
2013-03-23 02:16:40 +04:00
obj . created_by = self . request . user
2013-03-22 23:22:30 +04:00
def destroy ( self , request , * args , * * kwargs ) :
# somewhat lame that delete has to call it's own permissions check
obj = self . model . objects . get ( pk = kwargs [ ' pk ' ] )
if not request . user . is_superuser and not self . delete_permissions_check ( request , obj ) :
raise PermissionDenied ( )
obj . name = " _deleted_ %s _ %s " % ( str ( datetime . time ( ) ) , obj . name )
obj . active = False
obj . save ( )
return HttpResponse ( status = 204 )
2013-03-22 23:36:59 +04:00
def delete_permissions_check ( self , request , obj ) :
2013-03-22 23:53:08 +04:00
return self . __class__ . model . can_user_delete ( request . user , obj )
2013-03-22 23:36:59 +04:00
2013-03-22 23:44:32 +04:00
def item_permissions_check ( self , request , obj ) :
if request . method == ' GET ' :
return self . __class__ . model . can_user_read ( request . user , obj )
elif request . method in [ ' PUT ' ] :
return self . __class__ . model . can_user_administrate ( request . user , obj )
return False
2013-03-22 23:36:59 +04:00