Skip to content

Commit 3ef0195

Browse files
PubNub SDK v5.1.0 release.
1 parent 5beb601 commit 3ef0195

26 files changed

+878
-492
lines changed

.pubnub.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
name: python
2-
version: 5.0.1
2+
version: 5.1.0
33
schema: 1
44
scm: github.com/pubnub/python
55
changelog:
6+
- version: v5.1.0
7+
date: Mar 8, 2021
8+
changes:
9+
-
10+
text: "BREAKING CHANGE: Add randomized initialization vector usage by default for data encryption / decryption in publish / subscribe / history API calls."
11+
type: feature
612
- version: v5.0.1
713
date: Feb 4, 2021
814
changes:

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## [v5.1.0](https://github.com/pubnub/python/releases/tag/v5.1.0)
2+
3+
[Full Changelog](https://github.com/pubnub/python/compare/v5.0.1...v5.1.0)
4+
5+
- 🌟️ BREAKING CHANGE: Add randomized initialization vector usage by default for data encryption / decryption in publish / subscribe / history API calls.
6+
17
## [v5.0.1](https://github.com/pubnub/python/releases/tag/v5.0.1)
28

39
[Full Changelog](https://github.com/pubnub/python/compare/v5.0.0...v5.0.1)

pubnub/pnconfiguration.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def __init__(self):
2929
self.reconnect_policy = PNReconnectionPolicy.NONE
3030
self.daemon = False
3131
self.disable_token_manager = False
32-
self.use_random_initialization_vector = False
32+
self.use_random_initialization_vector = True
3333
self.suppress_leave_events = False
3434

3535
self.heartbeat_default_values = True

pubnub/pubnub_core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565

6666
class PubNubCore:
6767
"""A base class for PubNub Python API implementations"""
68-
SDK_VERSION = "5.0.1"
68+
SDK_VERSION = "5.1.0"
6969
SDK_NAME = "PubNub-Python"
7070

7171
TIMESTAMP_DIVIDER = 1000

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
setup(
44
name='pubnub',
5-
version='5.0.1',
5+
version='5.1.0',
66
description='PubNub Real-time push service in the cloud',
77
author='PubNub',
88
author_email='[email protected]',

tests/functional/test_publish.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import copy
22
import unittest
33

4-
try:
5-
from mock import MagicMock
6-
except ImportError:
7-
from unittest.mock import MagicMock
4+
5+
from unittest.mock import MagicMock
86

97
from pubnub.endpoints.pubsub.publish import Publish
108
from pubnub.pubnub import PubNub
@@ -139,6 +137,7 @@ def test_pub_with_auth(self):
139137

140138
def test_pub_encrypted_list_message(self):
141139
conf = copy.copy(pnconf)
140+
conf.use_random_initialization_vector = False
142141
conf.cipher_key = "testCipher"
143142

144143
pubnub = MagicMock(

tests/helper.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
from pubnub.crypto import PubNubCryptodome
99
from pubnub.pnconfiguration import PNConfiguration
1010

11-
12-
crypto = PubNubCryptodome(PNConfiguration())
11+
crypto_configuration = PNConfiguration()
12+
crypto = PubNubCryptodome(crypto_configuration)
1313

1414
DEFAULT_TEST_CIPHER_KEY = "testKey"
1515

@@ -71,6 +71,13 @@
7171
mocked_config.publish_key = pub_key_mock
7272
mocked_config.subscribe_key = sub_key_mock
7373

74+
hardcoded_iv_config = PNConfiguration()
75+
hardcoded_iv_config.use_random_initialization_vector = False
76+
77+
78+
def hardcoded_iv_config_copy():
79+
return copy(hardcoded_iv_config)
80+
7481

7582
def mocked_config_copy():
7683
return copy(mocked_config)
@@ -131,14 +138,6 @@ def gen_string(length):
131138
return ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(length))
132139

133140

134-
def gen_decrypt_func(cipher_key=DEFAULT_TEST_CIPHER_KEY):
135-
def decrypter(entry):
136-
mr = crypto.decrypt(cipher_key, entry)
137-
return mr
138-
139-
return decrypter
140-
141-
142141
class CountDownLatch(object):
143142
def __init__(self, count=1):
144143
self.count = count

tests/integrational/asyncio/test_file_upload.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import pytest
22

3+
from unittest.mock import patch
34
from pubnub.pubnub_asyncio import PubNubAsyncio
45
from tests.integrational.vcr_helper import pn_vcr
56
from tests.helper import pnconf_file_copy
@@ -91,17 +92,18 @@ async def test_send_and_download_file(event_loop, file_for_upload):
9192
@pytest.mark.asyncio
9293
async def test_send_and_download_file_encrypted(event_loop, file_for_upload, file_upload_test_data):
9394
pubnub = PubNubAsyncio(pnconf_file_copy(), custom_event_loop=event_loop)
94-
envelope = await send_file(pubnub, file_for_upload, cipher_key="test")
95-
download_envelope = await pubnub.download_file().\
96-
channel(CHANNEL).\
97-
file_id(envelope.result.file_id).\
98-
file_name(envelope.result.name).\
99-
cipher_key("test").\
100-
future()
101-
102-
assert isinstance(download_envelope.result, PNDownloadFileResult)
103-
assert download_envelope.result.data == bytes(file_upload_test_data["FILE_CONTENT"], "utf-8")
104-
pubnub.stop()
95+
with patch("pubnub.crypto.PubNubCryptodome.get_initialization_vector", return_value="knightsofni12345"):
96+
envelope = await send_file(pubnub, file_for_upload, cipher_key="test")
97+
download_envelope = await pubnub.download_file().\
98+
channel(CHANNEL).\
99+
file_id(envelope.result.file_id).\
100+
file_name(envelope.result.name).\
101+
cipher_key("test").\
102+
future()
103+
104+
assert isinstance(download_envelope.result, PNDownloadFileResult)
105+
assert download_envelope.result.data == bytes(file_upload_test_data["FILE_CONTENT"], "utf-8")
106+
pubnub.stop()
105107

106108

107109
@pn_vcr.use_cassette(

tests/integrational/asyncio/test_publish.py

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import pytest
55
import pubnub as pn
66

7+
from unittest.mock import patch
78
from pubnub.exceptions import PubNubException
89
from pubnub.models.consumer.common import PNStatus
910
from pubnub.models.consumer.pubsub import PNPublishResult
@@ -108,27 +109,29 @@ async def test_publish_object_via_post(event_loop):
108109
filter_query_parameters=['uuid', 'seqn', 'pnsdk'])
109110
@pytest.mark.asyncio
110111
async def test_publish_mixed_via_get_encrypted(event_loop):
111-
pubnub = PubNubAsyncio(pnconf_enc_copy(), custom_event_loop=event_loop)
112-
await asyncio.gather(
113-
asyncio.ensure_future(assert_success_publish_get(pubnub, "hi")),
114-
asyncio.ensure_future(assert_success_publish_get(pubnub, 5)),
115-
asyncio.ensure_future(assert_success_publish_get(pubnub, True)),
116-
asyncio.ensure_future(assert_success_publish_get(pubnub, ["hi", "hi2", "hi3"])))
112+
with patch("pubnub.crypto.PubNubCryptodome.get_initialization_vector", return_value="knightsofni12345"):
113+
pubnub = PubNubAsyncio(pnconf_enc_copy(), custom_event_loop=event_loop)
114+
await asyncio.gather(
115+
asyncio.ensure_future(assert_success_publish_get(pubnub, "hi")),
116+
asyncio.ensure_future(assert_success_publish_get(pubnub, 5)),
117+
asyncio.ensure_future(assert_success_publish_get(pubnub, True)),
118+
asyncio.ensure_future(assert_success_publish_get(pubnub, ["hi", "hi2", "hi3"])))
117119

118-
pubnub.stop()
120+
pubnub.stop()
119121

120122

121123
@pn_vcr.use_cassette(
122124
'tests/integrational/fixtures/asyncio/publish/object_via_get_encrypted.yaml',
123125
filter_query_parameters=['uuid', 'seqn', 'pnsdk'],
124-
match_on=['host', 'method', 'query', 'object_in_path_with_decrypt']
126+
match_on=['host', 'method', 'query']
125127
)
126128
@pytest.mark.asyncio
127129
async def test_publish_object_via_get_encrypted(event_loop):
128-
pubnub = PubNubAsyncio(pnconf_enc_copy(), custom_event_loop=event_loop)
129-
await asyncio.ensure_future(assert_success_publish_get(pubnub, {"name": "Alex", "online": True}))
130+
with patch("pubnub.crypto.PubNubCryptodome.get_initialization_vector", return_value="knightsofni12345"):
131+
pubnub = PubNubAsyncio(pnconf_enc_copy(), custom_event_loop=event_loop)
132+
await asyncio.ensure_future(assert_success_publish_get(pubnub, {"name": "Alex", "online": True}))
130133

131-
pubnub.stop()
134+
pubnub.stop()
132135

133136

134137
@pn_vcr.use_cassette(
@@ -138,28 +141,30 @@ async def test_publish_object_via_get_encrypted(event_loop):
138141
)
139142
@pytest.mark.asyncio
140143
async def test_publish_mixed_via_post_encrypted(event_loop):
141-
pubnub = PubNubAsyncio(pnconf_enc_copy(), custom_event_loop=event_loop)
142-
await asyncio.gather(
143-
asyncio.ensure_future(assert_success_publish_post(pubnub, "hi")),
144-
asyncio.ensure_future(assert_success_publish_post(pubnub, 5)),
145-
asyncio.ensure_future(assert_success_publish_post(pubnub, True)),
146-
asyncio.ensure_future(assert_success_publish_post(pubnub, ["hi", "hi2", "hi3"]))
147-
)
144+
with patch("pubnub.crypto.PubNubCryptodome.get_initialization_vector", return_value="knightsofni12345"):
145+
pubnub = PubNubAsyncio(pnconf_enc_copy(), custom_event_loop=event_loop)
146+
await asyncio.gather(
147+
asyncio.ensure_future(assert_success_publish_post(pubnub, "hi")),
148+
asyncio.ensure_future(assert_success_publish_post(pubnub, 5)),
149+
asyncio.ensure_future(assert_success_publish_post(pubnub, True)),
150+
asyncio.ensure_future(assert_success_publish_post(pubnub, ["hi", "hi2", "hi3"]))
151+
)
148152

149-
pubnub.stop()
153+
pubnub.stop()
150154

151155

152156
@pn_vcr.use_cassette(
153157
'tests/integrational/fixtures/asyncio/publish/object_via_post_encrypted.yaml',
154158
filter_query_parameters=['uuid', 'seqn', 'pnsdk'],
155-
match_on=['method', 'path', 'query', 'object_in_body_with_decrypt']
159+
match_on=['method', 'path', 'query']
156160
)
157161
@pytest.mark.asyncio
158162
async def test_publish_object_via_post_encrypted(event_loop):
159-
pubnub = PubNubAsyncio(pnconf_enc_copy(), custom_event_loop=event_loop)
160-
await asyncio.ensure_future(assert_success_publish_post(pubnub, {"name": "Alex", "online": True}))
163+
with patch("pubnub.crypto.PubNubCryptodome.get_initialization_vector", return_value="knightsofni12345"):
164+
pubnub = PubNubAsyncio(pnconf_enc_copy(), custom_event_loop=event_loop)
165+
await asyncio.ensure_future(assert_success_publish_post(pubnub, {"name": "Alex", "online": True}))
161166

162-
pubnub.stop()
167+
pubnub.stop()
163168

164169

165170
@pytest.mark.asyncio

tests/integrational/asyncio/test_subscribe.py

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import pytest
44
import pubnub as pn
55

6+
from unittest.mock import patch
67
from pubnub.models.consumer.pubsub import PNMessageResult
78
from pubnub.pubnub_asyncio import PubNubAsyncio, AsyncioEnvelope, SubscribeListener
89
from tests.helper import pnconf_sub_copy, pnconf_enc_sub_copy
@@ -95,46 +96,49 @@ async def test_subscribe_publish_unsubscribe(event_loop):
9596
pubnub_sub.stop()
9697

9798

98-
@pn_vcr.use_cassette('tests/integrational/fixtures/asyncio/subscription/sub_pub_unsub_enc.yaml',
99-
filter_query_parameters=['pnsdk'])
99+
@pn_vcr.use_cassette(
100+
'tests/integrational/fixtures/asyncio/subscription/sub_pub_unsub_enc.yaml',
101+
filter_query_parameters=['pnsdk']
102+
)
100103
@pytest.mark.asyncio
101104
async def test_encrypted_subscribe_publish_unsubscribe(event_loop):
102105
pubnub = PubNubAsyncio(pnconf_enc_sub_copy(), custom_event_loop=event_loop)
103106
pubnub.config.uuid = 'test-subscribe-asyncio-uuid'
104107

105-
callback = VCR599Listener(1)
106-
channel = "test-subscribe-asyncio-ch"
107-
message = "hey"
108-
pubnub.add_listener(callback)
109-
pubnub.subscribe().channels(channel).execute()
108+
with patch("pubnub.crypto.PubNubCryptodome.get_initialization_vector", return_value="knightsofni12345"):
109+
callback = VCR599Listener(1)
110+
channel = "test-subscribe-asyncio-ch"
111+
message = "hey"
112+
pubnub.add_listener(callback)
113+
pubnub.subscribe().channels(channel).execute()
110114

111-
await callback.wait_for_connect()
115+
await callback.wait_for_connect()
112116

113-
publish_future = asyncio.ensure_future(pubnub.publish().channel(channel).message(message).future())
114-
subscribe_message_future = asyncio.ensure_future(callback.wait_for_message_on(channel))
117+
publish_future = asyncio.ensure_future(pubnub.publish().channel(channel).message(message).future())
118+
subscribe_message_future = asyncio.ensure_future(callback.wait_for_message_on(channel))
115119

116-
await asyncio.wait([
117-
publish_future,
118-
subscribe_message_future
119-
])
120+
await asyncio.wait([
121+
publish_future,
122+
subscribe_message_future
123+
])
120124

121-
publish_envelope = publish_future.result()
122-
subscribe_envelope = subscribe_message_future.result()
125+
publish_envelope = publish_future.result()
126+
subscribe_envelope = subscribe_message_future.result()
123127

124-
assert isinstance(subscribe_envelope, PNMessageResult)
125-
assert subscribe_envelope.channel == channel
126-
assert subscribe_envelope.subscription is None
127-
assert subscribe_envelope.message == message
128-
assert subscribe_envelope.timetoken > 0
128+
assert isinstance(subscribe_envelope, PNMessageResult)
129+
assert subscribe_envelope.channel == channel
130+
assert subscribe_envelope.subscription is None
131+
assert subscribe_envelope.message == message
132+
assert subscribe_envelope.timetoken > 0
129133

130-
assert isinstance(publish_envelope, AsyncioEnvelope)
131-
assert publish_envelope.result.timetoken > 0
132-
assert publish_envelope.status.original_response[0] == 1
134+
assert isinstance(publish_envelope, AsyncioEnvelope)
135+
assert publish_envelope.result.timetoken > 0
136+
assert publish_envelope.status.original_response[0] == 1
133137

134-
pubnub.unsubscribe().channels(channel).execute()
135-
await callback.wait_for_disconnect()
138+
pubnub.unsubscribe().channels(channel).execute()
139+
await callback.wait_for_disconnect()
136140

137-
pubnub.stop()
141+
pubnub.stop()
138142

139143

140144
@pn_vcr.use_cassette('tests/integrational/fixtures/asyncio/subscription/join_leave.yaml',

0 commit comments

Comments
 (0)