Exemple #1
0
 def test__accepts_variable_args(self):
     self.assertThat(
         is_instance_or_subclass(self.foo, Baz, Foo, Bar), Equals(True)
     )
     self.assertThat(
         is_instance_or_subclass(self.foo, Baz, Bar), Equals(False)
     )
Exemple #2
0
 def test_accepts_tuple_or_list(self):
     self.assertThat(is_instance_or_subclass(self.foo, (Baz, Foo, Bar)),
                     Equals(True))
     self.assertThat(is_instance_or_subclass(self.bar, (Baz, Foo)),
                     Equals(False))
     self.assertThat(is_instance_or_subclass(self.baz, [Bar, Foo]),
                     Equals(True))
Exemple #3
0
 def test_accepts_non_flat_list(self):
     self.assertThat(
         is_instance_or_subclass(self.foo, (Baz, (Bar, (Foo, )))),
         Equals(True),
     )
     self.assertThat(
         is_instance_or_subclass(self.bar, *[Baz, [Bar, [Foo]]]),
         Equals(True),
     )
Exemple #4
0
 def test_rejects_incorrect_type(self):
     self.assertThat(is_instance_or_subclass(self.foo, Bar), Equals(False))
     self.assertThat(is_instance_or_subclass(self.bar, Baz), Equals(False))
     self.assertThat(is_instance_or_subclass(self.baz, Foo), Equals(False))
Exemple #5
0
 def test_accept_subclass(self):
     self.assertThat(is_instance_or_subclass(self.baz, Bar), Equals(True))
Exemple #6
0
 def test_returns_false_if_object_is_not_relevant(self):
     self.assertThat(is_instance_or_subclass("Bar", Bar), Equals(False))
Exemple #7
0
 def test_accepts_correct_type(self):
     self.assertThat(is_instance_or_subclass(self.foo, Foo), Equals(True))
     self.assertThat(is_instance_or_subclass(self.bar, Bar), Equals(True))
     self.assertThat(is_instance_or_subclass(self.baz, Baz), Equals(True))
Exemple #8
0
    def has_perm(self, user, perm, obj=None):
        # Note that a check for a superuser will never reach this code
        # because Django will return True (as an optimization) for every
        # permission check performed on a superuser.
        if not user.is_active:
            # Deactivated users, and in particular the node-init user,
            # are prohibited from accessing maasserver services.
            return False

        if isinstance(obj, Node):
            if perm == NODE_PERMISSION.VIEW:
                # Any registered user can view a node regardless of its state.
                return True
            elif perm == NODE_PERMISSION.EDIT:
                return obj.owner == user
            elif perm == NODE_PERMISSION.ADMIN:
                # 'admin_node' permission is solely granted to superusers.
                return False
            else:
                raise NotImplementedError(
                    'Invalid permission check (invalid permission name: %s).' %
                    perm)
        elif isinstance(obj, (BlockDevice, FilesystemGroup)):
            if isinstance(obj, BlockDevice):
                node = obj.node
            else:
                node = obj.get_node()
            if perm == NODE_PERMISSION.VIEW:
                # If the node is not ownered or the owner is the user then
                # they can view the information.
                return node.owner is None or node.owner == user
            elif perm == NODE_PERMISSION.EDIT:
                return node.owner == user
            elif perm == NODE_PERMISSION.ADMIN:
                # 'admin_node' permission is solely granted to superusers.
                return False
            else:
                raise NotImplementedError(
                    'Invalid permission check (invalid permission name: %s).' %
                    perm)
        elif isinstance(obj, Interface):
            if perm == NODE_PERMISSION.VIEW:
                # Any registered user can view a interface regardless
                # of its state.
                return True
            elif perm in NODE_PERMISSION.EDIT:
                # A device can be editted by its owner a node must be admin.
                node = obj.get_node()
                if node is None or node.node_type == NODE_TYPE.MACHINE:
                    return user.is_superuser
                else:
                    return node.owner == user
            elif perm in NODE_PERMISSION.ADMIN:
                # Admin permission is solely granted to superusers.
                return user.is_superuser
            else:
                raise NotImplementedError(
                    'Invalid permission check (invalid permission name: %s).' %
                    perm)
        elif is_instance_or_subclass(obj, UNRESTRICTED_READ_MODELS):
            # This model is classified under 'unrestricted read' for any
            # logged-in user; so everyone can view, but only an admin can
            # do anything else.
            if perm == NODE_PERMISSION.VIEW:
                return True
            elif perm in ADMIN_PERMISSIONS:
                # Admin permission is solely granted to superusers.
                return user.is_superuser
            else:
                raise NotImplementedError(
                    'Invalid permission check (invalid permission name: %s).' %
                    perm)
        elif is_instance_or_subclass(obj, ADMIN_RESTRICTED_MODELS):
            # Only administrators are allowed to read/write these objects.
            if perm in ADMIN_PERMISSIONS:
                return user.is_superuser
            else:
                raise NotImplementedError(
                    'Invalid permission check (invalid permission name: %s).' %
                    perm)
        else:
            raise NotImplementedError(
                'Invalid permission check (invalid object type).')
Exemple #9
0
    def has_perm(self, user, perm, obj=None):
        if not user.is_active:
            # Deactivated users, and in particular the node-init user,
            # are prohibited from accessing maasserver services.
            return False

        from maasserver.rbac import rbac
        rbac_enabled = rbac.is_enabled()
        visible_pools, view_all_pools = [], []
        deploy_pools, admin_pools = [], []
        if rbac_enabled:
            visible_pools = rbac.get_resource_pool_ids(
                user.username, 'view')
            view_all_pools = rbac.get_resource_pool_ids(
                user.username, 'view-all')
            deploy_pools = rbac.get_resource_pool_ids(
                user.username, 'deploy-machines')
            admin_pools = rbac.get_resource_pool_ids(
                user.username, 'admin-machines')

        # Sanity check that a `ResourcePool` is being checked against
        # `ResourcePoolPermission`.
        if (obj is not None and isinstance(obj, ResourcePool) and
                not isinstance(perm, ResourcePoolPermission)):
            raise TypeError(
                'obj type of ResourcePool must be checked '
                'against a `ResourcePoolPermission`.')

        # Handle node permissions without objects.
        if perm == NodePermission.admin and obj is None:
            # User wants to admin writes to all nodes (aka. create a node),
            # must be superuser for those permissions.
            return user.is_superuser
        elif perm == NodePermission.view and obj is None:
            # XXX 2018-11-20 blake_r: View permission without an obj is used
            # for device create as a standard user. Currently there is no
            # specific DevicePermission and no way for this code path to know
            # its for a device. So it is represented using this path.
            #
            # View is only used for the create action, modifying a created
            # device uses the appropriate `NodePermission.edit` scoped to the
            # device being editted.
            if rbac_enabled:
                # User must either be global admin or have access to deploy
                # or admin some machines.
                return (
                    user.is_superuser or
                    (len(deploy_pools) > 0 or len(admin_pools) > 0))
            return True

        # ResourcePool permissions are handled specifically.
        if isinstance(perm, ResourcePoolPermission):
            return self._perm_resource_pool(
                user, perm, rbac, visible_pools, obj)

        if isinstance(obj, (Node, BlockDevice, FilesystemGroup)):
            if isinstance(obj, BlockDevice):
                obj = obj.node
            elif isinstance(obj, FilesystemGroup):
                obj = obj.get_node()
            if perm == NodePermission.view:
                return self._can_view(
                    rbac_enabled, user, obj,
                    visible_pools, view_all_pools,
                    deploy_pools, admin_pools)
            elif perm == NodePermission.edit:
                can_edit = self._can_edit(
                    rbac_enabled, user, obj, deploy_pools, admin_pools)
                return not obj.locked and can_edit
            elif perm == NodePermission.lock:
                # only machines can be locked
                can_edit = self._can_edit(
                    rbac_enabled, user, obj, deploy_pools, admin_pools)
                return obj.pool_id is not None and can_edit
            elif perm == NodePermission.admin:
                return not obj.locked and self._can_admin(
                    rbac_enabled, user, obj, admin_pools)
            else:
                raise NotImplementedError(
                    'Invalid permission check (invalid permission name: %s).' %
                    perm)
        elif isinstance(obj, Interface):
            node = obj.get_node()
            if node is None:
                # Doesn't matter the permission level if the interface doesn't
                # have a node, the user must be a global admin.
                return user.is_superuser
            if perm == NodePermission.view:
                return self._can_view(
                    rbac_enabled, user, node,
                    visible_pools, view_all_pools,
                    deploy_pools, admin_pools)
            elif perm == NodePermission.edit:
                # Machine interface can only be modified by an administrator
                # of the machine. Even the owner of the machine cannot modify
                # the interfaces on that machine, unless they have
                # administrator rights.
                if node.node_type == NODE_TYPE.MACHINE:
                    return self._can_admin(
                        rbac_enabled, user, node, admin_pools)
                # Other node types must be editable by the user.
                return self._can_edit(
                    rbac_enabled, user, node, deploy_pools, admin_pools)
            elif perm == NodePermission.admin:
                # Admin permission is solely granted to superusers.
                return self._can_admin(
                    rbac_enabled, user, node, admin_pools)
            else:
                raise NotImplementedError(
                    'Invalid permission check (invalid permission name: %s).' %
                    perm)
        elif is_instance_or_subclass(obj, UNRESTRICTED_READ_MODELS):
            # This model is classified under 'unrestricted read' for any
            # logged-in user; so everyone can view, but only an admin can
            # do anything else.
            if perm == NodePermission.view:
                return True
            elif perm in ADMIN_PERMISSIONS:
                # Admin permission is solely granted to superusers.
                return user.is_superuser
            else:
                raise NotImplementedError(
                    'Invalid permission check (invalid permission name: %s).' %
                    perm)
        elif is_instance_or_subclass(obj, ADMIN_RESTRICTED_MODELS):
            # Only administrators are allowed to read/write these objects.
            if perm in ADMIN_PERMISSIONS:
                return user.is_superuser
            else:
                raise NotImplementedError(
                    'Invalid permission check (invalid permission name: %s).' %
                    perm)
        else:
            raise NotImplementedError(
                'Invalid permission check (invalid object type).')
Exemple #10
0
    def has_perm(self, user, perm, obj=None):
        if not user.is_active:
            # Deactivated users, and in particular the node-init user,
            # are prohibited from accessing maasserver services.
            return False

        from maasserver.rbac import rbac
        rbac_enabled = rbac.is_enabled()
        visible_pools, admin_pools = [], []
        if rbac_enabled:
            visible_pools = rbac.get_resource_pools(
                user.username, 'view').values_list(
                    'id', flat=True)
            admin_pools = rbac.get_resource_pools(
                user.username, 'admin-machines').values_list(
                    'id', flat=True)

        if isinstance(obj, (Node, BlockDevice, FilesystemGroup)):
            if isinstance(obj, BlockDevice):
                obj = obj.node
            elif isinstance(obj, FilesystemGroup):
                obj = obj.get_node()
            if perm == NodePermission.view:
                return self._can_view(
                    rbac_enabled, user, obj, visible_pools, admin_pools)
            elif perm == NodePermission.edit:
                can_edit = self._can_edit(
                    rbac_enabled, user, obj, visible_pools, admin_pools)
                return not obj.locked and can_edit
            elif perm == NodePermission.lock:
                # only machines can be locked
                can_edit = self._can_edit(
                    rbac_enabled, user, obj, visible_pools, admin_pools)
                return obj.pool_id is not None and can_edit
            elif perm == NodePermission.admin:
                return self._can_admin(
                    rbac_enabled, user, obj, admin_pools)
            else:
                raise NotImplementedError(
                    'Invalid permission check (invalid permission name: %s).' %
                    perm)
        elif isinstance(obj, Interface):
            node = obj.get_node()
            if node is None:
                # Doesn't matter the permission level if the interface doesn't
                # have a node, the user must be a global admin.
                return user.is_superuser
            if perm == NodePermission.view:
                return self._can_view(
                    rbac_enabled, user, node, visible_pools, admin_pools)
            elif perm == NodePermission.edit:
                # Machine interface can only be modified by an administrator
                # of the machine. Even the owner of the machine cannot modify
                # the interfaces on that machine, unless they have
                # administrator rights.
                if node.node_type == NODE_TYPE.MACHINE:
                    return self._can_admin(
                        rbac_enabled, user, node, admin_pools)
                # Other node types must be editable by the user.
                return self._can_edit(
                    rbac_enabled, user, node, visible_pools, admin_pools)
            elif perm == NodePermission.admin:
                # Admin permission is solely granted to superusers.
                return self._can_admin(
                    rbac_enabled, user, node, admin_pools)
            else:
                raise NotImplementedError(
                    'Invalid permission check (invalid permission name: %s).' %
                    perm)
        elif is_instance_or_subclass(obj, UNRESTRICTED_READ_MODELS):
            # This model is classified under 'unrestricted read' for any
            # logged-in user; so everyone can view, but only an admin can
            # do anything else.
            if perm == NodePermission.view:
                return True
            elif perm in ADMIN_PERMISSIONS:
                # Admin permission is solely granted to superusers.
                return user.is_superuser
            else:
                raise NotImplementedError(
                    'Invalid permission check (invalid permission name: %s).' %
                    perm)
        elif is_instance_or_subclass(obj, ADMIN_RESTRICTED_MODELS):
            # Only administrators are allowed to read/write these objects.
            if perm in ADMIN_PERMISSIONS:
                return user.is_superuser
            else:
                raise NotImplementedError(
                    'Invalid permission check (invalid permission name: %s).' %
                    perm)
        else:
            raise NotImplementedError(
                'Invalid permission check (invalid object type).')