Merge pull request #277 from matburt/fix_inventory_read_jt_rbac

Check inventory access for normal users when deciding what job templates show up in the queryset
This commit is contained in:
Matthew Jones
2015-06-12 16:04:34 -04:00
3 changed files with 129 additions and 21 deletions

View File

@@ -904,8 +904,21 @@ class JobTemplateAccess(BaseAccess):
inventory__permissions__pk=F('project__permissions__pk'), inventory__permissions__pk=F('project__permissions__pk'),
) )
perm_inventory_read_user_qs = qs.filter(
inventory__permissions__user__in=[self.user],
inventory__permissions__permission_type__in=PERMISSION_TYPES_ALLOWING_INVENTORY_READ,
inventory__permissions__active=True)
perm_inventory_read_team_qs = qs.filter(
inventory__permissions__team__users__in=[self.user],
inventory__permissions__team__active=True,
inventory__permissions__permission_type__in=PERMISSION_TYPES_ALLOWING_INVENTORY_READ,
inventory__permissions__active=True)
perm_inventory = perm_inventory_read_user_qs | perm_inventory_read_team_qs
# FIXME: I *think* this should work... needs more testing. # FIXME: I *think* this should work... needs more testing.
return org_admin_qs | perm_deploy_qs | perm_check_qs return org_admin_qs | (perm_deploy_qs & perm_inventory) | (perm_check_qs & perm_inventory)
def can_read(self, obj): def can_read(self, obj):
# you can only see the job templates that you have permission to launch. # you can only see the job templates that you have permission to launch.

View File

@@ -355,6 +355,29 @@ class BaseJobTestMixin(BaseTestMixin):
created_by = self.user_sue, created_by = self.user_sue,
) )
self.ops_east_permission = Permission.objects.create(
inventory = self.inv_ops_east,
project = self.proj_prod,
team = self.team_ops_east,
permission_type = PERM_JOBTEMPLATE_CREATE,
created_by = self.user_sue
)
self.ops_east_permission_prod_east = Permission.objects.create(
inventory = self.inv_ops_east,
project = self.proj_prod_east,
team = self.team_ops_east,
permission_type = PERM_JOBTEMPLATE_CREATE,
created_by = self.user_sue
)
self.ops_east_permission_inv_admin = Permission.objects.create(
inventory = self.inv_ops_east,
team = self.team_ops_east,
permission_type = PERM_INVENTORY_ADMIN,
created_by = self.user_sue
)
self.ops_testers_permission = Permission.objects.create( self.ops_testers_permission = Permission.objects.create(
inventory = self.inv_ops_west, inventory = self.inv_ops_west,
project = self.proj_prod, project = self.proj_prod,
@@ -363,6 +386,13 @@ class BaseJobTestMixin(BaseTestMixin):
created_by = self.user_sue created_by = self.user_sue
) )
self.ops_testers_permission_inv_read = Permission.objects.create(
inventory = self.inv_ops_west,
team = self.team_ops_testers,
permission_type = PERM_INVENTORY_READ,
created_by = self.user_sue
)
self.doug_check_permission = Permission.objects.create( self.doug_check_permission = Permission.objects.create(
inventory = self.inv_eng, inventory = self.inv_eng,
project = self.proj_dev, project = self.proj_dev,
@@ -371,6 +401,13 @@ class BaseJobTestMixin(BaseTestMixin):
created_by = self.user_sue created_by = self.user_sue
) )
self.doug_inv_read_permission = Permission.objects.create(
inventory = self.inv_eng,
user = self.user_doug,
permission_type = PERM_INVENTORY_READ,
created_by = self.user_sue
)
self.juan_deploy_permission = Permission.objects.create( self.juan_deploy_permission = Permission.objects.create(
inventory = self.inv_eng, inventory = self.inv_eng,
project = self.proj_dev, project = self.proj_dev,
@@ -488,6 +525,16 @@ class BaseJobTestMixin(BaseTestMixin):
host_config_key=uuid.uuid4().hex, host_config_key=uuid.uuid4().hex,
created_by=self.user_sue, created_by=self.user_sue,
) )
self.jt_ops_east_run_prod_east = JobTemplate.objects.create(
name='ops-east-prod-run-on-prod-east',
job_type='run',
inventory= self.inv_ops_east,
project=self.proj_prod_east,
playbook=self.proj_prod_east.playbooks[0],
credential=self.cred_ops_east,
host_config_key=uuid.uuid4().hex,
created_by=self.user_sue,
)
# self.job_ops_east_run = self.jt_ops_east_run.create_job( # self.job_ops_east_run = self.jt_ops_east_run.create_job(
# created_by=self.user_sue, # created_by=self.user_sue,
# ) # )
@@ -501,6 +548,16 @@ class BaseJobTestMixin(BaseTestMixin):
host_config_key=uuid.uuid4().hex, host_config_key=uuid.uuid4().hex,
created_by=self.user_sue, created_by=self.user_sue,
) )
self.jt_ops_west_check_test_team = JobTemplate.objects.create(
name='ops-west-prod-check-testers',
job_type='check',
inventory= self.inv_ops_west,
project=self.proj_prod,
playbook=self.proj_prod.playbooks[0],
credential=self.cred_ops_test,
host_config_key=uuid.uuid4().hex,
created_by=self.user_sue,
)
# self.job_ops_west_check = self.jt_ops_west_check.create_job( # self.job_ops_west_check = self.jt_ops_west_check.create_job(
# created_by=self.user_sue, # created_by=self.user_sue,
# ) # )

View File

@@ -211,29 +211,67 @@ class JobTemplateTest(BaseJobTestMixin, django.test.TestCase):
# Alex's credentials (admin of all orgs) == 200, full list # Alex's credentials (admin of all orgs) == 200, full list
self.check_get_list(url, self.user_alex, qs, fields) self.check_get_list(url, self.user_alex, qs, fields)
# Bob's credentials (admin of eng, user of ops) == 200, all from # # Bob is an admin for Eng he can see all Engineering templates
# engineering and operations. # this is: 2 Engineering templates and 1 Support Template
qs.filter( # Note: He is able to see the scan job from the support organization possibly incorrect
Q(project__organizations__admins__in=[self.user_bob]) | # due to being an org admin for that project and no credential assigned to that template
Q(project__teams__users__in=[self.user_bob]), with self.current_user(self.user_bob):
) resp = self.get(url, expect=200)
#self.check_get_list(url, self.user_bob, bob_qs, fields) print [x['name'] for x in resp['results']]
self.assertEquals(resp['count'], 3)
# Chuck's credentials (admin of eng) == 200, all from engineering. # Chuck has permission to see all Eng Job Templates as Lead Engineer
qs.filter( # Note: Since chuck is an org admin he can also see the support scan template
Q(project__organizations__admins__in=[self.user_chuck]) | with self.current_user(self.user_chuck):
Q(project__teams__users__in=[self.user_chuck]), resp = self.get(url, expect=200)
) print [x['name'] for x in resp['results']]
#self.check_get_list(url, self.user_chuck, chuck_qs, fields) self.assertEquals(resp['count'], 3)
# Doug's credentials (user of eng) == 200, none?. # Doug is in engineering but can only run scan jobs so he can only see the one Job Template
qs.filter( with self.current_user(self.user_doug):
Q(project__organizations__admins__in=[self.user_doug]) | resp = self.get(url, expect=200)
Q(project__teams__users__in=[self.user_doug]), print [x['name'] for x in resp['results']]
) self.assertEquals(resp['count'], 1)
#self.check_get_list(url, self.user_doug, doug_qs, fields)
# Juan can't see any job templates in Engineering because he lacks the inventory read permission
with self.current_user(self.user_juan):
resp = self.get(url, expect=200)
print [x['name'] for x in resp['results']]
self.assertEquals(resp['count'], 0)
# We give Juan inventory permission and he can see both Job Templates because he already has deploy permission
# Now he can see both job templates
juan_inv_permission = Permission.objects.create(
inventory = self.inv_eng,
user = self.user_juan,
permission_type = PERM_INVENTORY_READ,
created_by = self.user_sue
)
with self.current_user(self.user_juan):
resp = self.get(url, expect=200)
print [x['name'] for x in resp['results']]
self.assertEquals(resp['count'], 2)
# Randall is on the ops testers team that has permission to run a single check playbook on ops west
with self.current_user(self.user_randall):
resp = self.get(url, expect=200)
print [x['name'] for x in resp['results']]
self.assertEquals(resp['count'], 1)
# Holly is on the ops east team and can see all of that team's job templates
with self.current_user(self.user_holly):
resp = self.get(url, expect=200)
print [x['name'] for x in resp['results']]
self.assertEquals(resp['count'], 3)
# Chuck is temporarily assigned to ops east team to help them running some playbooks
# even though he's in a different group and org entirely he'll now see their job templates
self.team_ops_east.users.add(self.user_chuck)
with self.current_user(self.user_chuck):
resp = self.get(url, expect=200)
print [x['name'] for x in resp['results']]
self.assertEquals(resp['count'], 6)
# FIXME: Check with other credentials.
def test_credentials_list(self): def test_credentials_list(self):
url = reverse('api:credential_list') url = reverse('api:credential_list')