Some TODO updates, a model revision, and getting association/disassociation working on user/team creds.

This commit is contained in:
Michael DeHaan
2013-04-15 19:19:54 -04:00
parent 9fc041f4ec
commit ec0e0f60dc
4 changed files with 85 additions and 21 deletions

View File

@@ -14,7 +14,7 @@
# You should have received a copy of the GNU General Public License
# along with Ansible Commander. If not, see <http://www.gnu.org/licenses/>.
from django.http import HttpResponse
from django.http import HttpResponse, Http404
from django.views.decorators.csrf import csrf_exempt
from lib.main.models import *
from django.contrib.auth.models import User
@@ -147,14 +147,27 @@ class BaseSubList(BaseList):
relationship = getattr(main, self.__class__.relationship)
if not 'disassociate' in request.DATA:
if not request.user.is_superuser and not self.__class__.parent_model.can_user_attach(request.user, main, sub, self.__class__.relationship):
raise PermissionDenied()
if not request.user.is_superuser:
if type(main) != User:
if not self.__class__.parent_model.can_user_attach(request.user, main, sub, self.__class__.relationship):
raise PermissionDenied()
else:
if not UserHelper.can_user_attach(request.user, main, sub, self.__class__.relationship):
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()
if not request.user.is_superuser:
if type(main) != User:
if not self.__class__.parent_model.can_user_unattach(request.user, main, sub, self.__class__.relationship):
raise PermissionDenied()
else:
if not UserHelper.can_user_unattach(request.user, main, sub, self.__class__.relationship):
raise PermissionDenied()
if severable:
relationship.remove(sub)
else:
@@ -174,6 +187,10 @@ class BaseDetail(generics.RetrieveUpdateDestroyAPIView):
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 getattr(obj, 'active', True) == False:
raise Http404()
if getattr(obj, 'is_active', True) == False:
raise Http404()
if not request.user.is_superuser and not self.delete_permissions_check(request, obj):
raise PermissionDenied()
if isinstance(obj, PrimordialModel):

View File

@@ -131,11 +131,14 @@ class UserHelper(object):
def can_user_attach(cls, user, obj, sub_obj, relationship_type):
if type(sub_obj) != User:
if not sub_obj.can_user_read(user, sub_obj):
print "N1"
return False
rc = cls.can_user_administrate(user, obj)
return rc
@classmethod
def can_user_unattach(cls, user, obj, sub_obj, relationship_type):
return cls.can_user_administrate(user, obj)
class PrimordialModel(models.Model):
'''
common model for all object types that have these standard fields
@@ -548,6 +551,13 @@ class Credential(CommonModelNameNotUnique):
return True
return False
@classmethod
def can_user_delete(cls, user, obj):
if obj.user is None and obj.team is None:
# unassociated credentials may be marked deleted by anyone
return True
return cls.can_user_administrate(user,obj)
@classmethod
def can_user_read(cls, user, obj):
''' a user can be read if they are on the same team or can be administrated '''

View File

@@ -342,19 +342,29 @@ class ProjectsTest(BaseTest):
# editing a credential to edit the user record is not legal, this is a test of the .validate
# method on the serializer to allow 'write once' fields
self.put(edit_creds1, data=d_cred_user2, expect=400, auth=self.get_normal_credentials())
self.put(edit_creds1, data=d_cred_user, expect=200, auth=self.get_other_credentials())
cred_put_u = self.put(edit_creds1, data=d_cred_user, expect=200, auth=self.get_other_credentials())
self.put(edit_creds2, data=d_cred_team, expect=401)
self.put(edit_creds2, data=d_cred_team, expect=401, auth=self.get_invalid_credentials())
cred_team = Credential.objects.get(pk=cred_team.pk)
self.put(edit_creds2, data=d_cred_team, expect=200, auth=self.get_super_credentials())
cred_team = Credential.objects.get(pk=cred_team.pk)
self.put(edit_creds2, data=d_cred_team, expect=200, auth=self.get_normal_credentials())
cred_put_t = self.put(edit_creds2, data=d_cred_team, expect=200, auth=self.get_normal_credentials())
self.put(edit_creds2, data=d_cred_team, expect=403, auth=self.get_other_credentials())
cred_put_t['disassociate'] = 1
team_url = "/api/v1/teams/%s/credentials/" % cred_put_t['team']
self.post(team_url, data=cred_put_t, expect=204, auth=self.get_normal_credentials())
# can remove credentials from a user (via disassociate)
# can remove credentials from a team (via disassociate)
# can delete a credential directly
cred_put_u['disassociate'] = 1
url = cred_put_u['url']
user_url = "/api/v1/users/%s/credentials/" % cred_put_u['user']
self.post(user_url, data=cred_put_u, expect=204, auth=self.get_normal_credentials())
# can delete a credential directly -- probably won't be used too often
data = self.delete(url, expect=204, auth=self.get_other_credentials())
data = self.delete(url, expect=404, auth=self.get_other_credentials())
# =====================================================================
# PERMISSIONS