Repository: ansible/awx
File: awx/main/access.py (Python)

Code before:
                    return get_object_from_data(field, Class, data)
                else:
                    return None

        # If credentials is provided, the user should have use access to them.
        for pk in data.get('credentials', []):
            raise Exception('Credentials must be attached through association method.')

        # If an inventory is provided, the user should have use access.
        inventory = get_value(Inventory, 'inventory')
        if inventory:
            if self.user not in inventory.use_role:
                self.messages['job_template'] = [_('You do not have use permission on Inventory')]
                return False

        if not self.check_related('execution_environment', ExecutionEnvironment, data, role_field='read_role'):
            return False

        project = get_value(Project, 'project')
        # If the user has admin access to the project (as an org admin), should
        # be able to proceed without additional checks.
        if not project:
            return False

        if self.user not in project.use_role:
            self.messages['job_template'] = [_('You do not have use permission on Project')]
            return False

        return True

    @check_superuser
    def can_copy_related(self, obj):
        """
        Check if we have access to all the credentials related to Job Templates.
        Does not verify the user's permission for any other related fields (projects, inventories, etc).
        """

        # obj.credentials.all() is accessible ONLY when object is saved (has valid id)
        credential_manager = getattr(obj, 'credentials', None) if getattr(obj, 'id', False) else Credential.objects.none()
        user_can_copy = reduce(lambda prev, cred: prev and self.user in cred.use_role, credential_manager.all(), True)
        if not user_can_copy:
            raise PermissionDenied(_('Insufficient access to Job Template credentials.'))
        return user_can_copy

    def can_start(self, obj, validate_license=True):
        # Check license.
        if validate_license:
            self.check_license()

            # Check the per-org limit
            self.check_org_host_limit({'inventory': obj.inventory})

Review comment (suggestion):
The field that has the error is "project" not "job_template". The user already knows they are editing a job template. So I would change that, just the _key_ here.

Code after:
                else:
                    return None

        # If credentials is provided, the user should have use access to them.
        for pk in data.get('credentials', []):
            raise Exception('Credentials must be attached through association method.')

        # If an inventory is provided, the user should have use access.
        inventory = get_value(Inventory, 'inventory')
        if inventory:
            if self.user not in inventory.use_role:
                if self.save_messages:
                    self.messages['inventory'] = [_('You do not have use permission on Inventory')]
                return False

        if not self.check_related('execution_environment', ExecutionEnvironment, data, role_field='read_role'):
            return False

        project = get_value(Project, 'project')
        # If the user has admin access to the project (as an org admin), should
        # be able to proceed without additional checks.
        if not project:
            return False

        if self.user not in project.use_role:
            if self.save_messages:
                self.messages['project'] = [_('You do not have use permission on Project')]
            return False

        return True

    @check_superuser
    def can_copy_related(self, obj):
        """
        Check if we have access to all the credentials related to Job Templates.
        Does not verify the user's permission for any other related fields (projects, inventories, etc).
        """

        # obj.credentials.all() is accessible ONLY when object is saved (has valid id)
        credential_manager = getattr(obj, 'credentials', None) if getattr(obj, 'id', False) else Credential.objects.none()
        user_can_copy = reduce(lambda prev, cred: prev and self.user in cred.use_role, credential_manager.all(), True)
        if not user_can_copy:
            raise PermissionDenied(_('Insufficient access to Job Template credentials.'))
        return user_can_copy

    def can_start(self, obj, validate_license=True):
        # Check license.
        if validate_license:
            self.check_license()

            # Check the per-org limit