Skip to content

Commit dea9c0b

Browse files
PubNub SDK v5.2.0 release.
1 parent d840f41 commit dea9c0b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+713
-222
lines changed

.pubnub.yml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: python
2-
version: 5.1.4
2+
version: 5.2.0
33
schema: 1
44
scm: github.com/pubnub/python
55
sdks:
@@ -169,8 +169,14 @@ sdks:
169169
license-url: https://github.com/aio-libs/aiohttp/blob/master/LICENSE.txt
170170
is-required: Required
171171
changelog:
172+
- version: v5.2.0
173+
date: 2021-08-31
174+
changes:
175+
-
176+
text: "Furthermore PAMv3 tokens can now be used within other PubNub features."
177+
type: feature
172178
- version: v5.1.4
173-
date: Jun 29, 2021
179+
date: 2021-06-29
174180
changes:
175181
-
176182
text: "Additionally, example code for the FastAPI integration was added."
@@ -179,7 +185,7 @@ changelog:
179185
date: 2021-04-26
180186
changes:
181187
-
182-
text: "Disabling default request headers within the Endpoind."
188+
text: "Disabling default request headers within the Endpoint."
183189
type: bug
184190
- version: v5.1.2
185191
date: 2021-04-15

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## [v5.2.0](https://github.com/pubnub/python/releases/tag/v5.2.0)
2+
3+
[Full Changelog](https://github.com/pubnub/python/compare/v5.1.4...v5.2.0)
4+
5+
- 🌟️ Furthermore PAMv3 tokens can now be used within other PubNub features.
6+
17
## [v5.1.4](https://github.com/pubnub/python/releases/tag/v5.1.4)
28

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

DEVELOPER.md

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Developers manual
22

33
## Supported Python versions
4-
We support Python 2.7 and >=3.4
4+
We support Python 3.6, 3.7, 3.8, 3.9
55

66
## Supported platforms
77
We maintain and test our SDK using Travis.CI and Ubuntu.
@@ -30,26 +30,17 @@ There are 2 types of calls:
3030

3131
You can find more examples here https://github.com/pubnub/python/blob/master/tests/integrational/asyncio/test_invocations.py
3232

33-
### Tornado
34-
Tornado supports by Python 2.7 and Python >= 3.3.
35-
There are 2 types of calls:
36-
- using `result()` - only a result will be returned; in case of exception it will be raised natively
37-
- using `future()` - a wrapper (Envelope) for a result and a status; in case of exception it can be checked using env.is_error()
38-
39-
You can find more examples here https://github.com/pubnub/python/blob/master/tests/integrational/tornado/test_invocations.py
40-
41-
### Twisted
42-
Twisted is supported by Python 2.7 only.
43-
4433
## Tests
4534
* Test runner: py.test
4635
* Source code checker: flake
36+
* BDD tests runner: behave - one needs to place needed feature file under acceptance/name_of_the_feature directory.
37+
An example: `behave tests/acceptance/pam`
4738

4839
## Daemon mode with Native SDK
4940
Daemon mode for all requests are disabled by default. This means that all asynchronous requests including will block the main thread until all the children be closed. If SDK user want to use Java-like behaviour when it's up to him to decide should he wait for response completion or continue program execution, he has to explicitly set daemon mode to true:
5041

5142
```python
52-
pubnub.config.daemon = true
43+
pubnub.config.daemon = True
5344
```
5445

5546
## SubscribeListener

pubnub/endpoints/access/grant_token.py

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from pubnub import utils
22
from pubnub.endpoints.endpoint import Endpoint
3-
from pubnub.errors import PNERR_RESOURCES_MISSING, PNERR_TTL_MISSING, PNERR_INVALID_META
3+
from pubnub.errors import PNERR_TTL_MISSING, PNERR_INVALID_META, PNERR_RESOURCES_MISSING
44
from pubnub.exceptions import PubNubException
55
from pubnub.enums import HttpMethod, PNOperationType
66
from pubnub.models.consumer.v3.access_manager import PNGrantTokenResult
@@ -9,20 +9,14 @@
99
class GrantToken(Endpoint):
1010
GRANT_TOKEN_PATH = "/v3/pam/%s/grant"
1111

12-
READ = 1
13-
WRITE = 2
14-
MANAGE = 4
15-
DELETE = 8
16-
CREATE = 16
17-
1812
def __init__(self, pubnub):
1913
Endpoint.__init__(self, pubnub)
2014
self._ttl = None
2115
self._meta = None
16+
self._authorized_uuid = None
2217
self._channels = []
2318
self._groups = []
24-
self._users = []
25-
self._spaces = []
19+
self._uuids = []
2620

2721
self._sort_params = True
2822

@@ -34,6 +28,10 @@ def meta(self, meta):
3428
self._meta = meta
3529
return self
3630

31+
def authorized_uuid(self, uuid):
32+
self._authorized_uuid = uuid
33+
return self
34+
3735
def channels(self, channels):
3836
self._channels = channels
3937
return self
@@ -42,40 +40,40 @@ def groups(self, groups):
4240
self._groups = groups
4341
return self
4442

45-
def users(self, users):
46-
self._users = users
47-
return self
48-
49-
def spaces(self, spaces):
50-
self._spaces = spaces
43+
def uuids(self, uuids):
44+
self._uuids = uuids
5145
return self
5246

5347
def custom_params(self):
5448
return {}
5549

5650
def build_data(self):
57-
params = {'ttl': str(self._ttl)}
51+
params = {'ttl': int(self._ttl)}
5852

5953
permissions = {}
6054
resources = {}
6155
patterns = {}
6256

6357
utils.parse_resources(self._channels, "channels", resources, patterns)
6458
utils.parse_resources(self._groups, "groups", resources, patterns)
65-
utils.parse_resources(self._users, "users", resources, patterns)
66-
utils.parse_resources(self._spaces, "spaces", resources, patterns)
59+
utils.parse_resources(self._uuids, "uuids", resources, patterns)
60+
utils.parse_resources(self._uuids, "users", resources, patterns)
61+
utils.parse_resources(self._uuids, "spaces", resources, patterns)
6762

6863
permissions['resources'] = resources
6964
permissions['patterns'] = patterns
7065

71-
if self._meta is not None:
66+
if self._meta:
7267
if isinstance(self._meta, dict):
7368
permissions['meta'] = self._meta
7469
else:
7570
raise PubNubException(pn_error=PNERR_INVALID_META)
7671
else:
7772
permissions['meta'] = {}
7873

74+
if self._authorized_uuid:
75+
permissions["uuid"] = self._authorized_uuid
76+
7977
params['permissions'] = permissions
8078

8179
return utils.write_value_as_string(params)
@@ -111,12 +109,9 @@ def name(self):
111109
return "Grant Token"
112110

113111
def validate_resources(self):
114-
if (self._channels is None or len(self._channels) == 0) and \
115-
(self._groups is None or len(self._groups) == 0) and \
116-
(self._users is None or len(self._users) == 0) and \
117-
(self._spaces is None or len(self._spaces) == 0):
112+
if not any((self._channels, self._groups, self._uuids)):
118113
raise PubNubException(pn_error=PNERR_RESOURCES_MISSING)
119114

120115
def validate_ttl(self):
121-
if self._ttl is None:
116+
if not self._ttl:
122117
raise PubNubException(pn_error=PNERR_TTL_MISSING)

pubnub/endpoints/endpoint.py

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -183,19 +183,13 @@ def callback(params_to_merge):
183183
for query_key, query_value in self.pubnub._telemetry_manager.operation_latencies().items():
184184
custom_params[query_key] = query_value
185185

186-
if self.is_auth_required() and self.pubnub.config.auth_key is not None:
187-
custom_params['auth'] = self.pubnub.config.auth_key
188-
189-
if self.pubnub.config.disable_token_manager is False and self.pubnub.config.auth_key is None:
190-
tms_properties = self.get_tms_properties()
191-
if tms_properties is not None:
192-
token = self.pubnub.get_token(tms_properties)
193-
if token is not None:
194-
custom_params['auth'] = token
195-
else:
196-
logger.warning("No token found for: " + str(tms_properties))
197-
198-
if self.pubnub.config.secret_key is not None:
186+
if self.is_auth_required():
187+
if self.pubnub._get_token():
188+
custom_params["auth"] = self.pubnub._get_token()
189+
elif self.pubnub.config.auth_key:
190+
custom_params["auth"] = self.pubnub.config.auth_key
191+
192+
if self.pubnub.config.secret_key:
199193
utils.sign_request(self, self.pubnub, custom_params, self.http_method(), self.build_data())
200194

201195
custom_params.update(self.encoded_params())
@@ -283,6 +277,3 @@ def create_exception(self, category, response, response_info, exception):
283277
exception.status = status
284278

285279
return exception
286-
287-
def get_tms_properties(self):
288-
return None

pubnub/enums.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
from enum import Enum
2+
3+
14
class HttpMethod(object):
25
GET = 1
36
POST = 2
@@ -135,3 +138,14 @@ class PNMatchType(object):
135138
class PNPushEnvironment(object):
136139
DEVELOPMENT = "development"
137140
PRODUCTION = "production"
141+
142+
143+
class PAMPermissions(Enum):
144+
READ = 1
145+
WRITE = 2
146+
MANAGE = 4
147+
DELETE = 8
148+
CREATE = 16
149+
GET = 32
150+
UPDATE = 64
151+
JOIN = 128

pubnub/errors.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
PNERR_RESOURCES_MISSING = "Resources missing"
3333
PNERR_TTL_MISSING = "TTL missing"
3434
PNERR_INVALID_META = "Invalid meta parameter"
35-
PNERR_PERMISSION_MISSING = "Permission missing"
3635
PNERR_INVALID_ACCESS_TOKEN = "Invalid access token"
3736
PNERR_MESSAGE_ACTION_MISSING = "Message action is missing"
3837
PNERR_MESSAGE_ACTION_TYPE_MISSING = "Message action type is missing"

pubnub/managers.py

Lines changed: 9 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from cbor2 import loads
99

1010
from . import utils
11-
from .enums import PNStatusCategory, PNReconnectionPolicy, PNOperationType, PNResourceType, PNMatchType
11+
from .enums import PNStatusCategory, PNReconnectionPolicy, PNOperationType
1212
from .models.consumer.common import PNStatus
1313
from .models.server.subscribe import SubscribeEnvelope
1414
from .dtos import SubscribeOperation, UnsubscribeOperation
@@ -507,68 +507,19 @@ def endpoint_name_for_operation(operation_type):
507507

508508

509509
class TokenManager:
510-
511510
def __init__(self):
512-
self._map = {}
513-
self.init_map()
514-
515-
def init_map(self):
516-
resources = [PNResourceType.USER, PNResourceType.SPACE]
517-
518-
for resource in resources:
519-
skeleton_map = {
520-
PNMatchType.RESOURCE: {},
521-
PNMatchType.PATTERN: {}
522-
}
523-
self._map[resource] = skeleton_map
511+
self.token = None
524512

525513
def set_token(self, token):
526-
unwrapped_token = self.unwrap_token(token)
527-
self.store_token(unwrapped_token, token)
528-
529-
def set_tokens(self, tokens):
530-
for token in tokens:
531-
self.set_token(token)
532-
533-
def get_token(self, tms_properties):
534-
resource_token = self.get_token_by_match(tms_properties, PNMatchType.RESOURCE)
535-
536-
if resource_token is None:
537-
return self.get_token_by_match(tms_properties, PNMatchType.PATTERN)
538-
539-
return resource_token
540-
541-
def get_tokens(self):
542-
return self._map
543-
544-
def get_tokens_by_resource(self, resource_type):
545-
return self._map[resource_type]
546-
547-
def store_token(self, unwrapped_token, token):
548-
match_types = [
549-
PNMatchType.RESOURCE,
550-
PNMatchType.PATTERN
551-
]
552-
553-
for asset in match_types:
554-
short_match_type = self.get_shortened_match_type(asset)
555-
556-
if short_match_type in unwrapped_token:
557-
res_object = unwrapped_token[short_match_type]
558-
559-
for r_type in res_object.keys():
560-
single_res_object = res_object[r_type]
561-
for r_name in single_res_object.keys():
562-
if asset == PNMatchType.PATTERN:
563-
self._map[self.get_extended_resource_type(r_type)][asset].clear()
514+
self.token = token
564515

565-
self._map[self.get_extended_resource_type(r_type)][asset][r_name] = token
516+
def get_token(self):
517+
return self.token
566518

567-
def unwrap_token(self, token):
568-
raw = token
569-
570-
raw = raw.replace("_", "/").replace("-", "+")
571-
byte_array = base64.b64decode(raw)
519+
@staticmethod
520+
def unwrap_token(token):
521+
token = token.replace("_", "/").replace("-", "+")
522+
byte_array = base64.b64decode(token)
572523

573524
try:
574525
unwrapped_obj = loads(byte_array)
@@ -577,45 +528,3 @@ def unwrap_token(self, token):
577528
return decoded_obj
578529
except Exception:
579530
raise PubNubException(pn_error=PNERR_INVALID_ACCESS_TOKEN)
580-
581-
def get_token_by_match(self, tms_properties, match_type):
582-
if tms_properties is None or tms_properties.resource_type is None or tms_properties.resource_id is None:
583-
return None
584-
585-
if match_type != PNMatchType.PATTERN:
586-
if tms_properties.resource_id in self._map[tms_properties.resource_type][match_type]:
587-
token = self._map[tms_properties.resource_type][match_type][tms_properties.resource_id]
588-
if token is not None:
589-
return token
590-
else:
591-
string_token_wrapper_dict = self._map[tms_properties.resource_type][match_type]
592-
if len(string_token_wrapper_dict.keys()) > 0:
593-
first_key = list(string_token_wrapper_dict.keys())[0]
594-
return string_token_wrapper_dict[first_key]
595-
596-
return None
597-
598-
def get_extended_resource_type(self, r_type_abbr):
599-
if r_type_abbr == "usr":
600-
return PNResourceType.USER
601-
if r_type_abbr == "spc":
602-
return PNResourceType.SPACE
603-
604-
return r_type_abbr
605-
606-
def get_shortened_match_type(self, match_type):
607-
if match_type == PNMatchType.RESOURCE:
608-
return "res"
609-
if match_type == PNMatchType.PATTERN:
610-
return "pat"
611-
612-
return match_type
613-
614-
615-
class TokenManagerProperties:
616-
def __init__(self, resource_type, resource_id):
617-
self.resource_type = resource_type
618-
self.resource_id = resource_id
619-
620-
def __str__(self):
621-
return "resource_type: " + self.resource_type + ", resource_id: " + self.resource_id

0 commit comments

Comments
 (0)