Skip to content

Commit 30b3663

Browse files
qsoftdevelopmentqsdstefandavidnub
committed
Version 4.2.0 (#81)
* Introduce 'delete' permission to Grant * Implement v2 signatures. Update PAM endpoints to /v2. Update PAM tests to support v2 signatures and /v2 endpoints. * Add TokenManager. Implement GrantToken method. Add cbor2 library to dependencies. * Resolve test warnings due to use of deprecated method. * Remove PAM audit tests. Resolve Codacy errors. * Resolve logger deprecation warnings. Add delete_enabled field to PAMv2 Grant tests. * Resolved import errors in older Python versions. * Resolve unused variable warning. * Add cbor2 dependency to PyPy. * Prepare for release 4.1.8. * Refactor token manager properties code. * Update .pubnub.yml. * Bumping minor version - David Co-authored-by: Stefan QSD <[email protected]> Co-authored-by: David Lin <[email protected]>
1 parent ff2563f commit 30b3663

File tree

77 files changed

+1230
-540
lines changed

Some content is hidden

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

77 files changed

+1230
-540
lines changed

.pubnub.yml

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,21 @@
11
name: python
2-
version: 4.1.7
2+
version: 4.2.0
33
schema: 1
44
scm: github.com/pubnub/python
55
changelog:
6+
- version: v4.2.0
7+
date: Dec 24, 2019
8+
changes:
9+
- type: improvement
10+
text: Introduced delete permission to Grant endpoint. Migrated to v2 enpdoints for old PAM methods.
11+
- type: feature
12+
text: Added TokenManager and GrantToken method.
13+
- type: improvement
14+
text: Resolved warnings caused by the use of deprecated methods.
15+
- type: bug
16+
text: Removed Audit tests.
17+
- type: bug
18+
text: Resolved incorrectly reported SDK version.
619
- version: v4.1.7
720
date: Dec 2, 2019
821
changes:
@@ -137,6 +150,10 @@ changelog:
137150
features:
138151
access:
139152
- ACCESS-GRANT
153+
- ACCESS-GRANT-MANAGE
154+
- ACCESS-GRANT-DELETE
155+
- ACCESS-GRANT-V3
156+
- ACCESS-TOKEN-MANAGEMENT
140157
- ACCESS-SECRET-KEY-ALL-ACCESS
141158
channel-groups:
142159
- CHANNEL-GROUPS-ADD-CHANNELS
@@ -159,8 +176,10 @@ features:
159176
- PUBLISH-RAW-JSON
160177
- PUBLISH-WITH-METADATA
161178
- PUBLISH-GET
179+
- PUBLISH-POST
162180
- PUBLISH-ASYNC
163181
- PUBLISH-FIRE
182+
- PUBLISH-REPLICATION-FLAG
164183
storage:
165184
- STORAGE-REVERSE
166185
- STORAGE-INCLUDE-TIMETOKEN
@@ -195,6 +214,8 @@ features:
195214
- OBJECTS-UPDATE-SPACE
196215
- OBJECTS-DELETE-SPACE
197216
- OBJECTS-GET-MEMBERSHIPS
217+
- OBJECTS-MANAGE-MEMBERSHIPS
218+
- OBJECTS-MANAGE-MEMBERS
198219
- OBJECTS-JOIN-SPACES
199220
- OBJECTS-UPDATE-MEMBERSHIPS
200221
- OBJECTS-LEAVE-SPACES

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
## [4.2.0](https://github.com/pubnub/python/tree/v4.2.0)
2+
3+
[Full Changelog](https://github.com/pubnub/python/compare/v4.1.7...v4.2.0)
4+
5+
- 🌟 Introduced delete permission to Grant endpoint. Migrated to v2 enpdoints for old PAM methods.
6+
- 🌟 Added TokenManager and GrantToken method.
7+
- 🌟Resolved warnings caused by the use of deprecated methods.
8+
- 🐛Removed Audit tests.
9+
- 🐛Resolved incorrectly reported SDK version.
10+
111
## [4.1.7](https://github.com/pubnub/python/tree/v4.1.7)
212

313
[Full Changelog](https://github.com/pubnub/python/compare/v4.1.6...v4.1.7)

pubnub/endpoints/access/audit.py

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

66

77
class Audit(Endpoint):
8-
AUDIT_PATH = "/v1/auth/audit/sub-key/%s"
8+
AUDIT_PATH = "/v2/auth/audit/sub-key/%s"
99

1010
def __init__(self, pubnub):
1111
Endpoint.__init__(self, pubnub)

pubnub/endpoints/access/grant.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88

99
class Grant(Endpoint):
10-
GRANT_PATH = "/v1/auth/grant/sub-key/%s"
10+
GRANT_PATH = "/v2/auth/grant/sub-key/%s"
1111

1212
def __init__(self, pubnub):
1313
Endpoint.__init__(self, pubnub)
@@ -17,6 +17,7 @@ def __init__(self, pubnub):
1717
self._read = None
1818
self._write = None
1919
self._manage = None
20+
self._delete = None
2021
self._ttl = None
2122

2223
self._sort_params = True
@@ -45,6 +46,10 @@ def manage(self, flag):
4546
self._manage = flag
4647
return self
4748

49+
def delete(self, flag):
50+
self._delete = flag
51+
return self
52+
4853
def ttl(self, ttl):
4954
self._ttl = ttl
5055
return self
@@ -58,6 +63,8 @@ def custom_params(self):
5863
params['w'] = '1' if self._write is True else '0'
5964
if self._manage is not None:
6065
params['m'] = '1' if self._manage is True else '0'
66+
if self._delete is not None:
67+
params['d'] = '1' if self._delete is True else '0'
6168

6269
if len(self._auth_keys) > 0:
6370
params['auth'] = utils.join_items_and_encode(self._auth_keys)
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
from pubnub import utils
2+
from pubnub.endpoints.endpoint import Endpoint
3+
from pubnub.errors import PNERR_RESOURCES_MISSING, PNERR_TTL_MISSING, PNERR_INVALID_META
4+
from pubnub.exceptions import PubNubException
5+
from pubnub.enums import HttpMethod, PNOperationType
6+
from pubnub.models.consumer.v3.access_manager import PNGrantTokenResult
7+
8+
9+
class GrantToken(Endpoint):
10+
GRANT_TOKEN_PATH = "/v3/pam/%s/grant"
11+
12+
READ = 1
13+
WRITE = 2
14+
MANAGE = 4
15+
DELETE = 8
16+
CREATE = 16
17+
18+
def __init__(self, pubnub):
19+
Endpoint.__init__(self, pubnub)
20+
self._ttl = None
21+
self._meta = None
22+
self._channelList = []
23+
self._groupList = []
24+
self._userList = []
25+
self._spaceList = []
26+
27+
self._sort_params = True
28+
29+
def ttl(self, ttl):
30+
self._ttl = ttl
31+
return self
32+
33+
def meta(self, meta):
34+
self._meta = meta
35+
return self
36+
37+
def users(self, users):
38+
self._userList = users
39+
return self
40+
41+
def spaces(self, spaces):
42+
self._spaceList = spaces
43+
return self
44+
45+
def custom_params(self):
46+
return {}
47+
48+
def build_data(self):
49+
params = {'ttl': str(int(self._ttl))}
50+
51+
permissions = {}
52+
resources = {}
53+
patterns = {}
54+
55+
utils.parse_resources(self._channelList, "channels", resources, patterns)
56+
utils.parse_resources(self._groupList, "groups", resources, patterns)
57+
utils.parse_resources(self._userList, "users", resources, patterns)
58+
utils.parse_resources(self._spaceList, "spaces", resources, patterns)
59+
60+
permissions['resources'] = resources
61+
permissions['patterns'] = patterns
62+
63+
if self._meta is not None:
64+
if isinstance(self._meta, dict):
65+
permissions['meta'] = self._meta
66+
else:
67+
raise PubNubException(pn_error=PNERR_INVALID_META)
68+
else:
69+
permissions['meta'] = {}
70+
71+
params['permissions'] = permissions
72+
73+
return utils.write_value_as_string(params)
74+
75+
def build_path(self):
76+
return GrantToken.GRANT_TOKEN_PATH % self.pubnub.config.subscribe_key
77+
78+
def http_method(self):
79+
return HttpMethod.POST
80+
81+
def validate_params(self):
82+
self.validate_subscribe_key()
83+
self.validate_secret_key()
84+
self.validate_ttl()
85+
self.validate_resources()
86+
87+
def create_response(self, envelope):
88+
return PNGrantTokenResult.from_json(envelope['data'])
89+
90+
def is_auth_required(self):
91+
return False
92+
93+
def affected_channels(self):
94+
# generate a list of channels when they become supported in PAMv3
95+
return None
96+
97+
def affected_channels_groups(self):
98+
# generate a list of groups when they become supported in PAMv3
99+
return None
100+
101+
def request_timeout(self):
102+
return self.pubnub.config.non_subscribe_request_timeout
103+
104+
def connect_timeout(self):
105+
return self.pubnub.config.connect_timeout
106+
107+
def operation_type(self):
108+
return PNOperationType.PNAccessManagerGrantToken
109+
110+
def name(self):
111+
return "Grant Token"
112+
113+
def validate_resources(self):
114+
if (self._userList is None or len(self._userList) == 0) and \
115+
(self._spaceList is None or len(self._spaceList) == 0):
116+
raise PubNubException(pn_error=PNERR_RESOURCES_MISSING)
117+
118+
def validate_ttl(self):
119+
if self._ttl is None:
120+
raise PubNubException(pn_error=PNERR_TTL_MISSING)

pubnub/endpoints/endpoint.py

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from abc import ABCMeta, abstractmethod
22

3+
import logging
4+
35
from pubnub import utils
46
from pubnub.enums import PNStatusCategory, PNOperationType
57
from pubnub.errors import PNERR_SUBSCRIBE_KEY_MISSING, PNERR_PUBLISH_KEY_MISSING, PNERR_CHANNEL_OR_GROUP_MISSING, \
@@ -9,6 +11,8 @@
911
from pubnub.models.consumer.pn_error_data import PNErrorData
1012
from ..structures import RequestOptions, ResponseInfo
1113

14+
logger = logging.getLogger("pubnub")
15+
1216

1317
class Endpoint(object):
1418
SERVER_RESPONSE_SUCCESS = 200
@@ -90,7 +94,6 @@ def options(self):
9094

9195
def sync(self):
9296
self.validate_params()
93-
9497
envelope = self.pubnub.request_sync(self.options())
9598

9699
if envelope.status.is_error():
@@ -154,22 +157,17 @@ def callback(params_to_merge):
154157
if self.is_auth_required() and self.pubnub.config.auth_key is not None:
155158
custom_params['auth'] = self.pubnub.config.auth_key
156159

157-
if self.pubnub.config.secret_key is not None:
158-
custom_params['timestamp'] = str(self.pubnub.timestamp())
159-
signed_input = (self.pubnub.config.subscribe_key + "\n" + self.pubnub.config.publish_key + "\n")
160-
161-
if operation_type == PNOperationType.PNAccessManagerAudit:
162-
signed_input += 'audit\n'
163-
elif operation_type == PNOperationType.PNAccessManagerGrant or \
164-
operation_type == PNOperationType.PNAccessManagerRevoke:
165-
signed_input += 'grant\n'
166-
else:
167-
signed_input += self.build_path() + "\n"
160+
if self.pubnub.config.disable_token_manager is False and self.pubnub.config.auth_key is None:
161+
tms_properties = self.get_tms_properties()
162+
if tms_properties is not None:
163+
token = self.pubnub.get_token(tms_properties)
164+
if token is not None:
165+
custom_params['auth'] = token
166+
else:
167+
logger.warning("No token found for: " + str(tms_properties))
168168

169-
signed_input += utils.prepare_pam_arguments(custom_params)
170-
signature = utils.sign_sha256(self.pubnub.config.secret_key, signed_input)
171-
172-
custom_params['signature'] = signature
169+
if self.pubnub.config.secret_key is not None:
170+
utils.sign_request(self, self.pubnub, custom_params, self.http_method(), self.build_data())
173171

174172
# REVIEW: add encoder map to not hardcode encoding here
175173
if operation_type == PNOperationType.PNPublishOperation and 'meta' in custom_params:
@@ -248,3 +246,6 @@ def create_exception(self, category, response, response_info, exception):
248246
exception.status = status
249247

250248
return exception
249+
250+
def get_tms_properties(self):
251+
return None

pubnub/endpoints/membership/get_members.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
from pubnub import utils
44
from pubnub.endpoints.endpoint import Endpoint
5+
from pubnub.managers import TokenManagerProperties
56
from pubnub.models.consumer.membership import PNGetMembersResult
6-
from pubnub.enums import HttpMethod, PNOperationType
7+
from pubnub.enums import HttpMethod, PNOperationType, PNResourceType
78
from pubnub.exceptions import PubNubException
89

910

@@ -98,3 +99,9 @@ def operation_type(self):
9899

99100
def name(self):
100101
return 'Get members'
102+
103+
def get_tms_properties(self):
104+
return TokenManagerProperties(
105+
resource_type=PNResourceType.SPACE,
106+
resource_id=self._space_id if self._space_id is not None else ""
107+
)

pubnub/endpoints/membership/get_space_memberships.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
from pubnub import utils
44
from pubnub.endpoints.endpoint import Endpoint
5+
from pubnub.managers import TokenManagerProperties
56
from pubnub.models.consumer.membership import PNGetSpaceMembershipsResult
6-
from pubnub.enums import HttpMethod, PNOperationType
7+
from pubnub.enums import HttpMethod, PNOperationType, PNResourceType
78
from pubnub.exceptions import PubNubException
89

910

@@ -98,3 +99,9 @@ def operation_type(self):
9899

99100
def name(self):
100101
return 'Get space membership'
102+
103+
def get_tms_properties(self):
104+
return TokenManagerProperties(
105+
resource_type=PNResourceType.USER,
106+
resource_id=self._user_id if self._user_id is not None else ""
107+
)

pubnub/endpoints/membership/manage_members.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
from pubnub import utils
44
from pubnub.endpoints.endpoint import Endpoint
5+
from pubnub.managers import TokenManagerProperties
56
from pubnub.models.consumer.membership import PNManageMembersResult
6-
from pubnub.enums import HttpMethod, PNOperationType
7+
from pubnub.enums import HttpMethod, PNOperationType, PNResourceType
78
from pubnub.exceptions import PubNubException
89

910

@@ -108,3 +109,9 @@ def operation_type(self):
108109

109110
def name(self):
110111
return 'Update members'
112+
113+
def get_tms_properties(self):
114+
return TokenManagerProperties(
115+
resource_type=PNResourceType.SPACE,
116+
resource_id=self._space_id if self._space_id is not None else ""
117+
)

pubnub/endpoints/membership/manage_memberships.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
from pubnub import utils
44
from pubnub.endpoints.endpoint import Endpoint
5+
from pubnub.managers import TokenManagerProperties
56
from pubnub.models.consumer.membership import PNManageMembershipsResult
6-
from pubnub.enums import HttpMethod, PNOperationType
7+
from pubnub.enums import HttpMethod, PNOperationType, PNResourceType
78
from pubnub.exceptions import PubNubException
89

910

@@ -108,3 +109,9 @@ def operation_type(self):
108109

109110
def name(self):
110111
return 'Update space memberships'
112+
113+
def get_tms_properties(self):
114+
return TokenManagerProperties(
115+
resource_type=PNResourceType.USER,
116+
resource_id=self._user_id if self._user_id is not None else ""
117+
)

0 commit comments

Comments
 (0)