diff --git a/lib/main/base_views.py b/lib/main/base_views.py index 9f8cca0ce8..e8d543a87c 100644 --- a/lib/main/base_views.py +++ b/lib/main/base_views.py @@ -138,10 +138,15 @@ class BaseSubList(BaseList): # no attaching to yourself raise PermissionDenied() + if self.__class__.parent_model != User: + if not obj.__class__.can_user_read(request.user, obj): + raise PermissionDenied() if not self.__class__.parent_model.can_user_attach(request.user, main, obj, self.__class__.relationship, request.DATA): raise PermissionDenied() else: + if not UserHelper.can_user_read(request.user, obj): + raise PermissionDenied() # FIXME: should generalize this if not UserHelper.can_user_attach(request.user, main, obj, self.__class__.relationship, request.DATA): raise PermissionDenied() diff --git a/lib/main/models/__init__.py b/lib/main/models/__init__.py index c7d9382df7..b3db12e9b5 100644 --- a/lib/main/models/__init__.py +++ b/lib/main/models/__init__.py @@ -806,29 +806,45 @@ class JobTemplate(CommonModel): return True job_type = data['job_type'] - has_project_permission = False + has_launch_permission = False user_permissions = Permission.objects.filter(inventory=inventory, project=project, user=user) for perm in user_permissions: if job_type == PERM_INVENTORY_CHECK: # if you have run permissions, you can also create check jobs - has_project_permission = True + has_launch_permission = True elif job_type == PERM_INVENTORY_DEPLOY and perm.permission_type == PERM_INVENTORY_DEPLOY: # you need explicit run permissions to make run jobs - has_project_permission = True + has_launch_permission = True team_permissions = Permission.objects.filter(inventory=inventory, project=project, team__users__in = [user]) for perm in team_permissions: if job_type == PERM_INVENTORY_CHECK: # if you have run permissions, you can also create check jobs - has_project_permission = True + has_launch_permission = True elif job_type == PERM_INVENTORY_DEPLOY and perm.permission_type == PERM_INVENTORY_DEPLOY: # you need explicit run permissions to make run jobs - has_project_permission = True + has_launch_permission = True - # FIXME: make sure credential belongs to me or my team + if not has_launch_permission: + return False - return has_project_permission + # make sure user owns the credentials they are using + if data.has_key('credential'): + has_credential = False + credential = Credential.objects.get(pk=data['credential']) + if credential.team and credential.team.users.filter(id = user.pk).count(): + has_credential = True + if credential.user and credential.user == user: + has_credential = True + if not has_credential: + return False + # shouldn't really matter with permissions given, but make sure the user + # is also currently on the team in case they were added a per-user permission and then removed + # from the project. + if project.teams.filter(users__in = [ user ]).count(): + return False + return True class Job(CommonModel): diff --git a/lib/main/tests/jobs.py b/lib/main/tests/jobs.py index 87d29217b1..ab4f5ca720 100644 --- a/lib/main/tests/jobs.py +++ b/lib/main/tests/jobs.py @@ -69,6 +69,7 @@ class JobsTest(BaseTest): ) self.team.users.add(self.other_django_user) + self.team.users.add(self.other2_django_user) self.project = Project.objects.create( name = 'testProject', @@ -115,7 +116,14 @@ class JobsTest(BaseTest): self.credential = Credential.objects.create( ssh_key_data = 'xxx', - created_by = self.normal_django_user + created_by = self.normal_django_user, + user = self.other_django_user + ) + + self.credential2 = Credential.objects.create( + ssh_key_data = 'xxx', + created_by = self.normal_django_user, + team = self.team, ) self.organization.projects.add(self.project) @@ -169,11 +177,12 @@ class JobsTest(BaseTest): # nobody user can't even run check mode rec['name'] = 'job-foo4' self.post('/api/v1/job_templates/', rec, expect=403, auth=self.get_nobody_credentials()) + rec['credential'] = self.credential2.pk posted = self.post('/api/v1/job_templates/', rec, expect=201, auth=self.get_other2_credentials()) rec['name'] = 'job-foo5' rec['job_type'] = PERM_INVENTORY_DEPLOY self.post('/api/v1/job_templates/', rec, expect=403, auth=self.get_nobody_credentials()) - self.post('/api/v1/job_templates/', rec, expect=403, auth=self.get_other2_credentials()) + self.post('/api/v1/job_templates/', rec, expect=201, auth=self.get_other2_credentials()) url = posted['url'] # verify we can also get the job template record