Skip to content

Commit cbb6a73

Browse files
committed
Push key validation down to base client
1 parent b6957c4 commit cbb6a73

File tree

6 files changed

+159
-49
lines changed

6 files changed

+159
-49
lines changed

pusher/authentication_client.py

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,22 +31,37 @@
3131

3232
class AuthenticationClient(Client):
3333
def __init__(
34-
self, app_id, key, secret, ssl=True, host=None, port=None,
35-
timeout=5, cluster=None, encryption_master_key=None, json_encoder=None, json_decoder=None,
36-
backend=None, **backend_options):
34+
self,
35+
app_id,
36+
key,
37+
secret,
38+
ssl=True,
39+
host=None,
40+
port=None,
41+
timeout=5,
42+
cluster=None,
43+
encryption_master_key=None,
44+
encryption_master_key_base64=None,
45+
json_encoder=None,
46+
json_decoder=None,
47+
backend=None,
48+
**backend_options):
49+
3750
super(AuthenticationClient, self).__init__(
38-
app_id, key, secret, ssl, host, port, timeout, cluster, encryption_master_key,
39-
json_encoder, json_decoder, backend, **backend_options)
40-
41-
if host:
42-
self._host = ensure_text(host, "host")
43-
44-
elif cluster:
45-
self._host = (
46-
six.text_type("api-%s.pusher.com") %
47-
ensure_text(cluster, "cluster"))
48-
else:
49-
self._host = six.text_type("api.pusherapp.com")
51+
app_id,
52+
key,
53+
secret,
54+
ssl,
55+
host,
56+
port,
57+
timeout,
58+
cluster,
59+
encryption_master_key,
60+
encryption_master_key_base64,
61+
json_encoder,
62+
json_decoder,
63+
backend,
64+
**backend_options)
5065

5166

5267
def authenticate(self, channel, socket_id, custom_data=None):

pusher/client.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import six
1010

1111
from pusher.util import ensure_text, ensure_binary, app_id_re
12+
from pusher.crypto import parse_master_key
1213

1314

1415
class Client(object):
@@ -23,6 +24,7 @@ def __init__(
2324
timeout=5,
2425
cluster=None,
2526
encryption_master_key=None,
27+
encryption_master_key_base64=None,
2628
json_encoder=None,
2729
json_decoder=None,
2830
backend=None,
@@ -44,6 +46,15 @@ def __init__(
4446

4547
self._ssl = ssl
4648

49+
if host:
50+
self._host = ensure_text(host, "host")
51+
elif cluster:
52+
self._host = (
53+
six.text_type("api-%s.pusher.com") %
54+
ensure_text(cluster, "cluster"))
55+
else:
56+
self._host = six.text_type("api.pusherapp.com")
57+
4758
if port and not isinstance(port, six.integer_types):
4859
raise TypeError("port should be an integer")
4960

@@ -55,10 +66,12 @@ def __init__(
5566
self._timeout = timeout
5667
self._json_encoder = json_encoder
5768
self._json_decoder = json_decoder
58-
self._encryption_master_key = encryption_master_key
69+
70+
self._encryption_master_key = parse_master_key(encryption_master_key, encryption_master_key_base64)
5971

6072
self.http = backend(self, **backend_options)
6173

74+
6275
@property
6376
def app_id(self):
6477
return self._app_id

pusher/notification_client.py

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,38 @@
1919

2020
class NotificationClient(Client):
2121
def __init__(
22-
self, app_id, key, secret, ssl=True, host=None, port=None,
23-
timeout=30, cluster=None, encryption_master_key=None, json_encoder=None, json_decoder=None,
24-
backend=None, **backend_options):
22+
self,
23+
app_id,
24+
key,
25+
secret,
26+
ssl=True,
27+
host=None,
28+
port=None,
29+
timeout=30,
30+
cluster=None,
31+
json_encoder=None,
32+
json_decoder=None,
33+
backend=None,
34+
**backend_options):
35+
2536
super(NotificationClient, self).__init__(
26-
app_id, key, secret, ssl, host, port, timeout, cluster, encryption_master_key,
27-
json_encoder, json_decoder, backend, **backend_options)
37+
app_id,
38+
key,
39+
secret,
40+
ssl,
41+
host,
42+
port,
43+
timeout,
44+
cluster,
45+
None, # encryption_master_key
46+
None, # encryption_master_key_base64
47+
json_encoder,
48+
json_decoder,
49+
backend,
50+
**backend_options)
2851

2952
if host:
3053
self._host = ensure_text(host, "host")
31-
3254
else:
3355
self._host = DEFAULT_HOST
3456

pusher/pusher.py

Lines changed: 60 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,29 +36,77 @@ class Pusher(object):
3636
:param host: Used for custom host destination
3737
:param port: Used for custom port destination
3838
:param timeout: Request timeout (in seconds)
39-
:param encryption_master_key: Used to derive a shared secret between
40-
server and the clients for payload encryption/decryption
41-
:param cluster: Convention for other clusters than the main Pusher-one.
39+
:param encryption_master_key: deprecated, use encryption_master_key_base64
40+
:param encryption_master_key_base64: Used to derive a shared secret
41+
between server and the clients for payload encryption/decryption
42+
:param cluster: Convention for clusters other than the original Pusher cluster.
4243
Eg: 'eu' will resolve to the api-eu.pusherapp.com host
4344
:param backend: an http adapter class (AsyncIOBackend, RequestsBackend,
4445
SynchronousBackend, TornadoBackend)
4546
:param backend_options: additional backend
4647
"""
4748
def __init__(
48-
self, app_id, key, secret, ssl=True, host=None, port=None,
49-
timeout=5, cluster=None, encryption_master_key=None, json_encoder=None, json_decoder=None,
50-
backend=None, notification_host=None, notification_ssl=True, **backend_options):
49+
self,
50+
app_id,
51+
key,
52+
secret,
53+
ssl=True,
54+
host=None,
55+
port=None,
56+
timeout=5,
57+
cluster=None,
58+
encryption_master_key=None,
59+
encryption_master_key_base64=None,
60+
json_encoder=None,
61+
json_decoder=None,
62+
backend=None,
63+
notification_host=None,
64+
notification_ssl=True,
65+
**backend_options):
66+
5167
self._pusher_client = PusherClient(
52-
app_id, key, secret, ssl, host, port, timeout, cluster, encryption_master_key,
53-
json_encoder, json_decoder, backend, **backend_options)
68+
app_id,
69+
key,
70+
secret,
71+
ssl,
72+
host,
73+
port,
74+
timeout, cluster,
75+
encryption_master_key,
76+
encryption_master_key_base64,
77+
json_encoder,
78+
json_decoder,
79+
backend,
80+
**backend_options)
5481

5582
self._authentication_client = AuthenticationClient(
56-
app_id, key, secret, ssl, host, port, timeout, cluster, encryption_master_key,
57-
json_encoder, json_decoder, backend, **backend_options)
83+
app_id,
84+
key,
85+
secret,
86+
ssl,
87+
host,
88+
port,
89+
timeout,
90+
cluster,
91+
encryption_master_key,
92+
encryption_master_key_base64,
93+
json_encoder,
94+
json_decoder,
95+
backend,
96+
**backend_options)
5897

5998
self._notification_client = NotificationClient(
60-
app_id, key, secret, notification_ssl, notification_host, port,
61-
timeout, cluster, encryption_master_key, json_encoder, json_decoder, backend,
99+
app_id,
100+
key,
101+
secret,
102+
notification_ssl,
103+
notification_host,
104+
port,
105+
timeout,
106+
cluster,
107+
json_encoder,
108+
json_decoder,
109+
backend,
62110
**backend_options)
63111

64112

pusher/pusher_client.py

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,6 @@ def __init__(
5252
backend=None,
5353
**backend_options):
5454

55-
parsed_master_key = parse_master_key(encryption_master_key, encryption_master_key_base64)
56-
5755
super(PusherClient, self).__init__(
5856
app_id,
5957
key,
@@ -63,22 +61,13 @@ def __init__(
6361
port,
6462
timeout,
6563
cluster,
66-
parsed_master_key,
64+
encryption_master_key,
65+
encryption_master_key_base64,
6766
json_encoder,
6867
json_decoder,
6968
backend,
7069
**backend_options)
7170

72-
if host:
73-
self._host = ensure_text(host, "host")
74-
75-
elif cluster:
76-
self._host = (
77-
six.text_type("api-%s.pusher.com") %
78-
ensure_text(cluster, "cluster"))
79-
else:
80-
self._host = six.text_type("api.pusherapp.com")
81-
8271

8372
@request_method
8473
def trigger(self, channels, event_name, data, socket_id=None):

pusher_tests/test_authentication_client.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,29 @@
2323

2424
class TestAuthenticationClient(unittest.TestCase):
2525

26+
def test_host_should_be_text(self):
27+
AuthenticationClient(app_id=u'4', key=u'key', secret=u'secret', ssl=True, host=u'foo')
28+
29+
self.assertRaises(TypeError, lambda: AuthenticationClient(app_id=u'4', key=u'key', secret=u'secret', ssl=True, host=4))
30+
31+
def test_cluster_should_be_text(self):
32+
AuthenticationClient(app_id=u'4', key=u'key', secret=u'secret', ssl=True, cluster=u'eu')
33+
34+
self.assertRaises(TypeError, lambda: AuthenticationClient(app_id=u'4', key=u'key', secret=u'secret', ssl=True, cluster=4))
35+
36+
def test_host_behaviour(self):
37+
conf = AuthenticationClient(app_id=u'4', key=u'key', secret=u'secret', ssl=True)
38+
self.assertEqual(conf.host, u'api.pusherapp.com', u'default host should be correct')
39+
40+
conf = AuthenticationClient(app_id=u'4', key=u'key', secret=u'secret', ssl=True, cluster=u'eu')
41+
self.assertEqual(conf.host, u'api-eu.pusher.com', u'host should be overriden by cluster setting')
42+
43+
conf = AuthenticationClient(app_id=u'4', key=u'key', secret=u'secret', ssl=True, host=u'foo')
44+
self.assertEqual(conf.host, u'foo', u'host should be overriden by host setting')
45+
46+
conf = AuthenticationClient(app_id=u'4', key=u'key', secret=u'secret', ssl=True, cluster=u'eu', host=u'plah')
47+
self.assertEqual(conf.host, u'plah', u'host should be used in preference to cluster')
48+
2649
def test_authenticate_for_private_channels(self):
2750
authenticationClient = AuthenticationClient(
2851
key=u'foo', secret=u'bar', host=u'host', app_id=u'4', ssl=True)
@@ -36,13 +59,13 @@ def test_authenticate_for_private_channels(self):
3659
def test_authenticate_for_private_encrypted_channels(self):
3760
# The authentication client receives the decoded bytes of the key
3861
# not the base64 representation
39-
master_key=b'8tW5FQLniQ1sBQFwrw7t6TVEsJZd10yY'
62+
master_key=u'OHRXNUZRTG5pUTFzQlFGd3J3N3Q2VFZFc0paZDEweVk='
4063
authenticationClient = AuthenticationClient(
4164
key=u'foo',
4265
secret=u'bar',
4366
host=u'host',
4467
app_id=u'4',
45-
encryption_master_key=master_key,
68+
encryption_master_key_base64=master_key,
4669
ssl=True)
4770

4871
expected = {

0 commit comments

Comments
 (0)