Example of how to disassociate an object from a collection, to be generalized later!

This commit is contained in:
Michael DeHaan 2013-03-22 14:48:18 -04:00
parent d179c91537
commit ed6096216f
3 changed files with 40 additions and 13 deletions

View File

@ -2,6 +2,7 @@ from django.db import models
from django.db.models import CASCADE, SET_NULL, PROTECT
from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse
import exceptions
# TODO: jobs and events model TBD
# TODO: reporting model TBD
@ -29,6 +30,9 @@ class CommonModel(models.Model):
def __unicode__(self):
return unicode(self.name)
def can_user_administrate(self, user):
raise exceptions.NotImplementedError()
class Tag(models.Model):
'''
@ -173,6 +177,14 @@ class Project(CommonModel):
import lib.urls
return reverse(lib.urls.views_ProjectsDetail, args=(self.pk,))
def can_user_administrate(self, user):
organizations = Organization.filter(admins__in = [ user ])
organizations = self.organizations()
for org in organizations:
if org in project.organizations():
return True
return True
class Permission(CommonModel):
'''
A permission allows a user, project, or team to be able to use an inventory source.

View File

@ -280,17 +280,26 @@ class OrganizationsTest(BaseTest):
a_project = projects0['results'][-1]
# attempt to add the project to the 7th org and see what happens
self.post(projects7_url, a_project, expect=202, auth=self.get_super_credentials())
projects7 = self.get(projects0_url, expect=200, auth=self.get_super_credentials())
self.assertEquals(projects7['count'], 3)
self.post(projects7_url, a_project, expect=204, auth=self.get_super_credentials())
projects1 = self.get(projects0_url, expect=200, auth=self.get_super_credentials())
self.assertEquals(projects1['count'], 3)
# make sure we can't add the project again (should generate a conflict error)
self.post(projects7_url, a_project, expect=409, auth=self.get_super_credentials())
projects7 = self.get(projects7_url, expect=200, auth=self.get_super_credentials())
self.assertEquals(projects7['count'], 6)
# make sure adding a project that does not exist, or a missing pk field, results in a 400
self.post(projects7_url, dict(id=99999), expect=400, auth=self.get_super_credentials())
self.post(projects7_url, dict(asdf=1234), expect=400, auth=self.get_super_credentials())
# test that by posting a pk + disassociate: True we can remove a relationship
a_project['disassociate'] = True
self.post(projects7_url, a_project, expect=204, auth=self.get_super_credentials())
projects7 = self.get(projects7_url, expect=200, auth=self.get_super_credentials())
self.assertEquals(projects7['count'], 5)
def test_post_item_subobjects_users(self):
pass

View File

@ -159,11 +159,9 @@ class OrganizationsProjectsList(BaseList):
teams__users__in = [ self.request.user ]
).distinct()
# BOOKMARK
def post(self, request, *args, **kwargs):
# FIXME: overriden post for add-to-collection
# FIXME: if posted with disassociate: True, do not create object and remove the link
# POST { pk: 7, disassociate: True }
organization_id = kwargs['pk']
@ -178,14 +176,22 @@ class OrganizationsProjectsList(BaseList):
# the person who created the project. TODO -- want to defer this question
# to the model. (FIXME)
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)
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)
organization.projects.add(project)
return Response(status=status.HTTP_202_ACCEPTED)