diff --git a/lib/main/models/__init__.py b/lib/main/models/__init__.py index 13a9268f00..5826e48d70 100644 --- a/lib/main/models/__init__.py +++ b/lib/main/models/__init__.py @@ -26,6 +26,7 @@ import exceptions # TODO: jobs and events model TBD # TODO: reporting model TBD +PERM_INVENTORY_ADMIN = 'admin' PERM_INVENTORY_READ = 'read' PERM_INVENTORY_WRITE = 'write' PERM_INVENTORY_DEPLOY = 'run' @@ -37,17 +38,33 @@ JOB_TYPE_CHOICES = [ ] PERMISSION_TYPES = [ + PERM_INVENTORY_ADMIN, PERM_INVENTORY_READ, PERM_INVENTORY_WRITE, PERM_INVENTORY_DEPLOY, PERM_INVENTORY_CHECK, ] -PERMISSION_TYPES_ALLOWING_INVENTORY_READ = PERMISSION_TYPES +PERMISSION_TYPES_ALLOWING_INVENTORY_READ = [ + PERM_INVENTORY_ADMIN, + PERM_INVENTORY_WRITE, + PERM_INVENTORY_READ, +] +PERMISSION_TYPES_ALLOWING_INVENTORY_WRITE = [ + PERM_INVENTORY_ADMIN, + PERM_INVENTORY_WRITE, +] + +PERMISSION_TYPES_ALLOWING_INVENTORY_ADMIN = [ + PERM_INVENTORY_ADMIN, +] + +# FIXME: TODO: make sure all of these are used and consistent PERMISSION_TYPE_CHOICES = [ (PERM_INVENTORY_READ, _('Read Inventory')), - (PERM_INVENTORY_WRITE, _('Write Inventory')), + (PERM_INVENTORY_WRITE, _('Edit Inventory')), + (PERM_INVENTORY_ADMIN, _('Administrate Inventory')), (PERM_INVENTORY_DEPLOY, _('Deploy To Inventory')), (PERM_INVENTORY_CHECK, _('Deploy To Inventory (Dry Run)')), ] @@ -263,6 +280,34 @@ class Inventory(CommonModel): else: return self.name + @classmethod + def _has_permission_types(cls, user, obj, allowed): + if user.is_superuser: + return True + by_org_admin = user in obj.organization.admins.all() + by_team_permission = obj.permissions.filter( + team__in = user.teams.all(), + permission_type__in = allowed + ).count() + by_user_permission = obj.permissions.filter( + user = user, + permission_type__in = allowed + ).count() + return (by_org_admin + by_team_permission + by_user_permission) > 0 + + @classmethod + def can_user_administrate(cls, user, obj): + return cls._has_permission_types(user, obj, PERMISSION_TYPES_ALLOWING_INVENTORY_ADMIN) + + @classmethod + def can_user_read(cls, user, obj): + return cls._has_permission_types(user, obj, PERMISSION_TYPES_ALLOWING_INVENTORY_READ) + + @classmethod + def can_user_delete(cls, user, obj): + return cls._has_permission_types(user, obj, PERMISSION_TYPES_ALLOWING_INVENTORY_ADMIN) + + class Host(CommonModel): ''' A managed node diff --git a/lib/main/tests/inventory.py b/lib/main/tests/inventory.py index 0f455a92a0..d71aef75e9 100644 --- a/lib/main/tests/inventory.py +++ b/lib/main/tests/inventory.py @@ -30,7 +30,12 @@ class InventoryTest(BaseTest): # the normal user is an org admin of org 0 # create a permission here on the 'other' user so they have edit access on the org - # TODO + # we may add another permission type later. + self.perm_read = Permission.objects.create( + inventory = self.inventory_b, + user = self.other_django_user, + permission_type = 'read' + ) # and make one more user that won't be a part of any org, just for negative-access testing @@ -62,7 +67,7 @@ class InventoryTest(BaseTest): # a user who is on a team who has a read permissions on an inventory can see filtered inventories data = self.get(inventories, expect=200, auth=self.get_other_credentials()) - self.assertEquals(data['count'], 0) + self.assertEquals(data['count'], 1) # a regular user not part of anything cannot see any inventories data = self.get(inventories, expect=200, auth=self.get_nobody_credentials()) @@ -72,12 +77,18 @@ class InventoryTest(BaseTest): data = self.get(inventories_1, expect=200, auth=self.get_super_credentials()) self.assertEquals(data['name'], 'inventory-a') + # an org admin can get inventory records + data = self.get(inventories_1, expect=200, auth=self.get_normal_credentials()) + self.assertEquals(data['name'], 'inventory-a') + # a user who is on a team who has read permissions on an inventory can see inventory records + data = self.get(inventories_1, expect=403, auth=self.get_other_credentials()) + data = self.get(inventories_2, expect=200, auth=self.get_other_credentials()) + self.assertEquals(data['name'], 'inventory-b') # a regular user cannot read any inventory records - - - #new_user2 = dict(username='blippy2') + data = self.get(inventories_1, expect=403, auth=self.get_nobody_credentials()) + data = self.get(inventories_2, expect=403, auth=self.get_nobody_credentials()) # a super user can create inventory