2013-03-20 06:26:35 +04:00
from django . http import HttpResponse
from django . views . decorators . csrf import csrf_exempt
from lib . main . models import *
2013-03-22 19:35:26 +04:00
from django . contrib . auth . models import User
2013-03-20 06:26:35 +04:00
from lib . main . serializers import *
2013-03-21 08:34:59 +04:00
from lib . main . rbac import *
2013-03-21 22:20:59 +04:00
from django . core . exceptions import PermissionDenied
2013-03-20 06:26:35 +04:00
from rest_framework import mixins
from rest_framework import generics
from rest_framework import permissions
2013-03-22 17:50:42 +04:00
from rest_framework . response import Response
from rest_framework import status
2013-03-21 18:25:49 +04:00
import exceptions
2013-03-21 22:20:59 +04:00
import datetime
2013-03-20 06:26:35 +04:00
2013-03-21 23:11:47 +04:00
# FIXME: machinery for auto-adding audit trail logs to all CREATE/EDITS
2013-03-21 22:20:59 +04:00
class BaseList ( generics . ListCreateAPIView ) :
def list_permissions_check ( self , request , obj = None ) :
if request . method == ' GET ' :
# everybody can call get, but it's filtered
return True
if request . method == ' POST ' :
# superusers have already been cleared, so deny regular users
return False
raise exceptions . NotImplementedError
def get_queryset ( self ) :
return self . _get_queryset ( ) . filter ( active = True )
class BaseDetail ( generics . RetrieveUpdateDestroyAPIView ) :
2013-03-22 21:49:26 +04:00
def pre_save ( self , obj ) :
obj . created_by = owner = self . request . user
2013-03-21 22:20:59 +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 )
class OrganizationsList ( BaseList ) :
2013-03-20 06:26:35 +04:00
model = Organization
serializer_class = OrganizationSerializer
permission_classes = ( CustomRbac , )
2013-03-21 23:43:35 +04:00
# I can see the organizations if:
# I am a superuser
# I am an admin of the organization
# I am a member of the organization
2013-03-21 07:14:09 +04:00
2013-03-21 22:20:59 +04:00
def _get_queryset ( self ) :
2013-03-21 07:14:09 +04:00
if self . request . user . is_superuser :
2013-03-21 23:43:35 +04:00
return Organization . objects . all ( )
2013-03-21 22:20:59 +04:00
return Organization . objects . filter (
2013-03-22 19:35:26 +04:00
admins__in = [ self . request . user ]
2013-03-21 22:20:59 +04:00
) . distinct ( ) | Organization . objects . filter (
2013-03-22 19:35:26 +04:00
users__in = [ self . request . user ]
2013-03-21 22:20:59 +04:00
) . distinct ( )
class OrganizationsDetail ( BaseDetail ) :
2013-03-21 18:25:49 +04:00
2013-03-20 06:26:35 +04:00
model = Organization
serializer_class = OrganizationSerializer
permission_classes = ( CustomRbac , )
2013-03-21 23:11:47 +04:00
# FIXME: use this for the audit trail hook, ideally in base class.
2013-03-20 06:26:35 +04:00
#def pre_save(self, obj):
# obj.owner = self.request.user
2013-03-21 19:06:47 +04:00
def item_permissions_check ( self , request , obj ) :
2013-03-22 19:35:26 +04:00
is_admin = request . user in obj . admins . all ( )
is_user = request . user in obj . users . all ( )
2013-03-21 22:20:59 +04:00
2013-03-21 19:06:47 +04:00
if request . method == ' GET ' :
2013-03-21 22:20:59 +04:00
return is_admin or is_user
elif request . method in [ ' PUT ' ] :
return is_admin
return False
2013-03-21 18:44:01 +04:00
2013-03-21 22:20:59 +04:00
def delete_permissions_check ( self , request , obj ) :
2013-03-22 19:35:26 +04:00
return request . user in obj . admins . all ( )
2013-03-21 18:44:01 +04:00
2013-03-21 23:11:47 +04:00
class OrganizationsAuditTrailList ( BaseList ) :
2013-03-21 23:43:35 +04:00
model = AuditTrail
serializer_class = AuditTrailSerializer
permission_classes = ( CustomRbac , )
# FIXME: guts & tests
2013-03-21 23:11:47 +04:00
pass
class OrganizationsUsersList ( BaseList ) :
2013-03-21 23:43:35 +04:00
model = User
serializer_class = UserSerializer
permission_classes = ( CustomRbac , )
# I can see the users in the organization if:
# I am a super user
# I am an admin of the organization
def _get_queryset ( self ) :
# FIXME:
2013-03-22 19:35:26 +04:00
base = User . objects . all ( organizations__pk__in = [ self . kwargs . get ( ' pk ' ) ] )
2013-03-21 23:43:35 +04:00
if self . request . user . is_superuser :
return base . all ( )
return base . objects . filter (
2013-03-22 19:35:26 +04:00
organizations__organization__admins__in = [ self . request . user ]
2013-03-21 23:43:35 +04:00
) . distinct ( )
2013-03-21 23:11:47 +04:00
class OrganizationsAdminsList ( BaseList ) :
2013-03-21 23:43:35 +04:00
model = User
serializer_class = UserSerializer
permission_classes = ( CustomRbac , )
# I can see the admins in the organization if:
# I am a super user
# I am an admin of the organization
def _get_queryset ( self ) :
# FIXME
2013-03-22 01:38:53 +04:00
base = User . objects . all ( admin_of_organizations__pk__in = [ self . kwargs . get ( ' pk ' ) ] )
2013-03-21 23:43:35 +04:00
if self . request . user . is_superuser :
return base . all ( )
return base . filter (
2013-03-22 19:35:26 +04:00
organizations__organization__admins__in = [ self . request . user ]
2013-03-21 23:43:35 +04:00
) . distinct ( )
2013-03-21 23:11:47 +04:00
class OrganizationsProjectsList ( BaseList ) :
2013-03-21 23:43:35 +04:00
2013-03-22 01:38:53 +04:00
model = Project
serializer_class = ProjectSerializer
permission_classes = ( CustomRbac , )
2013-03-21 23:43:35 +04:00
# I can see the projects from the organization if:
# I'm the superuser
# I am a an administrator of the organization
2013-03-22 01:38:53 +04:00
# I am a member of a team on the project
2013-03-21 23:43:35 +04:00
def _get_queryset ( self ) :
2013-03-22 01:38:53 +04:00
base = Project . objects . filter ( organizations__in = [ self . kwargs . get ( ' pk ' ) ] )
2013-03-21 23:43:35 +04:00
if self . request . user . is_superuser :
return base . all ( )
return base . filter (
2013-03-22 19:35:26 +04:00
organizations__admins__in = [ self . request . user ]
2013-03-21 23:43:35 +04:00
) . distinct ( ) | base . filter (
2013-03-22 19:35:26 +04:00
teams__users__in = [ self . request . user ]
2013-03-21 23:43:35 +04:00
) . distinct ( )
2013-03-21 23:11:47 +04:00
2013-03-22 22:48:18 +04:00
# BOOKMARK
2013-03-22 17:50:42 +04:00
def post ( self , request , * args , * * kwargs ) :
2013-03-22 19:22:04 +04:00
# POST { pk: 7, disassociate: True }
2013-03-22 21:49:26 +04:00
organization_id = kwargs [ ' pk ' ]
project_id = request . DATA . get ( ' id ' )
2013-03-22 22:23:50 +04:00
organization = Organization . objects . get ( pk = organization_id )
projects = Project . objects . filter ( pk = project_id )
if len ( projects ) != 1 :
return Response ( status = status . HTTP_400_BAD_REQUEST )
project = projects [ 0 ]
2013-03-22 21:49:26 +04:00
# you can only add a project to an organization if you are a superuser or
2013-03-22 22:23:50 +04:00
# the person who created the project. TODO -- want to defer this question
# to the model. (FIXME)
2013-03-22 21:49:26 +04:00
2013-03-22 22:48:18 +04:00
if not ' disassociate ' in request . DATA :
# admin of another org can't add a project to their org
if not request . user . is_superuser or project . created_by == request . user :
raise PermissionDenied ( )
if project in organization . projects . all ( ) :
return Response ( status = status . HTTP_409_CONFLICT )
organization . projects . add ( project )
else :
# to disassociate, be the org admin or a superuser
# FIXME: sprinkle these throughout the object layer & simplify
if not request . user . is_superuser and not project . can_user_administrate ( request . user ) :
raise PermissionDenied ( )
organization . projects . remove ( project )
# multiple attempts to delete the same thing aren't an error, we're cool
return Response ( status = status . HTTP_204_NO_CONTENT )
2013-03-22 21:49:26 +04:00
2013-03-22 17:50:42 +04:00
2013-03-21 23:11:47 +04:00
class OrganizationsTagsList ( BaseList ) :
2013-03-21 23:43:35 +04:00
# FIXME: guts & tests
2013-03-21 23:11:47 +04:00
pass
2013-03-22 01:38:53 +04:00
class ProjectsDetail ( BaseDetail ) :
model = Project
serializer_class = ProjectSerializer
permission_classes = ( CustomRbac , )
def item_permissions_check ( self , request , obj ) :
# to get, must be in a team assigned to this project
# or be an org admin of an org this project is in
raise exceptions . NotImplementedError ( )
2013-03-22 19:35:26 +04:00
#is_admin = request.user in obj.admins.all()
#is_user = request.user in obj.users.all()
2013-03-22 01:38:53 +04:00
#
#if request.method == 'GET':
# return is_admin or is_user
#elif request.method in [ 'PUT' ]:
# return is_admin
#return False
def delete_permissions_check ( self , request , obj ) :
# FIXME: logic TBD
raise exceptions . NotImplementedError ( )
2013-03-22 19:35:26 +04:00
#return request.user in obj.admins.all()
2013-03-21 23:11:47 +04:00