Skip to content

Commit 2056b81

Browse files
committed
feat: Add tests for GCM compatibility
Fixed some Python3 GCM issues
1 parent b39b76f commit 2056b81

File tree

2 files changed

+35
-13
lines changed

2 files changed

+35
-13
lines changed

pywebpush/__init__.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
44

55
import base64
6-
import os
7-
86
import json
7+
import os
98

9+
import six
1010
import http_ece
1111
import pyelliptic
1212
import requests
@@ -42,6 +42,10 @@ def get(self, key, default=None):
4242
except KeyError:
4343
return default
4444

45+
def update(self, data):
46+
for key in data:
47+
self.__setitem__(key, data[key])
48+
4549

4650
class WebPusher:
4751
"""WebPusher encrypts a data block using HTTP Encrypted Content Encoding
@@ -88,11 +92,6 @@ def __init__(self, subscription_info):
8892
the client.
8993
9094
"""
91-
# Python 2 v. 3 hack
92-
try:
93-
self.basestr = basestring
94-
except NameError:
95-
self.basestr = str
9695
if 'endpoint' not in subscription_info:
9796
raise WebPushException("subscription_info missing endpoint URL")
9897
if 'keys' not in subscription_info:
@@ -102,7 +101,7 @@ def __init__(self, subscription_info):
102101
for k in ['p256dh', 'auth']:
103102
if keys.get(k) is None:
104103
raise WebPushException("Missing keys value: %s", k)
105-
if isinstance(keys[k], self.basestr):
104+
if isinstance(keys[k], six.string_types):
106105
keys[k] = bytes(keys[k].encode('utf8'))
107106
receiver_raw = base64.urlsafe_b64decode(self._repad(keys['p256dh']))
108107
if len(receiver_raw) != 65 and receiver_raw[0] != "\x04":
@@ -131,7 +130,7 @@ def encode(self, data):
131130
# ID tag.
132131
server_key_id = base64.urlsafe_b64encode(server_key.get_pubkey()[1:])
133132

134-
if isinstance(data, self.basestr):
133+
if isinstance(data, six.string_types):
135134
data = bytes(data.encode('utf8'))
136135

137136
# http_ece requires that these both be set BEFORE encrypt or
@@ -183,7 +182,6 @@ def send(self, data, headers={}, ttl=0, gcm_key=None, reg_id=None):
183182
})
184183
gcm_endpoint = 'https://android.googleapis.com/gcm/send'
185184
if self.subscription_info['endpoint'].startswith(gcm_endpoint):
186-
187185
if not gcm_key:
188186
raise WebPushException("API key not provided for gcm endpoint")
189187
endpoint = gcm_endpoint
@@ -193,7 +191,8 @@ def send(self, data, headers={}, ttl=0, gcm_key=None, reg_id=None):
193191
reg_ids.append(reg_id)
194192
data = {}
195193
data['registration_ids'] = reg_ids
196-
data['raw_data'] = base64.b64encode(encoded.get('body'))
194+
data['raw_data'] = base64.b64encode(
195+
encoded.get('body')).decode('utf8')
197196
encoded_data = json.dumps(data)
198197
headers.update({
199198
'Authorization': 'key='+gcm_key,

pywebpush/tests/test_webpush.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import base64
2+
import json
23
import os
34
import unittest
45

@@ -11,9 +12,9 @@
1112

1213

1314
class WebpushTestCase(unittest.TestCase):
14-
def _gen_subscription_info(self, recv_key):
15+
def _gen_subscription_info(self, recv_key, endpoint="https://example.com"):
1516
return {
16-
"endpoint": "https://example.com/",
17+
"endpoint": endpoint,
1718
"keys": {
1819
'auth': base64.urlsafe_b64encode(os.urandom(16)).strip(b'='),
1920
'p256dh': base64.urlsafe_b64encode(
@@ -115,3 +116,25 @@ def test_ci_dict(self):
115116
eq_('apple', ci.get("Foo"))
116117
del (ci['FOO'])
117118
eq_(None, ci.get('Foo'))
119+
120+
@patch("requests.post")
121+
def test_gcm(self, mock_post):
122+
recv_key = pyelliptic.ECC(curve="prime256v1")
123+
subscription_info = self._gen_subscription_info(
124+
recv_key,
125+
endpoint="https://android.googleapis.com/gcm/send/regid123")
126+
headers = {"Crypto-Key": "pre-existing",
127+
"Authentication": "bearer vapid"}
128+
data = "Mary had a little lamb"
129+
wp = WebPusher(subscription_info)
130+
self.assertRaises(
131+
WebPushException,
132+
wp.send,
133+
data,
134+
headers)
135+
wp.send(data, headers, gcm_key="gcm_key_value")
136+
pdata = json.loads(mock_post.call_args[1].get('data'))
137+
pheaders = mock_post.call_args[1].get('headers')
138+
eq_(pdata["registration_ids"][0], "regid123")
139+
eq_(pheaders.get("authorization"), "key=gcm_key_value")
140+
eq_(pheaders.get("content-type"), "application/json")

0 commit comments

Comments
 (0)