Ejemplo n.º 1
0
    def test_single_level_match(self):
        sub_ereg = MQTTUtils.convert_to_ereg("foo/+/bar")

        self.assertIsNotNone(re.match(sub_ereg, 'foo/buzz/bar'))
        self.assertIsNotNone(re.match(sub_ereg, 'foo//bar'))

        self.assertIsNone(re.match(sub_ereg, 'foo/bar'))
        self.assertIsNone(re.match(sub_ereg, 'foo/bar/'))
        self.assertIsNone(re.match(sub_ereg, '/foo/bar'))
        self.assertIsNone(re.match(sub_ereg, 'foo/one/two/bar'))
        self.assertIsNone(re.match(sub_ereg, 'foo/one/bar/'))
        self.assertIsNone(re.match(sub_ereg, '/foo/one/bar'))
        self.assertIsNone(re.match(sub_ereg, 'foo/+/bar'))

        ereg = MQTTUtils.convert_to_ereg('foo/bar/+')
        self.assertIsNotNone(re.match(ereg, 'foo/bar/buzz'))
        self.assertIsNotNone(re.match(ereg, 'foo/bar/'))

        self.assertIsNone(re.match(ereg, 'foo/bar/+'))
        self.assertIsNone(re.match(ereg, 'foo/bar/#'))
        self.assertIsNone(re.match(ereg, 'foo/bar/+/'))
        self.assertIsNone(re.match(ereg, 'foo/bar/+/#'))

        ereg = MQTTUtils.convert_to_ereg('+/foo/bar')
        self.assertIsNotNone(re.match(ereg, 'buzz/foo/bar'))
        self.assertIsNotNone(re.match(ereg, '/foo/bar'))

        self.assertIsNone(re.match(ereg, 'foo/bar'))
        self.assertIsNone(re.match(ereg, '//foo/bar'))
Ejemplo n.º 2
0
    def test_single_level_match(self):
        sub_ereg = MQTTUtils.convert_to_ereg("foo/+/bar")

        self.assertIsNotNone(re.match(sub_ereg, 'foo/buzz/bar'))
        self.assertIsNotNone(re.match(sub_ereg, 'foo//bar'))

        self.assertIsNone(re.match(sub_ereg, 'foo/bar'))
        self.assertIsNone(re.match(sub_ereg, 'foo/bar/'))
        self.assertIsNone(re.match(sub_ereg, '/foo/bar'))
        self.assertIsNone(re.match(sub_ereg, 'foo/one/two/bar'))
        self.assertIsNone(re.match(sub_ereg, 'foo/one/bar/'))
        self.assertIsNone(re.match(sub_ereg, '/foo/one/bar'))
        self.assertIsNone(re.match(sub_ereg, 'foo/+/bar'))

        ereg = MQTTUtils.convert_to_ereg('foo/bar/+')
        self.assertIsNotNone(re.match(ereg, 'foo/bar/buzz'))
        self.assertIsNotNone(re.match(ereg, 'foo/bar/'))

        self.assertIsNone(re.match(ereg, 'foo/bar/+'))
        self.assertIsNone(re.match(ereg, 'foo/bar/#'))
        self.assertIsNone(re.match(ereg, 'foo/bar/+/'))
        self.assertIsNone(re.match(ereg, 'foo/bar/+/#'))

        ereg = MQTTUtils.convert_to_ereg('+/foo/bar')
        self.assertIsNotNone(re.match(ereg, 'buzz/foo/bar'))
        self.assertIsNotNone(re.match(ereg, '/foo/bar'))

        self.assertIsNone(re.match(ereg, 'foo/bar'))
        self.assertIsNone(re.match(ereg, '//foo/bar'))
Ejemplo n.º 3
0
    def _encode_data(self):
        buffer = bytearray()
        buffer.extend(MQTTUtils.encode_value(self.id))

        for intent in self.subscription_intents:
            topic, qos = intent
            buffer.extend(MQTTUtils.encode_string(topic))
            buffer.append(MQTTUtils.encode_byte(qos) & self.QOS_PART_MASK)

        return bytes(buffer)
Ejemplo n.º 4
0
    def _encode_data(self):
        buffer = bytearray()
        buffer.extend(MQTTUtils.encode_string(self.topic))

        if self.qos in [MQTTConstants.AT_LEAST_ONCE, MQTTConstants.EXACTLY_ONCE]:
            buffer.extend(MQTTUtils.encode_value(self.id))

        buffer.extend(self.payload)

        return bytes(buffer)
Ejemplo n.º 5
0
    def _decode_data(self, _data):
        self.topic, l = MQTTUtils.decode_string(_data)
        cursor = l + 2

        if self.qos > MQTTConstants.AT_MOST_ONCE:
            self.id = MQTTUtils.decode_value(_data[cursor:cursor + 2])
            cursor += 2
        else:
            self.id = None

        self.payload = _data[cursor:]
Ejemplo n.º 6
0
    def _decode_data(self, _data):
        cursor = 0
        self.id = MQTTUtils.decode_value(_data[cursor:cursor + 2])
        cursor += 2

        self.unsubscribe_list = []
        while cursor < self.length:
            topic, l = MQTTUtils.decode_string(_data[cursor:])
            cursor += l + 2

            self.unsubscribe_list.append(topic)
Ejemplo n.º 7
0
    def _decode_data(self, _data):
        self.id = MQTTUtils.decode_value(_data[0:2])
        cursor = 2

        self.subscription_intents = []
        while cursor < self.length:
            topic, l = MQTTUtils.decode_string(_data[cursor:])
            cursor += l + 2

            qos = _data[cursor] & 0x03
            cursor += 1

            self.subscription_intents.append((topic, qos))
Ejemplo n.º 8
0
    def _encode_fixed_header(self, data):
        buffer = bytearray(1)
        buffer[0] |= self.type << 4
        buffer[0] |= (self.dup or 0) << 3
        buffer[0] |= (self.qos or 0) << 1
        buffer[0] |= self.retain or 0
        
        if not data:
            buffer.extend(MQTTUtils.encode_length(0))
        else:
            buffer.extend(MQTTUtils.encode_length(len(data)))

        return bytearray(buffer)
Ejemplo n.º 9
0
    def _encode_data(self):
        buffer = bytearray()

        # variable header
        buffer.extend(MQTTUtils.encode_string(self.protocol_name))
        buffer.append(MQTTUtils.encode_byte(self.protocol_version))

        connect_flags = 0x00
        connect_flags |= 0x80 if self.has_username else 0x00
        connect_flags |= 0x40 if self.has_passwd else 0x00
        connect_flags |= 0x20 if self.will_retain else 0x00
        connect_flags |= ((self.will_qos or 0x00) << 3) & 0x18
        connect_flags |= 0x04 if self.will_flag else 0x00
        connect_flags |= 0x02 if self.clean_session else 0x00
        buffer.append(connect_flags)

        buffer.extend(MQTTUtils.encode_value(self.keep_alive))

        # payload
        buffer.extend(MQTTUtils.encode_string(self.client_uid))

        if self.will_flag:
            buffer.extend(MQTTUtils.encode_string(self.will_topic))
            buffer.extend(MQTTUtils.encode_string(self.will_message))

        if self.has_username:
            buffer.extend(MQTTUtils.encode_string(self.username))

        if self.has_passwd:
            buffer.extend(MQTTUtils.encode_string(self.passwd))

        return bytes(buffer)
Ejemplo n.º 10
0
    def test_invalid_subscription_masks(self):
        masks = (
            '##',
            '++',
            '#/',
            '/#/+',
            '+#', '#+',
            '+#/', '#+/',
            '/+#', '/#+',
            'sports+',
            'sports#',
            '+sports',
            '#sports',
            'sports/#/',
            'sport/tennis#', 'sport#/tennis',
            '#sport/tennis', 'sport/#tennis',
            'sport/tennis+', 'sport+/tennis',
            'sport/+tennis', '+sport/tennis',
            '++/sport/tennis', 'sport/++/tennis', 'sport/tennis/++',
            '+++/sport/tennis', 'sport/+++/tennis', 'sport/tennis/+++',
            'sport/tennis/#/ranking',
            'sport/tennis/##/ranking',
            '#/sport/tennis/ranking',
            '##/sport/tennis/ranking',
            'sport/tennis/ranking/##',
            'sport/tennis/ranking/##/',
        )

        for mask in masks:
            self.assertFalse(MQTTUtils.subscription_is_valid(mask), "%s is valid" % mask)
Ejemplo n.º 11
0
    def test_single_level_mask(self):
        single_level = MQTTUtils.convert_to_ereg('foo/+/bar', allow_wildcards=True)
        self.assertIsMatch(single_level, 'foo/+/bar')
        self.assertIsMatch(single_level, 'foo/buzz/bar')
        self.assertIsMatch(single_level, 'foo//bar')

        self.assertIsNotMatch(single_level, 'foo/bar')
Ejemplo n.º 12
0
    def _clear_authorization_entry(cls, ts, allow_wildcards=False):
        """
        Validates an authorization entry
        :param ts: authorization entry: an asterisk string `'*'` meaning
        fully authorized, or a list of strings (topics, wildcards allowed)
        :type ts: str | list[str]
        :return:
        """

        if ts == cls.ALL:
            return ts

        elif isinstance(ts, list):
            rs = []
            for t in ts:
                assert isinstance(t, str)
                ereg = MQTTUtils.convert_to_ereg(
                    t, allow_wildcards=allow_wildcards)
                assert isinstance(ereg, str)
                rs.append((t, re.compile(ereg)))

            return rs

        else:
            raise ValueError('authorization has unexpected format')
Ejemplo n.º 13
0
    def _clear_authorization_entry(cls, ts, allow_wildcards=False):
        """
        Validates an authorization entry
        :param ts: authorization entry: an asterisk string `'*'` meaning
        fully authorized, or a list of strings (topics, wildcards allowed)
        :type ts: str | list[str]
        :return:
        """

        if ts == cls.ALL:
            return ts

        elif isinstance(ts, list):
            rs = []
            for t in ts:
                assert isinstance(t, str)
                ereg = MQTTUtils.convert_to_ereg(t,
                        allow_wildcards=allow_wildcards)
                assert isinstance(ereg, str)
                rs.append((t, re.compile(ereg)))

            return rs

        else:
            raise ValueError('authorization has unexpected format')
Ejemplo n.º 14
0
    def read_message(self):
        buffer = bytearray()
        chunk = yield self.read_bytes_async(MQTTConstants.MESSAGE_FIXED_HEADER_MINIMUM_SIZE)
        buffer.extend(chunk)

        while not MQTTUtils.is_length_field_complete(buffer[MQTTConstants.MESSAGE_TYPE_LENGTH:]):
            chunk = yield self.read_bytes_async(1)
            buffer.extend(chunk)

        msg_length, field_size = MQTTUtils.decode_length(buffer[MQTTConstants.MESSAGE_TYPE_LENGTH:])

        if msg_length > 0:
            chunk = yield self.read_bytes_async(msg_length)
            buffer.extend(chunk)

        self._update_timeout()
        return bytes(buffer)
Ejemplo n.º 15
0
    def test_single_level_mask(self):
        single_level = MQTTUtils.convert_to_ereg('foo/+/bar',
                                                 allow_wildcards=True)
        self.assertIsMatch(single_level, 'foo/+/bar')
        self.assertIsMatch(single_level, 'foo/buzz/bar')
        self.assertIsMatch(single_level, 'foo//bar')

        self.assertIsNotMatch(single_level, 'foo/bar')
Ejemplo n.º 16
0
    def _get_regex(self, mask):
        compiled = self._re_cache.get(mask, None)

        if not compiled:
            ereg = MQTTUtils.convert_to_ereg(mask)
            compiled = re.compile(ereg)
            self._re_cache[mask] = compiled

        return compiled
Ejemplo n.º 17
0
    def _get_regex(self, mask):
        compiled = self._re_cache.get(mask, None)

        if not compiled:
            ereg = MQTTUtils.convert_to_ereg(mask)
            compiled = re.compile(ereg)
            self._re_cache[mask] = compiled

        return compiled
Ejemplo n.º 18
0
    def test_substring_doesnt_match(self):
        super = "/foo/bar"
        sub = "/foo/ba"

        sub_ereg = MQTTUtils.convert_to_ereg(sub)

        self.assertTrue(re.match(sub_ereg, sub) is not None)
        self.assertTrue(re.match(sub_ereg, super) is None)

        ereg = MQTTUtils.convert_to_ereg('foo/bar')
        self.assertIsNotNone(re.match(ereg, 'foo/bar'))

        self.assertIsNone(re.match(ereg, 'foo/bar/'))
        self.assertIsNone(re.match(ereg, '/foo/bar'))
        self.assertIsNone(re.match(ereg, 'foo//bar'))

        self.assertIsNone(re.match(ereg, 'foo/bar/buzz'))
        self.assertIsNone(re.match(ereg, 'buzz/foo/bar'))
        self.assertIsNone(re.match(ereg, 'foo/buzz/bar'))
Ejemplo n.º 19
0
    def test_substring_doesnt_match(self):
        super = "/foo/bar"
        sub = "/foo/ba"

        sub_ereg = MQTTUtils.convert_to_ereg(sub)

        self.assertTrue(re.match(sub_ereg, sub) is not None)
        self.assertTrue(re.match(sub_ereg, super) is None)

        ereg = MQTTUtils.convert_to_ereg('foo/bar')
        self.assertIsNotNone(re.match(ereg, 'foo/bar'))

        self.assertIsNone(re.match(ereg, 'foo/bar/'))
        self.assertIsNone(re.match(ereg, '/foo/bar'))
        self.assertIsNone(re.match(ereg, 'foo//bar'))

        self.assertIsNone(re.match(ereg, 'foo/bar/buzz'))
        self.assertIsNone(re.match(ereg, 'buzz/foo/bar'))
        self.assertIsNone(re.match(ereg, 'foo/buzz/bar'))
Ejemplo n.º 20
0
    def read_message(self):
        buffer = bytearray()
        chunk = yield self.read_bytes_async(
            MQTTConstants.MESSAGE_FIXED_HEADER_MINIMUM_SIZE)
        buffer.extend(chunk)

        while not MQTTUtils.is_length_field_complete(
                buffer[MQTTConstants.MESSAGE_TYPE_LENGTH:]):
            chunk = yield self.read_bytes_async(1)
            buffer.extend(chunk)

        msg_length, field_size = MQTTUtils.decode_length(
            buffer[MQTTConstants.MESSAGE_TYPE_LENGTH:])

        if msg_length > 0:
            chunk = yield self.read_bytes_async(msg_length)
            buffer.extend(chunk)

        self._update_timeout()
        return bytes(buffer)
Ejemplo n.º 21
0
    def test_multilevel_match(self):
        sub = "foo/bar/#"
        sub_ereg = MQTTUtils.convert_to_ereg(sub)
        self.assertIsNone(re.match(sub_ereg, 'foo/b'))
        self.assertIsNotNone(re.match(sub_ereg, 'foo/bar'))
        self.assertIsNotNone(re.match(sub_ereg, 'foo/bar/'))
        self.assertIsNotNone(re.match(sub_ereg, 'foo/bar/one'))
        self.assertIsNotNone(re.match(sub_ereg, 'foo/bar/one/'))
        self.assertIsNotNone(re.match(sub_ereg, 'foo/bar/one/two'))
        self.assertIsNotNone(re.match(sub_ereg, 'foo/bar/one/two/'))

        self.assertIsNone(re.match(sub_ereg, 'foo/bar/#'))
        self.assertIsNone(re.match(sub_ereg, 'foo/bar/+'))
        self.assertIsNone(re.match(sub_ereg, 'foo/bar/+/'))
        self.assertIsNone(re.match(sub_ereg, 'foo/bar/+/#'))
Ejemplo n.º 22
0
    def test_multilevel_match(self):
        sub = "foo/bar/#"
        sub_ereg = MQTTUtils.convert_to_ereg(sub)
        self.assertIsNone(re.match(sub_ereg, 'foo/b'))
        self.assertIsNotNone(re.match(sub_ereg, 'foo/bar'))
        self.assertIsNotNone(re.match(sub_ereg, 'foo/bar/'))
        self.assertIsNotNone(re.match(sub_ereg, 'foo/bar/one'))
        self.assertIsNotNone(re.match(sub_ereg, 'foo/bar/one/'))
        self.assertIsNotNone(re.match(sub_ereg, 'foo/bar/one/two'))
        self.assertIsNotNone(re.match(sub_ereg, 'foo/bar/one/two/'))

        self.assertIsNone(re.match(sub_ereg, 'foo/bar/#'))
        self.assertIsNone(re.match(sub_ereg, 'foo/bar/+'))
        self.assertIsNone(re.match(sub_ereg, 'foo/bar/+/'))
        self.assertIsNone(re.match(sub_ereg, 'foo/bar/+/#'))
Ejemplo n.º 23
0
    def _decode_data(self, _data):
        self.protocol_name, l = MQTTUtils.decode_string(_data)
        assert self.protocol_name == 'MQIsdp' or self.protocol_name == 'MQTT'

        cursor = l + 2
        self.protocol_version = _data[cursor]
        assert self.protocol_version == 3 or self.protocol_version == 4

        cursor += 1
        self.has_username = (_data[cursor] & 0x80) == 0x80
        self.has_passwd = (_data[cursor] & 0x40) == 0x40
        self.will_retain = (_data[cursor] & 0x20) == 0x20
        self.will_qos = (_data[cursor] & 0x18) >> 3
        self.will_flag = (_data[cursor] & 0x04) == 0x04
        self.clean_session = (_data[cursor] & 0x02) == 0x02
        cursor += 1

        self.keep_alive = MQTTUtils.decode_value(_data[cursor:cursor+2])
        cursor += 2

        self.client_uid, l = MQTTUtils.decode_string(_data[cursor:])
        cursor += l

        if self.will_flag:
            cursor += 2

            self.will_topic, l = MQTTUtils.decode_string(_data[cursor:])
            cursor += l + 2

            self.will_message, l = MQTTUtils.decode_string(_data[cursor:])
            cursor += l
        else:
            self.will_topic = None
            self.will_message = None

        if self.has_username:
            cursor += 2
            self.username, l = MQTTUtils.decode_string(_data[cursor:])
            cursor += l
        else:
            self.username = None

        if self.has_passwd:
            cursor += 2
            if cursor < self.length - 2:
                self.passwd, l = MQTTUtils.decode_string(_data[cursor:])
            else:
                self.passwd = None
        else:
            self.passwd = None
Ejemplo n.º 24
0
    def test_multi_level_mask(self):
        """
        tests for access_control.Authorization.is_subscription_allowed
        """
        multi_level = MQTTUtils.convert_to_ereg('foo/bar/#', allow_wildcards=True)

        self.assertIsMatch(multi_level, 'foo/bar')
        self.assertIsMatch(multi_level, 'foo/bar/')
        self.assertIsMatch(multi_level, 'foo/bar//')
        self.assertIsMatch(multi_level, 'foo/bar/#')

        self.assertIsMatch(multi_level, 'foo/bar/+')
        self.assertIsMatch(multi_level, 'foo/bar/+/')
        self.assertIsMatch(multi_level, 'foo/bar/+/#')

        self.assertIsMatch(multi_level, 'foo/bar/buzz/+/#')
        self.assertIsMatch(multi_level, 'foo/bar/fuzz/+/buzz/#')
Ejemplo n.º 25
0
    def from_bytes(cls, bytes_):
        assert type(bytes_) == bytes
        obj = cls()

        _raw_data = bytes(bytes_)

        obj.type, obj.dup, obj.qos, obj.retain, obj.length, remaining_data \
            = MQTTUtils.strip_fixed_header(_raw_data)

        assert obj.type == obj._message_type
        obj._decode_data(remaining_data)

        # The raw_data already corresponds to the obj field data. We change it
        # back to false to avoid encoding the data again upon raw_data lookup.
        obj._raw_data = _raw_data
        obj._pending_update = False

        return obj
Ejemplo n.º 26
0
    def test_multi_level_mask(self):
        """
        tests for access_control.Authorization.is_subscription_allowed
        """
        multi_level = MQTTUtils.convert_to_ereg('foo/bar/#',
                                                allow_wildcards=True)

        self.assertIsMatch(multi_level, 'foo/bar')
        self.assertIsMatch(multi_level, 'foo/bar/')
        self.assertIsMatch(multi_level, 'foo/bar//')
        self.assertIsMatch(multi_level, 'foo/bar/#')

        self.assertIsMatch(multi_level, 'foo/bar/+')
        self.assertIsMatch(multi_level, 'foo/bar/+/')
        self.assertIsMatch(multi_level, 'foo/bar/+/#')

        self.assertIsMatch(multi_level, 'foo/bar/buzz/+/#')
        self.assertIsMatch(multi_level, 'foo/bar/fuzz/+/buzz/#')
Ejemplo n.º 27
0
    def test_valid_subscription_masks(self):
        masks = (
            '',
            '#',
            'foo/#',
            '1/data/#',
            '1/control/user/2',
            '1/control/user/+',
            '1/control/+/2',
            '+/control/+/2',
            '+/control/+/#',
            '1/control/devices/wtcsctnfZ-1-2',
            '+',
            '+/',
            '+/#',
            '+/+',
            '+/+/',
            '+/+/#',
            '/+',
            '/+/+',
            '/+/+/#',
            'sport/tennis/player1',
            'sport/tennis/player1/ranking',
            'sport/tennis/player1/score/wimbledon',
            'sport/#',
            'sport/tennis/#',
            '+/tennis/#',
            'sport/+/player1',
            'sport/+/player1/#',
            '/',
            '//',
            '+//',
            '/+/',
            '//+',
            '/#',
            '//#',
            '+//#',
            '/+/#',
            '//+/#',
        )

        for mask in masks:
            self.assertTrue(MQTTUtils.subscription_is_valid(mask),
                            "%s is invalid" % mask)
Ejemplo n.º 28
0
    def test_mixed_masks(self):
        mixed = MQTTUtils.convert_to_ereg('foo/+/bar/#', allow_wildcards=True)
        self.assertIsMatch(mixed, 'foo/+/bar')
        self.assertIsMatch(mixed, 'foo/+/bar/#')
        self.assertIsMatch(mixed, 'foo/+/bar/buzz')
        self.assertIsMatch(mixed, 'foo/+/bar/buzz/')
        self.assertIsMatch(mixed, 'foo/+/bar/buzz/#')
        self.assertIsMatch(mixed, 'foo/+/bar/+/#')
        self.assertIsMatch(mixed, 'foo/+/bar/+/+/#')
        self.assertIsMatch(mixed, 'foo/buzz/bar')
        self.assertIsMatch(mixed, 'foo/buzz/bar/')
        self.assertIsMatch(mixed, 'foo/buzz/bar/+')
        self.assertIsMatch(mixed, 'foo/buzz/bar/#')
        self.assertIsMatch(mixed, 'foo/buzz/bar/+/')
        self.assertIsMatch(mixed, 'foo/buzz/bar/+/#')

        self.assertIsNotMatch(mixed, 'foo/#')
        self.assertIsNotMatch(mixed, 'foo/+/#')
        self.assertIsNotMatch(mixed, 'foo/+/+/#')
Ejemplo n.º 29
0
    def test_valid_subscription_masks(self):
        masks = (
            '',
            '#',
            'foo/#',
            '1/data/#',
            '1/control/user/2',
            '1/control/user/+',
            '1/control/+/2',
            '+/control/+/2',
            '+/control/+/#',
            '1/control/devices/wtcsctnfZ-1-2',
            '+',
            '+/',
            '+/#',
            '+/+',
            '+/+/',
            '+/+/#',
            '/+',
            '/+/+',
            '/+/+/#',
            'sport/tennis/player1',
            'sport/tennis/player1/ranking',
            'sport/tennis/player1/score/wimbledon',
            'sport/#',
            'sport/tennis/#',
            '+/tennis/#',
            'sport/+/player1',
            'sport/+/player1/#',
            '/',
            '//',
            '+//',
            '/+/',
            '//+',
            '/#',
            '//#',
            '+//#',
            '/+/#',
            '//+/#',
        )

        for mask in masks:
            self.assertTrue(MQTTUtils.subscription_is_valid(mask), "%s is invalid" % mask)
Ejemplo n.º 30
0
    def test_mixed_masks(self):
        mixed = MQTTUtils.convert_to_ereg('foo/+/bar/#', allow_wildcards=True)
        self.assertIsMatch(mixed, 'foo/+/bar')
        self.assertIsMatch(mixed, 'foo/+/bar/#')
        self.assertIsMatch(mixed, 'foo/+/bar/buzz')
        self.assertIsMatch(mixed, 'foo/+/bar/buzz/')
        self.assertIsMatch(mixed, 'foo/+/bar/buzz/#')
        self.assertIsMatch(mixed, 'foo/+/bar/+/#')
        self.assertIsMatch(mixed, 'foo/+/bar/+/+/#')
        self.assertIsMatch(mixed, 'foo/buzz/bar')
        self.assertIsMatch(mixed, 'foo/buzz/bar/')
        self.assertIsMatch(mixed, 'foo/buzz/bar/+')
        self.assertIsMatch(mixed, 'foo/buzz/bar/#')
        self.assertIsMatch(mixed, 'foo/buzz/bar/+/')
        self.assertIsMatch(mixed, 'foo/buzz/bar/+/#')

        self.assertIsNotMatch(mixed, 'foo/#')
        self.assertIsNotMatch(mixed, 'foo/+/#')
        self.assertIsNotMatch(mixed, 'foo/+/+/#')
Ejemplo n.º 31
0
    def subscribe(self, subscription_mask, qos):
        """
        Subscribes the client to a topic or wildcarded mask at the informed QoS
        level. Calling this method also signalizes the server to enqueue the
        matching retained messages.

        When called for a (`subscripition_mask`, `qos`) pair for which the
        client has already a subscription it will silently ignore the command
        and return a suback.

        :param string subscription_mask: A MQTT valid topic or wildcarded mask;
        :param int qos: A valid QoS level (0, 1 or 2).
        :rtype: int
        :return: The granted QoS level (0, 1 or 2) or 0x80 for failed
          subscriptions.
        """
        if qos not in [0, 1, 2]:
            self.logger.warn('client tried to subscribe with invalid qos %s' %
                             qos)
            return 0x80

        new_subscription = subscription_mask not in self.subscriptions or \
            self.subscriptions.qos(subscription_mask) != qos

        if not self.authorization.is_subscription_allowed(subscription_mask):
            self.logger.warn("[uid: %s] is not allowed to subscribe on %s" %
                             (self.uid, subscription_mask))
            del self.subscriptions[subscription_mask]
            qos = 0x80

        elif new_subscription:
            ereg = MQTTUtils.convert_to_ereg(subscription_mask)
            if ereg is not None:
                self.subscriptions.add(subscription_mask, qos,
                                       re.compile(ereg))
                self.server.enqueue_retained_message(self, subscription_mask)

            else:
                qos = 0x80
        if "#" in subscription_mask:
            print("SUBSCRIBING TO: {}".format(subscription_mask))
        return qos
Ejemplo n.º 32
0
    def test_invalid_subscription_masks(self):
        masks = (
            '##',
            '++',
            '#/',
            '/#/+',
            '+#',
            '#+',
            '+#/',
            '#+/',
            '/+#',
            '/#+',
            'sports+',
            'sports#',
            '+sports',
            '#sports',
            'sports/#/',
            'sport/tennis#',
            'sport#/tennis',
            '#sport/tennis',
            'sport/#tennis',
            'sport/tennis+',
            'sport+/tennis',
            'sport/+tennis',
            '+sport/tennis',
            '++/sport/tennis',
            'sport/++/tennis',
            'sport/tennis/++',
            '+++/sport/tennis',
            'sport/+++/tennis',
            'sport/tennis/+++',
            'sport/tennis/#/ranking',
            'sport/tennis/##/ranking',
            '#/sport/tennis/ranking',
            '##/sport/tennis/ranking',
            'sport/tennis/ranking/##',
            'sport/tennis/ranking/##/',
        )

        for mask in masks:
            self.assertFalse(MQTTUtils.subscription_is_valid(mask),
                             "%s is valid" % mask)
Ejemplo n.º 33
0
    def test_mixed_match(self):
        ereg = MQTTUtils.convert_to_ereg('foo/+/bar/#')
        self.assertIsNotNone(re.match(ereg, 'foo/xyz/bar'))
        self.assertIsNotNone(re.match(ereg, 'foo/xyz/bar/'))
        self.assertIsNotNone(re.match(ereg, 'foo/xyz/bar/abc'))
        self.assertIsNotNone(re.match(ereg, 'foo//bar'))
        self.assertIsNotNone(re.match(ereg, 'foo//bar/'))
        self.assertIsNotNone(re.match(ereg, 'foo//bar/abc'))

        self.assertIsNone(re.match(ereg, 'foo/bar'))
        self.assertIsNone(re.match(ereg, 'foo/#'))
        self.assertIsNone(re.match(ereg, 'foo/+/bar'))
        self.assertIsNone(re.match(ereg, 'foo/+/bar/#'))
        self.assertIsNone(re.match(ereg, 'foo/+/bar/abc'))
        self.assertIsNone(re.match(ereg, 'foo/+/bar/abc/'))
        self.assertIsNone(re.match(ereg, 'foo/+/bar/abc/#'))
        self.assertIsNone(re.match(ereg, 'foo/+/bar/+/#'))
        self.assertIsNone(re.match(ereg, 'foo/xyz/bar/#'))
        self.assertIsNone(re.match(ereg, 'foo/xyz/bar/+'))
        self.assertIsNone(re.match(ereg, 'foo/xyz/bar/+/#'))
Ejemplo n.º 34
0
    def test_mixed_match(self):
        ereg = MQTTUtils.convert_to_ereg('foo/+/bar/#')
        self.assertIsNotNone(re.match(ereg, 'foo/xyz/bar'))
        self.assertIsNotNone(re.match(ereg, 'foo/xyz/bar/'))
        self.assertIsNotNone(re.match(ereg, 'foo/xyz/bar/abc'))
        self.assertIsNotNone(re.match(ereg, 'foo//bar'))
        self.assertIsNotNone(re.match(ereg, 'foo//bar/'))
        self.assertIsNotNone(re.match(ereg, 'foo//bar/abc'))

        self.assertIsNone(re.match(ereg, 'foo/bar'))
        self.assertIsNone(re.match(ereg, 'foo/#'))
        self.assertIsNone(re.match(ereg, 'foo/+/bar'))
        self.assertIsNone(re.match(ereg, 'foo/+/bar/#'))
        self.assertIsNone(re.match(ereg, 'foo/+/bar/abc'))
        self.assertIsNone(re.match(ereg, 'foo/+/bar/abc/'))
        self.assertIsNone(re.match(ereg, 'foo/+/bar/abc/#'))
        self.assertIsNone(re.match(ereg, 'foo/+/bar/+/#'))
        self.assertIsNone(re.match(ereg, 'foo/xyz/bar/#'))
        self.assertIsNone(re.match(ereg, 'foo/xyz/bar/+'))
        self.assertIsNone(re.match(ereg, 'foo/xyz/bar/+/#'))
Ejemplo n.º 35
0
    def subscribe(self, subscription_mask, qos):
        """
        Subscribes the client to a topic or wildcarded mask at the informed QoS
        level. Calling this method also signalizes the server to enqueue the
        matching retained messages.

        When called for a (`subscripition_mask`, `qos`) pair for which the
        client has already a subscription it will silently ignore the command
        and return a suback.

        :param string subscription_mask: A MQTT valid topic or wildcarded mask;
        :param int qos: A valid QoS level (0, 1 or 2).
        :rtype: int
        :return: The granted QoS level (0, 1 or 2) or 0x80 for failed
          subscriptions.
        """
        if qos not in [0, 1, 2]:
            self.logger.warn('client tried to subscribe with invalid qos %s' % qos)
            return 0x80

        new_subscription = subscription_mask not in self.subscriptions or \
            self.subscriptions.qos(subscription_mask) != qos

        if not self.authorization.is_subscription_allowed(subscription_mask):
            self.logger.warn("[uid: %s] is not allowed to subscribe on %s" %
                             (self.uid, subscription_mask))
            del self.subscriptions[subscription_mask]
            qos = 0x80

        elif new_subscription:
            ereg = MQTTUtils.convert_to_ereg(subscription_mask)
            if ereg is not None:
                self.subscriptions.add(subscription_mask, qos, re.compile(ereg))
                self.server.enqueue_retained_message(self, subscription_mask)

            else:
                qos = 0x80
        if "#" in subscription_mask:
            print("SUBSCRIBING TO: {}".format(subscription_mask))
        return qos
Ejemplo n.º 36
0
 def add(self, mask, qos, pattern=None):
     self._re_cache[mask] = pattern or re.compile(
         MQTTUtils.convert_to_ereg(mask))
     self._subscriptions[mask] = qos
Ejemplo n.º 37
0
    def _decode_data(self, _data):
        cursor = 0
        self.id = MQTTUtils.decode_value(_data[cursor:cursor + 2])
        cursor += 2

        self.payload = _data[cursor:]
Ejemplo n.º 38
0
 def _encode_data(self):
     return bytes(MQTTUtils.encode_value(self.id))
Ejemplo n.º 39
0
 def __hash__(self):
     return MQTTUtils.hash_message_bytes(self.raw_data)
Ejemplo n.º 40
0
 def _decode_data(self, _data):
     self.id = MQTTUtils.decode_value(_data[0:2])
Ejemplo n.º 41
0
    def _encode_data(self):
        buffer = bytearray()
        buffer.extend(self.id)

        for topic in self.unsubscribe_list:
            buffer.extend(MQTTUtils.encode_string(topic))
Ejemplo n.º 42
0
 def add(self, mask, qos, pattern=None):
     self._re_cache[mask] = pattern or re.compile(MQTTUtils.convert_to_ereg(mask))
     self._subscriptions[mask] = qos
Ejemplo n.º 43
0
    def _encode_data(self):
        buffer = bytearray()
        buffer.extend(MQTTUtils.encode_value(self.id))
        buffer.extend(self.payload)

        return bytes(buffer)
Ejemplo n.º 44
0
 def _encode_data(self):
     buffer = bytearray()
     sp = self.SESSION_PRESENT if self.session_present else 0x00
     buffer.append(MQTTUtils.encode_byte(sp))
     buffer.append(MQTTUtils.encode_byte(self.return_code))
     return bytes(buffer)