예제 #1
0
 def test_bad_jsonmessage(self):
     with pytest.raises(RouterException):
         self.m_payload = gcmclient.JSONMessage(registration_ids=None,
                                                collapse_key="coll_key",
                                                time_to_live=60,
                                                dry_run=False,
                                                data={"foo": "bar"})
예제 #2
0
파일: gcm.py 프로젝트: Alkalami/autopush
    def _route(self, notification, uaid_data):
        """Blocking GCM call to route the notification"""
        router_data = uaid_data["router_data"]
        # THIS MUST MATCH THE CHANNELID GENERATED BY THE REGISTRATION SERVICE
        # Currently this value is in hex form.
        data = {"chid": notification.channel_id.hex}
        # Payload data is optional. The endpoint handler validates that the
        # correct encryption headers are included with the data.
        if notification.data:
            mdata = self.router_conf.get('max_data', 4096)
            if notification.data_length > mdata:
                raise self._error("This message is intended for a " +
                                  "constrained device and is limited " +
                                  "to 3070 bytes. Converted buffer too " +
                                  "long by %d bytes" %
                                  (notification.data_length - mdata),
                                  413, errno=104, log_exception=False)

            data['body'] = notification.data
            data['con'] = notification.headers['encoding']

            if 'encryption' in notification.headers:
                data['enc'] = notification.headers.get('encryption')
            if 'crypto_key' in notification.headers:
                data['cryptokey'] = notification.headers['crypto_key']
            elif 'encryption_key' in notification.headers:
                data['enckey'] = notification.headers['encryption_key']

        # registration_ids are the GCM instance tokens (specified during
        # registration.
        router_ttl = min(self.MAX_TTL,
                         max(notification.ttl or 0, self.min_ttl))
        payload = gcmclient.JSONMessage(
            registration_ids=[router_data.get("token")],
            collapse_key=self.collapseKey,
            time_to_live=router_ttl,
            dry_run=self.dryRun or ("dryrun" in router_data),
            data=data,
        )
        try:
            client = self.gcmclients[router_data['creds']['senderID']]
            d = client.send(payload)
            d.addCallback(
                self._process_reply,
                uaid_data,
                router_ttl,
                notification)

            d.addErrback(
                self._process_error
            )
            return d
        except KeyError:
            self.log.critical("Missing GCM bridge credentials")
            raise RouterException("Server error", status_code=500,
                                  errno=900)
예제 #3
0
 def setUp(self):
     self.gcm = gcmclient.GCM(api_key="FakeValue")
     self.gcm._sender = self._m_request = Mock(spec=requests.post)
     self._m_response = Mock(spec=requests.Response)
     self._m_response.return_value = 200
     self._m_response.headers = dict()
     self.m_payload = gcmclient.JSONMessage(registration_ids="some_reg_id",
                                            collapse_key="coll_key",
                                            time_to_live=60,
                                            dry_run=False,
                                            data={"foo": "bar"})
예제 #4
0
 def setUp(self):
     self.gcm = gcmclient.GCM(api_key="FakeValue")
     self.gcm._sender = Mock(spec=treq.request)
     self._m_request = Deferred()
     self.gcm._sender.return_value = self._m_request
     self._m_response = Mock(spec=treq.response._Response)
     self._m_response.code = 200
     self._m_response.headers = Headers()
     self._m_resp_text = Deferred()
     self._m_response.text.return_value = self._m_resp_text
     self.m_payload = gcmclient.JSONMessage(
         registration_ids="some_reg_id",
         collapse_key="coll_key",
         time_to_live=60,
         dry_run=False,
         data={"foo": "bar"}
     )
예제 #5
0
    def _route(self, notification, uaid_data):
        """Blocking GCM call to route the notification"""
        router_data = uaid_data["router_data"]
        # THIS MUST MATCH THE CHANNELID GENERATED BY THE REGISTRATION SERVICE
        # Currently this value is in hex form.
        data = {"chid": notification.channel_id.hex}
        # Payload data is optional. The endpoint handler validates that the
        # correct encryption headers are included with the data.
        if notification.data:
            mdata = self.router_conf.get('max_data', 4096)
            if notification.data_length > mdata:
                raise self._error("This message is intended for a " +
                                  "constrained device and is limited " +
                                  "to 3070 bytes. Converted buffer too " +
                                  "long by %d bytes" %
                                  (notification.data_length - mdata),
                                  413, errno=104, log_exception=False)

            data['body'] = notification.data
            data['con'] = notification.headers['encoding']

            if 'encryption' in notification.headers:
                data['enc'] = notification.headers.get('encryption')
            if 'crypto_key' in notification.headers:
                data['cryptokey'] = notification.headers['crypto_key']
            elif 'encryption_key' in notification.headers:
                data['enckey'] = notification.headers['encryption_key']

        # registration_ids are the GCM instance tokens (specified during
        # registration.
        router_ttl = min(self.MAX_TTL,
                         max(notification.ttl or 0, self.min_ttl))
        payload = gcmclient.JSONMessage(
            registration_ids=[router_data.get("token")],
            collapse_key=self.collapseKey,
            time_to_live=router_ttl,
            dry_run=self.dryRun or ("dryrun" in router_data),
            data=data,
        )
        try:
            gcm = self.gcm[router_data['creds']['senderID']]
            result = gcm.send(payload)
        except RouterException:
            raise  # pragma nocover
        except KeyError:
            self.log.critical("Missing GCM bridge credentials")
            raise RouterException("Server error", status_code=500,
                                  errno=900)
        except gcmclient.GCMAuthenticationError as e:
            self.log.error("GCM Authentication Error: %s" % e)
            raise RouterException("Server error", status_code=500,
                                  errno=901)
        except ConnectionError as e:
            self.log.warn("GCM Unavailable: %s" % e)
            self.metrics.increment("notification.bridge.error",
                                   tags=make_tags(
                                       self._base_tags,
                                       reason="connection_unavailable"))
            raise RouterException("Server error", status_code=502,
                                  errno=902,
                                  log_exception=False)
        except Exception as e:
            self.log.error("Unhandled exception in GCM Routing: %s" % e)
            raise RouterException("Server error", status_code=500)
        return self._process_reply(result, uaid_data, ttl=router_ttl,
                                   notification=notification)