Example #1
0
    def test_with_key(self):
        self.ably = RestSetup.get_ably_rest(use_binary_protocol=self.use_binary_protocol)

        token_details = self.ably.auth.request_token()
        assert isinstance(token_details, TokenDetails)

        ably = RestSetup.get_ably_rest(key=None, token_details=token_details,
                                       use_binary_protocol=self.use_binary_protocol)
        channel = self.get_channel_name('test_request_token_with_key')

        ably.channels[channel].publish('event', 'foo')

        assert ably.channels[channel].history().items[0].data == 'foo'
Example #2
0
    def test_idempotent_rest_publishing(self):
        # Test default value
        if api_version < '1.2':
            assert self.ably.options.idempotent_rest_publishing is False
        else:
            assert self.ably.options.idempotent_rest_publishing is True

        # Test setting value explicitly
        ably = RestSetup.get_ably_rest(idempotent_rest_publishing=True)
        assert ably.options.idempotent_rest_publishing is True

        ably = RestSetup.get_ably_rest(idempotent_rest_publishing=False)
        assert ably.options.idempotent_rest_publishing is False
    def test_idempotent_rest_publishing(self):
        # Test default value
        if api_version < '1.2':
            assert self.ably.options.idempotent_rest_publishing is False
        else:
            assert self.ably.options.idempotent_rest_publishing is True

        # Test setting value explicitly
        ably = RestSetup.get_ably_rest(idempotent_rest_publishing=True)
        assert ably.options.idempotent_rest_publishing is True

        ably = RestSetup.get_ably_rest(idempotent_rest_publishing=False)
        assert ably.options.idempotent_rest_publishing is False
Example #4
0
    def setUpClass(cls):
        RestSetup._RestSetup__test_vars = None
        cls.ably = RestSetup.get_ably_rest()
        cls.ably_text = RestSetup.get_ably_rest(use_binary_protocol=False)

        cls.last_year = datetime.now().year - 1
        cls.previous_year = datetime.now().year - 2
        cls.last_interval = datetime(cls.last_year, 2, 3, 15, 5)
        cls.previous_interval = datetime(cls.previous_year, 2, 3, 15, 5)
        previous_year_stats = 120
        stats = [
            {
                'intervalId': Stats.to_interval_id(cls.last_interval -
                                                   timedelta(minutes=2),
                                                   'minute'),
                'inbound': {'realtime': {'messages': {'count': 50, 'data': 5000}}},
                'outbound': {'realtime': {'messages': {'count': 20, 'data': 2000}}}
            },
            {
                'intervalId': Stats.to_interval_id(cls.last_interval - timedelta(minutes=1),
                                                   'minute'),
                'inbound': {'realtime': {'messages': {'count': 60, 'data': 6000}}},
                'outbound': {'realtime': {'messages': {'count': 10, 'data': 1000}}}
            },
            {
                'intervalId': Stats.to_interval_id(cls.last_interval, 'minute'),
                'inbound': {'realtime': {'messages': {'count': 70, 'data': 7000}}},
                'outbound': {'realtime': {'messages': {'count': 40, 'data': 4000}}},
                'persisted': {'presence': {'count': 20, 'data': 2000}},
                'connections': {'tls':   {'peak': 20, 'opened': 10}},
                'channels': {'peak': 50, 'opened': 30},
                'apiRequests': {'succeeded': 50, 'failed': 10},
                'tokenRequests': {'succeeded': 60, 'failed': 20},
            }
        ]

        previous_stats = []
        for i in range(previous_year_stats):
            previous_stats.append(
                {
                    'intervalId': Stats.to_interval_id(cls.previous_interval -
                                                       timedelta(minutes=i),
                                                       'minute'),
                    'inbound':  {'realtime': {'messages': {'count': i}}}
                }
            )

        cls.ably.http.post('/stats', body=stats + previous_stats)
Example #5
0
    def test_cached_fallback(self):
        timeout = 2000
        ably = RestSetup.get_ably_rest(fallback_hosts_use_default=True,
                                       fallback_retry_timeout=timeout)
        host = ably.options.get_rest_host()

        state = {'errors': 0}
        send = requests.sessions.Session.send

        def side_effect(self, prepped, *args, **kwargs):
            if urlparse(prepped.url).hostname == host:
                state['errors'] += 1
                raise RuntimeError
            return send(self, prepped, *args, **kwargs)

        with mock.patch('requests.sessions.Session.send',
                        side_effect=side_effect,
                        autospec=True):
            # The main host is called and there's an error
            ably.time()
            assert state['errors'] == 1

            # The cached host is used: no error
            ably.time()
            ably.time()
            ably.time()
            assert state['errors'] == 1

            # The cached host has expired, we've an error again
            time.sleep(timeout / 1000.0)
            ably.time()
            assert state['errors'] == 2
Example #6
0
    def test_with_key(self):
        self.ably = RestSetup.get_ably_rest(
            use_binary_protocol=self.use_binary_protocol)

        token_details = self.ably.auth.request_token()
        assert isinstance(token_details, TokenDetails)

        ably = RestSetup.get_ably_rest(
            key=None,
            token_details=token_details,
            use_binary_protocol=self.use_binary_protocol)
        channel = self.get_channel_name('test_request_token_with_key')

        ably.channels[channel].publish('event', 'foo')

        assert ably.channels[channel].history().items[0].data == 'foo'
Example #7
0
    def setUp(self):
        self.ably = RestSetup.get_ably_rest(use_binary_protocol=False)

        # Mocked responses
        # without headers
        responses.add(responses.GET,
                      'http://rest.ably.io/channels/channel_name/ch1',
                      body='[{"id": 0}, {"id": 1}]', status=200,
                      content_type='application/json')
        # with headers
        responses.add_callback(
            responses.GET,
            'http://rest.ably.io/channels/channel_name/ch2',
            self.get_response_callback(
                headers={
                    'link':
                    '<http://rest.ably.io/channels/channel_name/ch2?page=1>; rel="first",'
                    ' <http://rest.ably.io/channels/channel_name/ch2?page=2>; rel="next"'
                },
                body='[{"id": 0}, {"id": 1}]',
                status=200),
            content_type='application/json')

        # start intercepting requests
        responses.start()

        self.paginated_result = PaginatedResult.paginated_query(
            self.ably.http,
            url='http://rest.ably.io/channels/channel_name/ch1',
            response_processor=lambda response: response.to_native())
        self.paginated_result_with_headers = PaginatedResult.paginated_query(
            self.ably.http,
            url='http://rest.ably.io/channels/channel_name/ch2',
            response_processor=lambda response: response.to_native())
Example #8
0
 def test_request_token_with_specified_key(self):
     key = RestSetup.get_test_vars()["keys"][1]
     token_details = self.ably.auth.request_token(
         key_name=key["key_name"], key_secret=key["key_secret"])
     assert token_details.token is not None, "Expected token"
     assert key.get(
         "capability") == token_details.capability, "Unexpected capability"
Example #9
0
    def test_without_permissions(self):
        key = test_vars["keys"][2]
        ably = RestSetup.get_ably_rest(key=key["key_str"])
        with pytest.raises(AblyException) as excinfo:
            ably.channels['test_publish_without_permission'].publish('foo', 'woop')

        assert 'not permitted' in excinfo.value.message
Example #10
0
    def test_with_auth_url_headers_and_params_POST(self):
        url = 'http://www.example.com'
        headers = {'foo': 'bar'}
        self.ably = RestSetup.get_ably_rest(key=None, auth_url=url)

        auth_params = {'foo': 'auth', 'spam': 'eggs'}
        token_params = {'foo': 'token'}

        responses.add(responses.POST, url, body='token_string')
        token_details = self.ably.auth.request_token(token_params=token_params,
                                                     auth_url=url,
                                                     auth_headers=headers,
                                                     auth_method='POST',
                                                     auth_params=auth_params)

        assert isinstance(token_details, TokenDetails)
        assert len(responses.calls) == 1
        request = responses.calls[0].request
        assert request.headers[
            'content-type'] == 'application/x-www-form-urlencoded'
        assert headers['foo'] == request.headers['foo']
        assert urlparse(request.url).query == ''  # No querystring!
        assert parse_qs(request.body) == {
            'foo': ['token'],
            'spam': ['eggs']
        }  # TokenParams has precedence
        assert 'token_string' == token_details.token
Example #11
0
    def test_with_auth_url_headers_and_params_GET(self):

        url = 'http://www.example.com'
        headers = {'foo': 'bar'}
        self.ably = RestSetup.get_ably_rest(
            key=None,
            auth_url=url,
            auth_headers={'this': 'will_not_be_used'},
            auth_params={'this': 'will_not_be_used'})

        auth_params = {'foo': 'auth', 'spam': 'eggs'}
        token_params = {'foo': 'token'}

        responses.add(responses.GET,
                      url,
                      json={
                          'issued': 1,
                          'token': 'another_token_string'
                      })
        token_details = self.ably.auth.request_token(token_params=token_params,
                                                     auth_url=url,
                                                     auth_headers=headers,
                                                     auth_params=auth_params)
        assert 'another_token_string' == token_details.token
        request = responses.calls[0].request
        assert request.headers['foo'] == 'bar'
        assert 'this' not in request.headers
        assert parse_qs(urlparse(request.url).query) == {
            'foo': ['token'],
            'spam': ['eggs']
        }
        assert not request.body
Example #12
0
    def test_wildcard_client_id_can_publish_as_others(self):
        wildcard_token_details = self.ably.auth.request_token(
            {'client_id': '*'})
        wildcard_ably = RestSetup.get_ably_rest(
            key=None,
            token_details=wildcard_token_details,
            use_binary_protocol=self.use_binary_protocol)

        assert wildcard_ably.auth.client_id == '*'
        channel = wildcard_ably.channels[self.get_channel_name(
            'persisted:wildcard_client_id')]
        channel.publish(name='publish1', data='no client_id')
        some_client_id = uuid.uuid4().hex
        channel.publish(name='publish2',
                        data='some client_id',
                        client_id=some_client_id)

        history = channel.history()
        messages = history.items

        assert messages is not None, "Expected non-None messages"
        assert len(messages) == 2, "Expected 2 messages"

        assert messages[0].client_id == some_client_id
        assert messages[1].client_id is None
 def test_request_token_with_specified_key(self):
     key = RestSetup.get_test_vars()["keys"][1]
     token_details = self.ably.auth.request_token(
         key_name=key["key_name"], key_secret=key["key_secret"])
     self.assertIsNotNone(token_details.token, msg="Expected token")
     self.assertEqual(key.get("capability"),
                      token_details.capability,
                      msg="Unexpected capability")
Example #14
0
    def test_time_accuracy(self):
        ably = RestSetup.get_ably_rest(use_binary_protocol=self.use_binary_protocol)

        reported_time = ably.time()
        actual_time = time.time() * 1000.0

        seconds = 10
        assert abs(actual_time - reported_time) < seconds * 1000, "Time is not within %s seconds" % seconds
Example #15
0
 def test_key_name_and_secret_are_required(self):
     ably = RestSetup.get_ably_rest(key=None, token='not a real token')
     with pytest.raises(AblyException, match="40101 401 No key specified"):
         ably.auth.create_token_request()
     with pytest.raises(AblyException, match="40101 401 No key specified"):
         ably.auth.create_token_request(key_name=self.key_name)
     with pytest.raises(AblyException, match="40101 401 No key specified"):
         ably.auth.create_token_request(key_secret=self.key_secret)
Example #16
0
 def test_key_name_and_secret_are_required(self):
     ably = RestSetup.get_ably_rest(key=None, token='not a real token')
     with pytest.raises(AblyException, match="40101 401 No key specified"):
         ably.auth.create_token_request()
     with pytest.raises(AblyException, match="40101 401 No key specified"):
         ably.auth.create_token_request(key_name=self.key_name)
     with pytest.raises(AblyException, match="40101 401 No key specified"):
         ably.auth.create_token_request(key_secret=self.key_secret)
Example #17
0
    def setUpClass(cls):
        cls.ably = RestSetup.get_ably_rest()

        # Populate the channel (using the new api)
        cls.channel = cls.get_channel_name()
        cls.path = '/channels/%s/messages' % cls.channel
        for i in range(20):
            body = {'name': 'event%s' % i, 'data': 'lorem ipsum %s' % i}
            cls.ably.request('POST', cls.path, body=body)
Example #18
0
    def test_time_without_key_or_token(self):
        ably = RestSetup.get_ably_rest(key=None, token='foo',
                                       use_binary_protocol=self.use_binary_protocol)

        reported_time = ably.time()
        actual_time = time.time() * 1000.0

        seconds = 10
        assert abs(actual_time - reported_time) < seconds * 1000, "Time is not within %s seconds" % seconds
Example #19
0
 def test_with_token_str_http(self):
     token = self.ably.auth.authorize()
     token = token.token
     ably = RestSetup.get_ably_rest(
         key=None,
         token=token,
         tls=False,
         use_binary_protocol=self.use_binary_protocol)
     ably.channels.test_auth_with_token_str.publish('event', 'foo_bar')
Example #20
0
    def setUpClass(cls):
        cls.ably = RestSetup.get_ably_rest()

        # Populate the channel (using the new api)
        cls.channel = cls.get_channel_name()
        cls.path = '/channels/%s/messages' % cls.channel
        for i in range(20):
            body = {'name': 'event%s' % i, 'data': 'lorem ipsum %s' % i}
            cls.ably.request('POST', cls.path, body=body)
Example #21
0
    def test_query_time_param(self):
        ably = RestSetup.get_ably_rest(query_time=True,
                                       use_binary_protocol=self.use_binary_protocol)

        timestamp = ably.auth._timestamp
        with patch('ably.rest.rest.AblyRest.time', wraps=ably.time) as server_time,\
                patch('ably.rest.auth.Auth._timestamp', wraps=timestamp) as local_time:
            ably.auth.request_token()
            assert not local_time.called
            assert server_time.called
Example #22
0
    def test_client_id_null_for_anonymous_auth(self):
        ably = RestSetup.get_ably_rest(
            key=None,
            key_name=test_vars["keys"][0]["key_name"],
            key_secret=test_vars["keys"][0]["key_secret"])
        token = ably.auth.authorize()

        assert isinstance(token, TokenDetails)
        assert token.client_id is None
        assert ably.auth.client_id is None
Example #23
0
    def test_query_time_param(self):
        ably = RestSetup.get_ably_rest(
            query_time=True, use_binary_protocol=self.use_binary_protocol)

        timestamp = ably.auth._timestamp
        with patch('ably.rest.rest.AblyRest.time', wraps=ably.time) as server_time,\
                patch('ably.rest.auth.Auth._timestamp', wraps=timestamp) as local_time:
            ably.auth.request_token()
            assert not local_time.called
            assert server_time.called
Example #24
0
    def test_client_id_null_for_anonymous_auth(self):
        ably = RestSetup.get_ably_rest(
            key=None,
            key_name=test_vars["keys"][0]["key_name"],
            key_secret=test_vars["keys"][0]["key_secret"])
        token = ably.auth.authorize()

        assert isinstance(token, TokenDetails)
        assert token.client_id is None
        assert ably.auth.client_id is None
    def test_publish_error(self):
        ably = RestSetup.get_ably_rest(use_binary_protocol=self.use_binary_protocol)
        ably.auth.authorize(
            token_params={'capability': {"only_subscribe": ["subscribe"]}})

        with pytest.raises(AblyException) as excinfo:
            ably.channels["only_subscribe"].publish()

        assert 401 == excinfo.value.status_code
        assert 40160 == excinfo.value.code
Example #26
0
    def test_time_accuracy(self):
        ably = RestSetup.get_ably_rest(
            use_binary_protocol=self.use_binary_protocol)

        reported_time = ably.time()
        actual_time = time.time() * 1000.0

        seconds = 10
        assert abs(
            actual_time - reported_time
        ) < seconds * 1000, "Time is not within %s seconds" % seconds
Example #27
0
    def test_when_auth_url_has_query_string(self):
        url = 'http://www.example.com?with=query'
        headers = {'foo': 'bar'}
        self.ably = RestSetup.get_ably_rest(key=None, auth_url=url)

        responses.add(responses.GET, 'http://www.example.com',
                      body='token_string')
        self.ably.auth.request_token(auth_url=url,
                                     auth_headers=headers,
                                     auth_params={'spam': 'eggs'})
        assert responses.calls[0].request.url.endswith('?with=query&spam=eggs')
Example #28
0
    def test_when_auth_url_has_query_string(self):
        url = 'http://www.example.com?with=query'
        headers = {'foo': 'bar'}
        self.ably = RestSetup.get_ably_rest(key=None, auth_url=url)

        responses.add(responses.GET,
                      'http://www.example.com',
                      body='token_string')
        self.ably.auth.request_token(auth_url=url,
                                     auth_headers=headers,
                                     auth_params={'spam': 'eggs'})
        assert responses.calls[0].request.url.endswith('?with=query&spam=eggs')
Example #29
0
    def test_token_request_dict_can_be_used_to_get_a_token(self):
        token_request = self.ably.auth.create_token_request(
            key_name=self.key_name, key_secret=self.key_secret)
        assert isinstance(token_request, TokenRequest)

        ably = RestSetup.get_ably_rest(
            key=None,
            auth_callback=lambda x: token_request.to_dict(),
            use_binary_protocol=self.use_binary_protocol)

        token = ably.auth.authorize()
        assert isinstance(token, TokenDetails)
Example #30
0
    def test_client_id_null_until_auth(self):
        client_id = uuid.uuid4().hex
        token_ably = RestSetup.get_ably_rest(
            default_token_params={'client_id': client_id})
        # before auth, client_id is None
        assert token_ably.auth.client_id is None

        token = token_ably.auth.authorize()
        assert isinstance(token, TokenDetails)

        # after auth, client_id is defined
        assert token.client_id == client_id
        assert token_ably.auth.client_id == client_id
Example #31
0
    def test_publish_error(self):
        ably = RestSetup.get_ably_rest(
            use_binary_protocol=self.use_binary_protocol)
        ably.auth.authorize(
            token_params={'capability': {
                "only_subscribe": ["subscribe"]
            }})

        with pytest.raises(AblyException) as excinfo:
            ably.channels["only_subscribe"].publish()

        assert 401 == excinfo.value.status_code
        assert 40160 == excinfo.value.code
Example #32
0
    def test_time_without_key_or_token(self):
        ably = RestSetup.get_ably_rest(
            key=None,
            token='foo',
            use_binary_protocol=self.use_binary_protocol)

        reported_time = ably.time()
        actual_time = time.time() * 1000.0

        seconds = 10
        assert abs(
            actual_time - reported_time
        ) < seconds * 1000, "Time is not within %s seconds" % seconds
Example #33
0
    def test_client_id_null_until_auth(self):
        client_id = uuid.uuid4().hex
        token_ably = RestSetup.get_ably_rest(
            default_token_params={'client_id': client_id})
        # before auth, client_id is None
        assert token_ably.auth.client_id is None

        token = token_ably.auth.authorize()
        assert isinstance(token, TokenDetails)

        # after auth, client_id is defined
        assert token.client_id == client_id
        assert token_ably.auth.client_id == client_id
    def test_publish_message_with_wrong_client_id_on_implicit_identified_client(self):
        new_token = self.ably.auth.authorize(
            token_params={'client_id': uuid.uuid4().hex})
        new_ably = RestSetup.get_ably_rest(key=None, token=new_token.token,
                                           use_binary_protocol=self.use_binary_protocol)
        channel = new_ably.channels[
            self.get_channel_name('persisted:wrong_client_id_implicit_client')]

        with pytest.raises(AblyException) as excinfo:
            channel.publish(name='publish', data='test', client_id='invalid')

        assert 400 == excinfo.value.status_code
        assert 40012 == excinfo.value.code
Example #35
0
    def test_token_request_can_be_used_to_get_a_token(self):
        token_request = self.ably.auth.create_token_request(
            key_name=self.key_name, key_secret=self.key_secret)
        assert isinstance(token_request, TokenRequest)

        def auth_callback(token_params):
            return token_request

        ably = RestSetup.get_ably_rest(key=None, auth_callback=auth_callback,
                                       use_binary_protocol=self.use_binary_protocol)

        token = ably.auth.authorize()

        assert isinstance(token, TokenDetails)
Example #36
0
    def setUpClass(cls):
        cls.ably = RestSetup.get_ably_rest()

        # Register several devices for later use
        cls.devices = {}
        for i in range(10):
            cls.save_device()

        # Register several subscriptions for later use
        cls.channels = {'canpublish:test1': [], 'canpublish:test2': [], 'canpublish:test3': []}
        for key, channel in zip(cls.devices, itertools.cycle(cls.channels)):
            device = cls.devices[key]
            cls.save_subscription(channel, device_id=device.id)
        assert len(list(itertools.chain(*cls.channels.values()))) == len(cls.devices)
Example #37
0
    def test_when_not_renewable(self):
        self.ably = RestSetup.get_ably_rest(
            key=None,
            token='token ID cannot be used to create a new token',
            use_binary_protocol=False)
        self.ably.channels[self.channel].publish('evt', 'msg')
        assert 1 == self.publish_attempts

        publish = self.ably.channels[self.channel].publish

        with pytest.raises(AblyAuthException, match="The provided token is not renewable and there is no means to generate a new token"):
            publish('evt', 'msg')

        assert 0 == self.token_requests
Example #38
0
    def setUpClass(cls):
        cls.ably = RestSetup.get_ably_rest()

        # Register several devices for later use
        cls.devices = {}
        for i in range(10):
            cls.save_device()

        # Register several subscriptions for later use
        cls.channels = {'canpublish:test1': [], 'canpublish:test2': [], 'canpublish:test3': []}
        for key, channel in zip(cls.devices, itertools.cycle(cls.channels)):
            device = cls.devices[key]
            cls.save_subscription(channel, device_id=device.id)
        assert len(list(itertools.chain(*cls.channels.values()))) == len(cls.devices)
Example #39
0
    def test_when_not_renewable_with_token_details(self):
        token_details = TokenDetails(token='a_dummy_token')
        self.ably = RestSetup.get_ably_rest(key=None,
                                            token_details=token_details,
                                            use_binary_protocol=False)
        self.ably.channels[self.channel].publish('evt', 'msg')
        assert 1 == self.publish_attempts

        publish = self.ably.channels[self.channel].publish

        match = "The provided token is not renewable and there is no means to generate a new token"
        with pytest.raises(AblyAuthException, match=match):
            publish('evt', 'msg')

        assert 0 == self.token_requests
Example #40
0
    def test_client_id_precedence(self):
        client_id = uuid.uuid4().hex
        overridden_client_id = uuid.uuid4().hex
        ably = RestSetup.get_ably_rest(
            use_binary_protocol=self.use_binary_protocol,
            client_id=client_id,
            default_token_params={'client_id': overridden_client_id})
        token = ably.auth.authorize()
        assert token.client_id == client_id
        assert ably.auth.client_id == client_id

        channel = ably.channels[
            self.get_channel_name('test_client_id_precedence')]
        channel.publish('test', 'data')
        assert channel.history().items[0].client_id == client_id
Example #41
0
    def test_client_id_precedence(self):
        client_id = uuid.uuid4().hex
        overridden_client_id = uuid.uuid4().hex
        ably = RestSetup.get_ably_rest(
            use_binary_protocol=self.use_binary_protocol,
            client_id=client_id,
            default_token_params={'client_id': overridden_client_id})
        token = ably.auth.authorize()
        assert token.client_id == client_id
        assert ably.auth.client_id == client_id

        channel = ably.channels[self.get_channel_name(
            'test_client_id_precedence')]
        channel.publish('test', 'data')
        assert channel.history().items[0].client_id == client_id
Example #42
0
    def test_publish_message_with_wrong_client_id_on_implicit_identified_client(
            self):
        new_token = self.ably.auth.authorize(
            token_params={'client_id': uuid.uuid4().hex})
        new_ably = RestSetup.get_ably_rest(
            key=None,
            token=new_token.token,
            use_binary_protocol=self.use_binary_protocol)
        channel = new_ably.channels[self.get_channel_name(
            'persisted:wrong_client_id_implicit_client')]

        with pytest.raises(AblyException) as excinfo:
            channel.publish(name='publish', data='test', client_id='invalid')

        assert 400 == excinfo.value.status_code
        assert 40012 == excinfo.value.code
Example #43
0
    def test_capability(self):
        capability = Capability({'channel': ['publish']})
        token_request = self.ably.auth.create_token_request(
            key_name=self.key_name, key_secret=self.key_secret,
            token_params={'capability': capability})
        assert token_request.capability == str(capability)

        def auth_callback(token_params):
            return token_request

        ably = RestSetup.get_ably_rest(key=None, auth_callback=auth_callback,
                                       use_binary_protocol=self.use_binary_protocol)

        token = ably.auth.authorize()

        assert str(token.capability) == str(capability)
Example #44
0
    def test_request_headers(self):
        ably = RestSetup.get_ably_rest()
        r = ably.http.make_request('HEAD', '/time', skip_auth=True)

        # API
        assert 'X-Ably-Version' in r.request.headers
        assert r.request.headers['X-Ably-Version'] == '1.0'

        # Lib
        assert 'X-Ably-Lib' in r.request.headers
        expr = r"^python-1\.0\.\d+(-\w+)?$"
        assert re.search(expr, r.request.headers['X-Ably-Lib'])

        # Lib Variant
        ably.set_variant('django')
        r = ably.http.make_request('HEAD', '/time', skip_auth=True)
        expr = r"^python.django-1\.0\.\d+(-\w+)?$"
        assert re.search(expr, r.request.headers['X-Ably-Lib'])
Example #45
0
    def test_when_not_renewable(self):
        self.ably = RestSetup.get_ably_rest(
            key=None,
            token='token ID cannot be used to create a new token',
            use_binary_protocol=False)
        self.ably.channels[self.channel].publish('evt', 'msg')
        assert 1 == self.publish_attempts

        publish = self.ably.channels[self.channel].publish

        with pytest.raises(
                AblyAuthException,
                match=
                "The provided token is not renewable and there is no means to generate a new token"
        ):
            publish('evt', 'msg')

        assert 0 == self.token_requests
Example #46
0
    def test_request_headers(self):
        ably = RestSetup.get_ably_rest()
        r = ably.http.make_request('HEAD', '/time', skip_auth=True)

        # API
        assert 'X-Ably-Version' in r.request.headers
        assert r.request.headers['X-Ably-Version'] == '1.0'

        # Lib
        assert 'X-Ably-Lib' in r.request.headers
        expr = r"^python-1\.0\.\d+(-\w+)?$"
        assert re.search(expr, r.request.headers['X-Ably-Lib'])

        # Lib Variant
        ably.set_variant('django')
        r = ably.http.make_request('HEAD', '/time', skip_auth=True)
        expr = r"^python.django-1\.0\.\d+(-\w+)?$"
        assert re.search(expr, r.request.headers['X-Ably-Lib'])
Example #47
0
    def setUp(self):
        host = test_vars['host']
        self.ably = RestSetup.get_ably_rest(use_binary_protocol=False)
        # with headers
        self.token_requests = 0
        self.publish_attempts = 0
        self.tokens = ['a_token', 'another_token']
        self.channel = uuid.uuid4().hex

        def call_back(request):
            headers = {'Content-Type': 'application/json'}
            body = {}
            self.token_requests += 1
            body['token'] = self.tokens[self.token_requests - 1]
            body['expires'] = (time.time() + 60) * 1000
            return (200, headers, json.dumps(body))

        responses.add_callback(
            responses.POST, 'https://{}:443/keys/{}/requestToken'.format(
                host, test_vars["keys"][0]['key_name']), call_back)

        def call_back(request):
            headers = {'Content-Type': 'application/json'}
            self.publish_attempts += 1
            if self.publish_attempts in [1, 3]:
                body = '[]'
                status = 201
            else:
                body = {
                    'error': {
                        'message': 'Authentication failure',
                        'statusCode': 401,
                        'code': 40140
                    }
                }
                status = 401

            return (status, headers, json.dumps(body))

        responses.add_callback(
            responses.POST,
            'https://{}:443/channels/{}/messages'.format(host, self.channel),
            call_back)
        responses.start()
Example #48
0
    def test_auth_init_with_token_callback(self):
        callback_called = []

        def token_callback(token_params):
            callback_called.append(True)
            return "this_is_not_really_a_token_request"

        ably = RestSetup.get_ably_rest(
            key=None,
            key_name=test_vars["keys"][0]["key_name"],
            auth_callback=token_callback)

        try:
            ably.stats(None)
        except Exception:
            pass

        assert callback_called, "Token callback not called"
        assert Auth.Method.TOKEN == ably.auth.auth_mechanism, "Unexpected Auth method mismatch"
Example #49
0
    def test_capability(self):
        capability = Capability({'channel': ['publish']})
        token_request = self.ably.auth.create_token_request(
            key_name=self.key_name,
            key_secret=self.key_secret,
            token_params={'capability': capability})
        assert token_request.capability == str(capability)

        def auth_callback(token_params):
            return token_request

        ably = RestSetup.get_ably_rest(
            key=None,
            auth_callback=auth_callback,
            use_binary_protocol=self.use_binary_protocol)

        token = ably.auth.authorize()

        assert str(token.capability) == str(capability)
Example #50
0
    def test_auth_init_with_token_callback(self):
        callback_called = []

        def token_callback(token_params):
            callback_called.append(True)
            return "this_is_not_really_a_token_request"

        ably = RestSetup.get_ably_rest(
            key=None,
            key_name=test_vars["keys"][0]["key_name"],
            auth_callback=token_callback)

        try:
            ably.stats(None)
        except Exception:
            pass

        assert callback_called, "Token callback not called"
        assert Auth.Method.TOKEN == ably.auth.auth_mechanism, "Unexpected Auth method mismatch"
Example #51
0
    def test_with_callback(self):
        called_token_params = {'ttl': '3600000'}
        def callback(token_params):
            assert token_params == called_token_params
            return 'token_string'

        self.ably = RestSetup.get_ably_rest(key=None, auth_callback=callback)

        token_details = self.ably.auth.request_token(
            token_params=called_token_params, auth_callback=callback)
        assert isinstance(token_details, TokenDetails)
        assert 'token_string' == token_details.token

        def callback(token_params):
            assert token_params == called_token_params
            return TokenDetails(token='another_token_string')

        token_details = self.ably.auth.request_token(
            token_params=called_token_params, auth_callback=callback)
        assert 'another_token_string' == token_details.token
Example #52
0
    def test_with_auth_url_headers_and_params_POST(self):
        url = 'http://www.example.com'
        headers = {'foo': 'bar'}
        self.ably = RestSetup.get_ably_rest(key=None, auth_url=url)

        auth_params = {'foo': 'auth', 'spam': 'eggs'}
        token_params = {'foo': 'token'}

        responses.add(responses.POST, url, body='token_string')
        token_details = self.ably.auth.request_token(
            token_params=token_params, auth_url=url, auth_headers=headers,
            auth_method='POST', auth_params=auth_params)

        assert isinstance(token_details, TokenDetails)
        assert len(responses.calls) == 1
        request = responses.calls[0].request
        assert request.headers['content-type'] == 'application/x-www-form-urlencoded'
        assert headers['foo'] == request.headers['foo']
        assert urlparse(request.url).query == ''  # No querystring!
        assert parse_qs(request.body) == {'foo': ['token'], 'spam': ['eggs']}  # TokenParams has precedence
        assert 'token_string' == token_details.token
Example #53
0
    def setUp(self):
        host = test_vars['host']
        self.ably = RestSetup.get_ably_rest(use_binary_protocol=False)
        # with headers
        self.token_requests = 0
        self.publish_attempts = 0
        self.tokens = ['a_token', 'another_token']
        self.channel = uuid.uuid4().hex

        def call_back(request):
            headers = {'Content-Type': 'application/json'}
            body = {}
            self.token_requests += 1
            body['token'] = self.tokens[self.token_requests - 1]
            body['expires'] = (time.time() + 60) * 1000
            return (200, headers, json.dumps(body))

        responses.add_callback(
            responses.POST,
            'https://{}:443/keys/{}/requestToken'.format(
                host, test_vars["keys"][0]['key_name']),
            call_back)

        def call_back(request):
            headers = {'Content-Type': 'application/json'}
            self.publish_attempts += 1
            if self.publish_attempts in [1, 3]:
                body = '[]'
                status = 201
            else:
                body = {'error': {'message': 'Authentication failure', 'statusCode': 401, 'code': 40140}}
                status = 401

            return (status, headers, json.dumps(body))

        responses.add_callback(
            responses.POST,
            'https://{}:443/channels/{}/messages'.format(host, self.channel),
            call_back)
        responses.start()
Example #54
0
    def test_with_auth_url_headers_and_params_GET(self):

        url = 'http://www.example.com'
        headers = {'foo': 'bar'}
        self.ably = RestSetup.get_ably_rest(
            key=None, auth_url=url,
            auth_headers={'this': 'will_not_be_used'},
            auth_params={'this': 'will_not_be_used'})

        auth_params = {'foo': 'auth', 'spam': 'eggs'}
        token_params = {'foo': 'token'}

        responses.add(responses.GET, url, json={'issued': 1, 'token':
                                                'another_token_string'})
        token_details = self.ably.auth.request_token(
            token_params=token_params, auth_url=url, auth_headers=headers,
            auth_params=auth_params)
        assert 'another_token_string' == token_details.token
        request = responses.calls[0].request
        assert request.headers['foo'] == 'bar'
        assert 'this' not in request.headers
        assert parse_qs(urlparse(request.url).query) == {'foo': ['token'], 'spam': ['eggs']}
        assert not request.body
    def test_wildcard_client_id_can_publish_as_others(self):
        wildcard_token_details = self.ably.auth.request_token({'client_id': '*'})
        wildcard_ably = RestSetup.get_ably_rest(
            key=None,
            token_details=wildcard_token_details,
            use_binary_protocol=self.use_binary_protocol)

        assert wildcard_ably.auth.client_id == '*'
        channel = wildcard_ably.channels[
            self.get_channel_name('persisted:wildcard_client_id')]
        channel.publish(name='publish1', data='no client_id')
        some_client_id = uuid.uuid4().hex
        channel.publish(name='publish2', data='some client_id',
                        client_id=some_client_id)

        history = channel.history()
        messages = history.items

        assert messages is not None, "Expected non-None messages"
        assert len(messages) == 2, "Expected 2 messages"

        assert messages[0].client_id == some_client_id
        assert messages[1].client_id is None
import six
import msgpack
import responses

from ably import AblyRest
from ably.http.paginatedresult import PaginatedResult
from ably.types.presence import (PresenceMessage,
                                 make_encrypted_presence_response_handler)
from ably import ChannelOptions
from ably.util.crypto import get_default_params

from test.ably.utils import dont_vary_protocol, VaryByProtocolTestsMetaclass, BaseTestCase
from test.ably.restsetup import RestSetup

test_vars = RestSetup.get_test_vars()


@six.add_metaclass(VaryByProtocolTestsMetaclass)
class TestPresence(BaseTestCase):

    def setUp(self):
        self.ably = AblyRest(test_vars["keys"][0]["key_str"],
                             rest_host=test_vars["host"],
                             port=test_vars["port"],
                             tls_port=test_vars["tls_port"],
                             tls=test_vars["tls"])
        self.per_protocol_setup(True)

    def per_protocol_setup(self, use_binary_protocol):
        # This will be called every test that vary by protocol for each protocol
Example #57
0
 def setUpClass(cls):
     cls.ably = RestSetup.get_ably_rest()
     cls.channel = cls.ably.channels.get('persisted:presence_fixtures')