Skip to content

Commit 70fac22

Browse files
committed
2 parents 8ce1192 + 453ba34 commit 70fac22

File tree

20 files changed

+328
-177
lines changed

20 files changed

+328
-177
lines changed

.github/workflows/commands-handler.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ jobs:
2323
uses: ./.github/.release/actions/actions/commands
2424
with:
2525
token: ${{ secrets.GH_TOKEN }}
26+
jira-api-key: ${{ secrets.JIRA_API_KEY }}
2627
listener: client-engineering-bot

.github/workflows/release.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,5 @@ jobs:
5454
uses: ./.github/.release/actions/actions/services/github-release
5555
with:
5656
token: ${{ secrets.GH_TOKEN }}
57+
jira-api-key: ${{ secrets.JIRA_API_KEY }}
5758
last-service: true

.github/workflows/run_acceptance_tests.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ jobs:
2222
token: ${{ secrets.GH_TOKEN }}
2323
- name: Install Python dependencies and run acceptance tests
2424
run: |
25+
cp sdk-specifications/features/access/authorization-failure-reporting.feature tests/acceptance/pam
2526
cp sdk-specifications/features/access/grant-token.feature tests/acceptance/pam
27+
cp sdk-specifications/features/access/revoke-token.feature tests/acceptance/pam
28+
2629
sudo pip3 install -r requirements-dev.txt
2730
behave --junit tests/acceptance/pam
2831
- name: Expose acceptance tests reports

.pubnub.yml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: python
2-
version: 5.4.0
2+
version: 5.5.0
33
schema: 1
44
scm: github.com/pubnub/python
55
sdks:
@@ -18,7 +18,7 @@ sdks:
1818
distributions:
1919
- distribution-type: library
2020
distribution-repository: package
21-
package-name: pubnub-5.1.3
21+
package-name: pubnub-5.5.0
2222
location: https://pypi.org/project/pubnub/
2323
supported-platforms:
2424
supported-operating-systems:
@@ -97,8 +97,8 @@ sdks:
9797
-
9898
distribution-type: library
9999
distribution-repository: git release
100-
package-name: pubnub-5.1.3
101-
location: https://github.com/pubnub/python/releases/download/v5.1.3/pubnub-5.1.3.tar.gz
100+
package-name: pubnub-5.5.0
101+
location: https://github.com/pubnub/python/releases/download/v5.5.0/pubnub-5.5.0.tar.gz
102102
supported-platforms:
103103
supported-operating-systems:
104104
Linux:
@@ -169,6 +169,12 @@ sdks:
169169
license-url: https://github.com/aio-libs/aiohttp/blob/master/LICENSE.txt
170170
is-required: Required
171171
changelog:
172+
- date: 2021-12-16
173+
version: v5.5.0
174+
changes:
175+
-
176+
text: "Revoke token functionality."
177+
type: feature
172178
- version: v5.4.0
173179
date: 2021-10-07
174180
changes:
@@ -479,6 +485,7 @@ features:
479485
- ACCESS-GRANT-TOKEN
480486
- ACCESS-PARSE-TOKEN
481487
- ACCESS-SET-TOKEN
488+
- ACCESS-REVOKE-TOKEN
482489
channel-groups:
483490
- CHANNEL-GROUPS-ADD-CHANNELS
484491
- CHANNEL-GROUPS-REMOVE-CHANNELS

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
## v5.5.0
2+
December 16 2021
3+
4+
## [v5.5.0](https://github.com/pubnub/python/releases/tag/v5.5.0)
5+
6+
- 🌟️ Revoke token functionality.
7+
8+
## v5.4.0
9+
December 16 2021
10+
111
## [v5.4.0](https://github.com/pubnub/python/releases/tag/v5.4.0)
212

313
[Full Changelog](https://github.com/pubnub/python/compare/v5.3.1...v5.4.0)

pubnub/endpoints/access/revoke.py

Lines changed: 0 additions & 30 deletions
This file was deleted.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from pubnub.enums import PNOperationType, HttpMethod
2+
from pubnub.endpoints.endpoint import Endpoint
3+
from pubnub.models.consumer.v3.access_manager import PNRevokeTokenResult
4+
from pubnub import utils
5+
6+
7+
class RevokeToken(Endpoint):
8+
REVOKE_TOKEN_PATH = "/v3/pam/%s/grant/%s"
9+
10+
def __init__(self, pubnub, token):
11+
Endpoint.__init__(self, pubnub)
12+
self.token = token
13+
14+
def validate_params(self):
15+
self.validate_subscribe_key()
16+
self.validate_secret_key()
17+
18+
def create_response(self, envelope):
19+
return PNRevokeTokenResult(envelope)
20+
21+
def is_auth_required(self):
22+
return False
23+
24+
def request_timeout(self):
25+
return self.pubnub.config.non_subscribe_request_timeout
26+
27+
def connect_timeout(self):
28+
return self.pubnub.config.connect_timeout
29+
30+
def http_method(self):
31+
return HttpMethod.DELETE
32+
33+
def custom_params(self):
34+
return {}
35+
36+
def build_path(self):
37+
return RevokeToken.REVOKE_TOKEN_PATH % (self.pubnub.config.subscribe_key, utils.url_encode(self.token))
38+
39+
def operation_type(self):
40+
return PNOperationType.PNAccessManagerRevokeToken
41+
42+
def name(self):
43+
return "RevokeToken"

pubnub/enums.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ class PNOperationType(object):
6969
PNFireOperation = 25
7070
PNSignalOperation = 26
7171

72+
PNAccessManagerRevokeToken = 40
7273
PNAccessManagerGrantToken = 41
74+
7375
PNAddMessageAction = 42
7476
PNGetMessageActions = 43
7577
PNDeleteMessageAction = 44

pubnub/managers.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,9 @@ def endpoint_name_for_operation(operation_type):
466466
PNOperationType.PNAccessManagerRevoke: 'pam',
467467
PNOperationType.PNTimeOperation: 'pam',
468468

469+
PNOperationType.PNAccessManagerGrantToken: 'pamv3',
470+
PNOperationType.PNAccessManagerRevokeToken: 'pamv3',
471+
469472
PNOperationType.PNSignalOperation: 'sig',
470473

471474
PNOperationType.PNSetUuidMetadataOperation: 'obj',
@@ -488,8 +491,6 @@ def endpoint_name_for_operation(operation_type):
488491
PNOperationType.PNRemoveMembershipsOperation: 'obj',
489492
PNOperationType.PNManageMembershipsOperation: 'obj',
490493

491-
PNOperationType.PNAccessManagerGrantToken: 'pamv3',
492-
493494
PNOperationType.PNAddMessageAction: 'msga',
494495
PNOperationType.PNGetMessageActions: 'msga',
495496
PNOperationType.PNDeleteMessageAction: 'msga',

pubnub/models/consumer/v3/access_manager.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,11 @@ def __str__(self):
2121

2222
def get_token(self):
2323
return self.token
24+
25+
26+
class PNRevokeTokenResult:
27+
def __init__(self, result):
28+
self.status = result['status']
29+
30+
def __str__(self):
31+
return "Revoke token success with status: %s" % self.status

pubnub/pubnub_core.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
from .endpoints.access.audit import Audit
2828
from .endpoints.access.grant import Grant
2929
from .endpoints.access.grant_token import GrantToken
30-
from .endpoints.access.revoke import Revoke
30+
from .endpoints.access.revoke_token import RevokeToken
3131
from .endpoints.channel_groups.add_channel_to_channel_group import AddChannelToChannelGroup
3232
from .endpoints.channel_groups.list_channels_in_channel_group import ListChannelsInChannelGroup
3333
from .endpoints.channel_groups.remove_channel_from_channel_group import RemoveChannelFromChannelGroup
@@ -65,7 +65,7 @@
6565

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

7171
TIMESTAMP_DIVIDER = 1000
@@ -170,8 +170,8 @@ def grant(self):
170170
def grant_token(self):
171171
return GrantToken(self)
172172

173-
def revoke(self):
174-
return Revoke(self)
173+
def revoke_token(self, token):
174+
return RevokeToken(self, token)
175175

176176
def audit(self):
177177
return Audit(self)

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.4.0',
5+
version='5.5.0',
66
description='PubNub Real-time push service in the cloud',
77
author='PubNub',
88
author_email='support@pubnub.com',

tests/acceptance/pam/steps/given_steps.py

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from pubnub.models.consumer.v3.channel import Channel
55
from pubnub.models.consumer.v3.group import Group
66
from pubnub.models.consumer.v3.uuid import UUID
7-
from tests.helper import PAM_TOKEN_WITH_ALL_PERMS_GRANTED
7+
from tests.helper import PAM_TOKEN_WITH_ALL_PERMS_GRANTED, PAM_TOKEN_EXPIRED, PAM_TOKEN_WITH_PUBLISH_ENABLED
88

99

1010
@given("I have a keyset with access manager enabled")
@@ -22,6 +22,33 @@ def step_impl(context):
2222
}
2323

2424

25+
@given("I have a keyset with access manager enabled - without secret key")
26+
def step_impl(context):
27+
pubnub_instance = PubNub(pnconf_pam_acceptance_copy())
28+
pubnub_instance.config.secret_key = None
29+
context.peer_without_secret_key = pubnub_instance
30+
31+
32+
@given("a valid token with permissions to publish with channel {channel}")
33+
def step_impl(context, channel):
34+
context.token = PAM_TOKEN_WITH_PUBLISH_ENABLED
35+
36+
37+
@given("an expired token with permissions to publish with channel {channel}")
38+
def step_impl(context, channel):
39+
context.token = PAM_TOKEN_EXPIRED
40+
41+
42+
@given("the token string {token}")
43+
def step_impl(context, token):
44+
context.token = token.strip("'")
45+
46+
47+
@given("a token")
48+
def step_impl(context):
49+
context.token = PAM_TOKEN_WITH_PUBLISH_ENABLED
50+
51+
2552
@given("the TTL {ttl}")
2653
def step_impl(context, ttl):
2754
context.TTL = ttl
@@ -209,17 +236,17 @@ def step_impl(context):
209236

210237
@given("I have a known token containing UUID pattern Permissions")
211238
def step_impl(context):
212-
context.token_to_parse = PAM_TOKEN_WITH_ALL_PERMS_GRANTED
239+
context.token = PAM_TOKEN_WITH_ALL_PERMS_GRANTED
213240

214241

215242
@given("I have a known token containing UUID resource permissions")
216243
def step_impl(context):
217-
context.token_to_parse = PAM_TOKEN_WITH_ALL_PERMS_GRANTED
244+
context.token = PAM_TOKEN_WITH_ALL_PERMS_GRANTED
218245

219246

220247
@given("I have a known token containing an authorized UUID")
221248
def step_impl(context):
222-
context.token_to_parse = PAM_TOKEN_WITH_ALL_PERMS_GRANTED
249+
context.token = PAM_TOKEN_WITH_ALL_PERMS_GRANTED
223250

224251

225252
@given("token resource permission READ")
@@ -254,29 +281,43 @@ def step_impl(context):
254281

255282
@given("the error status code is {status}")
256283
def step_impl(context, status):
257-
assert context.grant_call_error["status"] == int(status)
284+
assert context.pam_call_error["status"] == int(status)
258285

259286

260287
@given("the error message is {err_msg}")
261288
def step_impl(context, err_msg):
262-
assert context.grant_call_error["error"]["message"] == err_msg.strip("'")
289+
assert context.pam_call_error["error"]["message"] == err_msg.strip("'")
263290

264291

265292
@given("the error source is {err_source}")
266293
def step_impl(context, err_source):
267-
assert context.grant_call_error["error"]["source"] == err_source.strip("'")
294+
assert context.pam_call_error["error"]["source"] == err_source.strip("'")
268295

269296

270297
@given("the error detail message is {err_detail}")
271298
def step_impl(context, err_detail):
272-
assert context.grant_call_error["error"]["details"][0]["message"] == err_detail.strip("'")
299+
err_detail = err_detail.strip("'")
300+
if err_detail == "not empty":
301+
assert context.pam_call_error["error"]["details"][0]["message"]
302+
else:
303+
assert context.pam_call_error["error"]["details"][0]["message"] == err_detail
273304

274305

275306
@given("the error detail location is {err_detail_location}")
276307
def step_impl(context, err_detail_location):
277-
assert context.grant_call_error["error"]["details"][0]["location"] == err_detail_location.strip("'")
308+
assert context.pam_call_error["error"]["details"][0]["location"] == err_detail_location.strip("'")
278309

279310

280311
@given("the error detail location type is {err_detail_location_type}")
281312
def step_impl(context, err_detail_location_type):
282-
assert context.grant_call_error["error"]["details"][0]["locationType"] == err_detail_location_type.strip("'")
313+
assert context.pam_call_error["error"]["details"][0]["locationType"] == err_detail_location_type.strip("'")
314+
315+
316+
@given("the error service is {service_name}")
317+
def step_impl(context, service_name):
318+
assert context.pam_call_error["service"] == service_name.strip("'")
319+
320+
321+
@given("the auth error message is {message}")
322+
def step_impl(context, message):
323+
assert context.pam_call_error["message"] == message.strip("'")

tests/acceptance/pam/steps/then_steps.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import json
12
from behave import then
3+
from pubnub.exceptions import PubNubException
24

35

46
@then("the token contains the TTL 60")
@@ -58,10 +60,26 @@ def step_impl(context, channel_group):
5860

5961
@then("I see the error message {error} and details {error_details}")
6062
def step_impl(context, error, error_details):
61-
assert context.grant_call_error["error"]["message"] == error.strip("'")
62-
assert context.grant_call_error["error"]["details"][0]["message"] == error_details.strip("'")
63+
assert context.pam_call_error["error"]["message"] == error.strip("'")
64+
assert context.pam_call_error["error"]["details"][0]["message"] == error_details.strip("'")
6365

6466

6567
@then("an error is returned")
6668
def step_impl(context):
67-
assert context.grant_call_error
69+
assert context.pam_call_error
70+
71+
72+
@then("I get confirmation that token has been revoked")
73+
def step_impl(context):
74+
assert context.revoke_result.result.status == 200
75+
76+
77+
@then("an auth error is returned")
78+
def step_impl(context):
79+
assert isinstance(context.pam_call_result, PubNubException)
80+
context.pam_call_error = json.loads(context.pam_call_result._errormsg)
81+
82+
83+
@then("the result is successful")
84+
def step_impl(context):
85+
assert context.publish_result.result.timetoken

0 commit comments

Comments
 (0)