Exemple #1
0
    def setUp(self):
        settings = AutopushSettings(
            hostname="localhost",
            statsd_host=None,
        )

        self.headers = headers = {
            "content-encoding": "aes128",
            "encryption": "awesomecrypto",
            "crypto-key": "niftykey"
        }
        self.router = WebPushRouter(settings, {})
        self.notif = WebPushNotification(
            uaid=uuid.UUID(dummy_uaid),
            channel_id=uuid.UUID(dummy_chid),
            data="data",
            headers=headers,
            ttl=20,
            message_id=uuid.uuid4().hex,
        )
        self.notif.cleanup_headers()
        mock_result = Mock(spec=gcmclient.gcm.Result)
        mock_result.canonical = dict()
        mock_result.failed = dict()
        mock_result.not_registered = dict()
        mock_result.needs_retry.return_value = False
        self.router_mock = settings.router = Mock(spec=Router)
        self.message_mock = settings.message = Mock(spec=Message)
        self.agent_mock = Mock(spec=settings.agent)
        settings.agent = self.agent_mock
        self.router.metrics = Mock()
        self.settings = settings
    def test_ttl_none(self):
        self.router.gcm['test123'] = self.gcm
        self.notif = WebPushNotification(uaid=uuid.UUID(dummy_uaid),
                                         channel_id=uuid.UUID(dummy_chid),
                                         data="q60d6g",
                                         headers=self.headers,
                                         ttl=None)
        self.notif.cleanup_headers()
        d = self.router.route_notification(self.notif, self.router_data)

        def check_results(result):
            assert isinstance(result, RouterResponse)
            assert result.status_code == 201
            assert result.logged_status == 200
            assert "TTL" in result.headers
            assert self.gcm._sender.called
            # Make sure the data was encoded as base64
            payload = json.loads(self.gcm._sender.call_args[1]['data'])
            data = payload['data']
            assert data['body'] == 'q60d6g'
            assert data['enc'] == 'test'
            assert data['chid'] == dummy_chid
            assert data['enckey'] == 'test'
            assert data['con'] == 'aesgcm'
            # use the defined min TTL
            assert payload['time_to_live'] == 60

        d.addCallback(check_results)
        return d
    def test_route_crypto_key(self):
        headers = {
            "content-encoding": "aesgcm",
            "encryption": "test",
            "crypto-key": "test"
        }
        self.notif = WebPushNotification(
            uaid=uuid.UUID(dummy_uaid),
            channel_id=uuid.UUID(dummy_chid),
            data="q60d6g",
            headers=headers,
            ttl=200,
            message_id=10,
        )
        self.notif.cleanup_headers()
        d = self.router.route_notification(self.notif, self.router_data)

        def check_results(result):
            assert isinstance(result, RouterResponse)
            assert result.status_code == 201
            assert result.logged_status == 200
            assert "TTL" in result.headers
            assert self.mock_connection.called

        d.addCallback(check_results)
        return d
Exemple #4
0
    def test_ttl_none(self):
        self.router.fcm = self.fcm
        self.notif = WebPushNotification(uaid=uuid.UUID(dummy_uaid),
                                         channel_id=uuid.UUID(dummy_chid),
                                         data="q60d6g",
                                         headers=self.headers,
                                         ttl=None)
        self.notif.cleanup_headers()
        d = self.router.route_notification(self.notif, self.router_data)

        def check_results(result):
            ok_(isinstance(result, RouterResponse))
            ok_(self.router.fcm.notify_single_device.called)
            # Make sure the data was encoded as base64
            args = self.router.fcm.notify_single_device.call_args[1]
            data = args['data_message']
            eq_(data['body'], 'q60d6g')
            eq_(data['chid'], dummy_chid)
            eq_(data['enc'], 'test')
            eq_(data['enckey'], 'test')
            eq_(data['con'], 'aesgcm')
            # use the defined min TTL
            eq_(args['time_to_live'], 60)

        d.addCallback(check_results)
        return d
Exemple #5
0
    def test_ttl_high(self):
        self.router.gcm['test123'] = self.gcm
        self.notif = WebPushNotification(uaid=uuid.UUID(dummy_uaid),
                                         channel_id=uuid.UUID(dummy_chid),
                                         data="q60d6g",
                                         headers=self.headers,
                                         ttl=5184000)
        self.notif.cleanup_headers()
        d = self.router.route_notification(self.notif, self.router_data)

        def check_results(result):
            ok_(isinstance(result, RouterResponse))
            ok_(self.router.gcm['test123'].send.called)
            # Make sure the data was encoded as base64
            data = self.router.gcm['test123'].send.call_args[0][0].data
            options = self.router.gcm['test123'].send.call_args[0][0].options
            eq_(data['body'], 'q60d6g')
            eq_(data['enc'], 'test')
            eq_(data['chid'], dummy_chid)
            eq_(data['enckey'], 'test')
            eq_(data['con'], 'aesgcm')
            # use the defined min TTL
            eq_(options['time_to_live'], 2419200)

        d.addCallback(check_results)
        return d
    def test_ttl_high(self):
        self.router.fcm = self.fcm
        self.notif = WebPushNotification(uaid=uuid.UUID(dummy_uaid),
                                         channel_id=uuid.UUID(dummy_chid),
                                         data="q60d6g",
                                         headers=self.headers,
                                         ttl=5184000)
        self.notif.cleanup_headers()
        d = self.router.route_notification(self.notif, self.router_data)

        def check_results(result):
            assert isinstance(result, RouterResponse)
            assert self.router.fcm.notify_single_device.called
            # Make sure the data was encoded as base64
            args = self.router.fcm.notify_single_device.call_args[1]
            data = args['data_message']
            assert data['body'] == 'q60d6g'
            assert data['chid'] == dummy_chid
            assert data['enc'] == 'test'
            assert data['enckey'] == 'test'
            assert data['con'] == 'aesgcm'
            # use the defined min TTL
            assert args['time_to_live'] == 2419200

        d.addCallback(check_results)
        return d
    def setUp(self):
        conf = AutopushConfig(
            hostname="localhost",
            statsd_host=None,
        )
        self.metrics = metrics = Mock(spec=SinkMetrics)
        self.db = db = test_db(metrics=metrics)

        self.headers = headers = {
            "content-encoding": "aes128",
            "encryption": "awesomecrypto",
            "crypto-key": "niftykey"
        }
        self.agent_mock = agent = Mock(spec=Agent)
        self.router = WebPushRouter(conf, {}, db, agent)
        self.notif = WebPushNotification(
            uaid=uuid.UUID(dummy_uaid),
            channel_id=uuid.UUID(dummy_chid),
            data="data",
            headers=headers,
            ttl=20,
            message_id=uuid.uuid4().hex,
        )
        self.notif.cleanup_headers()
        mock_result = Mock(spec=gcmclient.Result)
        mock_result.canonical = dict()
        mock_result.failed = dict()
        mock_result.not_registered = dict()
        mock_result.retry_after = 1000
        self.router_mock = db.router
        self.message_mock = db._message = Mock(spec=Message)
        self.conf = conf
    def test_route_to_busy_node_with_ttl_zero(self):
        notif = WebPushNotification(
            uaid=uuid.UUID(dummy_uaid),
            channel_id=uuid.UUID(dummy_chid),
            data="data",
            headers=self.headers,
            ttl=0,
            message_id=uuid.uuid4().hex,
        )
        self.notif.cleanup_headers()
        self.agent_mock.request.return_value = response_mock = Mock()
        response_mock.addCallback.return_value = response_mock
        type(response_mock).code = PropertyMock(
            side_effect=MockAssist([202, 200]))
        self.message_mock.store_message.return_value = True
        self.message_mock.all_channels.return_value = (True, [dummy_chid])
        self.db.message_table = Mock(return_value=self.message_mock)
        router_data = dict(node_id="http://somewhere",
                           uaid=dummy_uaid,
                           current_month=self.db.current_msg_month)
        self.router_mock.get_uaid.return_value = router_data
        self.router.message_id = uuid.uuid4().hex

        d = self.router.route_notification(notif, router_data)

        def verify_deliver(fail):
            exc = fail.value
            assert isinstance(exc, RouterException)
            assert exc.status_code == 201
            assert len(self.metrics.increment.mock_calls) == 0
            assert "Location" in exc.headers

        d.addBoth(verify_deliver)
        return d
Exemple #9
0
def make_webpush_notification(uaid, chid, ttl=100):
    message_id = str(uuid.uuid4())
    return WebPushNotification(
        uaid=uuid.UUID(uaid),
        channel_id=uuid.UUID(chid),
        update_id=message_id,
        message_id=message_id,
        ttl=ttl,
    )
Exemple #10
0
 def setUp(self):
     conf = AutopushConfig(
         hostname="localhost",
         statsd_host=None,
     )
     self.gcm_config = {
         'max_data': 32,
         'ttl': 60,
         'senderIDs': {
             'test123': {
                 "auth": "12345678abcdefg"
             }
         }
     }
     self.response = Mock(spec=requests.Response)
     self.response.status_code = 200
     self.response.headers = dict()
     self.response.content = json.dumps({
         "multicast_id":
         5174939174563864884,
         "success":
         1,
         "failure":
         0,
         "canonical_ids":
         0,
         "results": [{
             "message_id": "0:1510011451922224%7a0e7efbaab8b7cc"
         }]
     })
     self.gcm = gcmclient.GCM(api_key="SomeKey")
     self.gcm._sender = Mock(return_value=self.response)
     self.router = GCMRouter(conf, self.gcm_config, SinkMetrics())
     self.router.gcm['test123'] = self.gcm
     self.headers = {
         "content-encoding": "aesgcm",
         "encryption": "test",
         "encryption-key": "test"
     }
     # Payloads are Base64-encoded.
     self.notif = WebPushNotification(
         uaid=uuid.UUID(dummy_uaid),
         channel_id=uuid.UUID(dummy_chid),
         data="q60d6g",
         headers=self.headers,
         ttl=200,
         message_id=10,
     )
     self.notif.cleanup_headers()
     self.router_data = dict(router_data=dict(
         token="connect_data",
         creds=dict(senderID="test123", auth="12345678abcdefg")))
Exemple #11
0
 def to_WebPushNotification(self):
     # type: () -> WebPushNotification
     return WebPushNotification(
         uaid=UUID(self.uaid),
         channel_id=self.channelID,
         data=self.data,
         headers=self.headers,
         ttl=self.ttl,
         topic=self.topic,
         timestamp=self.timestamp,
         message_id=self.version,
         update_id=self.version,
     )
Exemple #12
0
    def test_long_data(self):
        self.router.gcmclients['test123'] = self.gcmclient
        bad_notif = WebPushNotification(
            uaid=uuid.UUID(dummy_uaid),
            channel_id=uuid.UUID(dummy_chid),
            data="\x01abcdefghijklmnopqrstuvwxyz0123456789",
            headers=self.headers,
            ttl=200
        )
        self._set_content()

        with pytest.raises(RouterException) as ex:
            self.router.route_notification(bad_notif, self.router_data)

        assert isinstance(ex.value, RouterException)
        assert ex.value.status_code == 413
        assert ex.value.errno == 104
Exemple #13
0
def preflight_check(message, router, uaid="deadbeef00000000deadbeef00000000"):
    # type: (Message, Router, str) -> None
    """Performs a pre-flight check of the router/message to ensure
    appropriate permissions for operation.

    Failure to run correctly will raise an exception.

    """
    # Verify tables are ready for use if they just got created
    ready = False
    while not ready:
        tbl_status = [x.table_status() for x in [message, router]]
        ready = all([status == "ACTIVE" for status in tbl_status])
        if not ready:
            time.sleep(1)

    # Use a distinct UAID so it doesn't interfere with metrics
    uaid = uuid.UUID(uaid)
    chid = uuid.uuid4()
    message_id = str(uuid.uuid4())
    node_id = "mynode:2020"
    connected_at = 0
    notif = WebPushNotification(
        uaid=uaid,
        channel_id=chid,
        update_id=message_id,
        message_id=message_id,
        ttl=60,
    )

    # Store a notification, fetch it, delete it
    message.store_message(notif)
    assert message.delete_message(notif)

    # Store a router entry, fetch it, delete it
    router.register_user(
        dict(uaid=uaid.hex,
             node_id=node_id,
             connected_at=connected_at,
             current_month=datetime.date.today().month,
             router_type="webpush"))
    item = router.get_uaid(uaid.hex)
    assert item.get("node_id") == node_id
    # Clean up the preflight data.
    router.clear_node(item)
    router.drop_user(uaid.hex)
Exemple #14
0
    def test_long_data(self):
        self.router.gcm['test123'] = self.gcm
        bad_notif = WebPushNotification(
            uaid=uuid.UUID(dummy_uaid),
            channel_id=uuid.UUID(dummy_chid),
            data="\x01abcdefghijklmnopqrstuvwxyz0123456789",
            headers=self.headers,
            ttl=200)

        d = self.router.route_notification(bad_notif, self.router_data)

        def check_results(result):
            assert isinstance(result.value, RouterException)
            assert result.value.status_code == 413
            assert result.value.errno == 104

        d.addBoth(check_results)
        return d
Exemple #15
0
 def setUp(self, mt, mc):
     from twisted.logger import Logger
     conf = AutopushConfig(
         hostname="localhost",
         statsd_host=None,
     )
     apns_config = {
         'firefox': {
             'cert': 'fake.cert',
             'key': 'fake.key',
             'topic': 'com.example.SomeApp',
             'max_connections': 2,
         }
     }
     self.mock_connection = mc
     mc.return_value = mc
     self.metrics = metrics = Mock(spec=SinkMetrics)
     self.router = APNSRouter(conf, apns_config, metrics)
     self.mock_response = Mock()
     self.mock_response.status = 200
     mc.get_response.return_value = self.mock_response
     # toss the existing connection
     try:
         self.router.apns['firefox'].connections.pop()
     except IndexError:  # pragma nocover
         pass
     self.router.apns['firefox'].connections.append(self.mock_connection)
     self.router.apns['firefox'].log = Mock(spec=Logger)
     self.headers = {
         "content-encoding": "aesgcm",
         "encryption": "test",
         "encryption-key": "test"
     }
     self.notif = WebPushNotification(
         uaid=uuid.UUID(dummy_uaid),
         channel_id=uuid.UUID(dummy_chid),
         data="q60d6g",
         headers=self.headers,
         ttl=200,
         message_id=10,
     )
     self.notif.cleanup_headers()
     self.router_data = dict(
         router_data=dict(token="connect_data", rel_channel="firefox"))
Exemple #16
0
    def test_long_data(self):
        self.router.fcm = self.fcm
        bad_notif = WebPushNotification(
            uaid=uuid.UUID(dummy_uaid),
            channel_id=uuid.UUID(dummy_chid),
            data="\x01abcdefghijklmnopqrstuvwxyz0123456789",
            headers=self.headers,
            ttl=200,
            message_id=10,
        )
        self.notif.cleanup_headers()
        d = self.router.route_notification(bad_notif, self.router_data)

        def check_results(result):
            ok_(isinstance(result.value, RouterException))
            eq_(result.value.status_code, 413)
            eq_(result.value.errno, 104)

        d.addBoth(check_results)
        return d
Exemple #17
0
 def setUp(self, fgcm):
     settings = AutopushSettings(
         hostname="localhost",
         statsd_host=None,
     )
     self.gcm_config = {
         'max_data': 32,
         'ttl': 60,
         'senderIDs': {
             'test123': {
                 "auth": "12345678abcdefg"
             }
         }
     }
     self.gcm = fgcm
     self.router = GCMRouter(settings, self.gcm_config)
     self.headers = {
         "content-encoding": "aesgcm",
         "encryption": "test",
         "encryption-key": "test"
     }
     # Payloads are Base64-encoded.
     self.notif = WebPushNotification(
         uaid=uuid.UUID(dummy_uaid),
         channel_id=uuid.UUID(dummy_chid),
         data="q60d6g",
         headers=self.headers,
         ttl=200,
         message_id=10,
     )
     self.notif.cleanup_headers()
     self.router_data = dict(router_data=dict(
         token="connect_data",
         creds=dict(senderID="test123", auth="12345678abcdefg")))
     mock_result = Mock(spec=gcmclient.gcm.Result)
     mock_result.canonical = dict()
     mock_result.failed = dict()
     mock_result.not_registered = dict()
     mock_result.needs_retry.return_value = False
     self.mock_result = mock_result
     fgcm.send.return_value = mock_result
Exemple #18
0
 def setUp(self, ffcm):
     conf = AutopushConfig(
         hostname="localhost",
         statsd_host=None,
     )
     self.fcm_config = {
         'max_data': 32,
         'ttl': 60,
         'senderID': 'test123',
         "auth": "12345678abcdefg"
     }
     self.fcm = ffcm
     self.router = FCMRouter(conf, self.fcm_config, SinkMetrics())
     self.headers = {
         "content-encoding": "aesgcm",
         "encryption": "test",
         "encryption-key": "test"
     }
     # Payloads are Base64-encoded.
     self.notif = WebPushNotification(uaid=uuid.UUID(dummy_uaid),
                                      channel_id=uuid.UUID(dummy_chid),
                                      data="q60d6g",
                                      headers=self.headers,
                                      ttl=200)
     self.notif.cleanup_headers()
     self.router_data = dict(router_data=dict(
         token="connect_data",
         creds=dict(senderID="test123", auth="12345678abcdefg")))
     mock_result = dict(
         multicast_id="",
         success=0,
         failure=0,
         canonical_ids=0,
         results=[dict()],
     )
     self.mock_result = mock_result
     ffcm.notify_single_device.return_value = mock_result