def test_task_queue_default(self): account_sid = "AC123" auth_token = "foobar" workspace_sid = "WS456" taskqueue_sid = "WQ789" capability = TaskRouterCapability(account_sid, auth_token, workspace_sid, taskqueue_sid) capability.generate_token() token = capability.generate_token() self.assertNotEqual(None, token) decoded = jwt.decode(token, auth_token) self.assertNotEqual(None, decoded) self.check_decoded(decoded, account_sid, workspace_sid, taskqueue_sid, taskqueue_sid) policies = decoded['policies'] self.assertEqual(len(policies), 3) for method, url, policy in [ ('GET', "https://event-bridge.twilio.com/v1/wschannels/AC123/WQ789", policies[0]), ('POST', "https://event-bridge.twilio.com/v1/wschannels/AC123/WQ789", policies[1]) ('GET', "https://taskrouter.twilio.com/v1/Workspaces/WS456/TaskQueues/WQ789", policies[2]) ]: yield self.check_policy, method, url, policy
def test_empty_grants(self): scat = AccessToken(SIGNING_KEY_SID, ACCOUNT_SID, 'secret') token = str(scat) assert_is_not_none(token) payload = decode(token, 'secret') self._validate_claims(payload) assert_equal([], payload['grants'])
def test_default(self): token = self.capability.generate_token() self.assertNotEqual(None, token) decoded = jwt.decode(token, self.auth_token) self.assertNotEqual(None, decoded) policies = decoded['policies'] self.assertEqual(len(policies), 3) # websocket GET get_policy = policies[0] self.assertEqual("https://event-bridge.twilio.com/v1/wschannels/AC123/WQ789", get_policy['url']) self.assertEqual("GET", get_policy['method']) self.assertTrue(get_policy['allow']) self.assertEqual({}, get_policy['query_filter']) self.assertEqual({}, get_policy['post_filter']) # websocket POST post_policy = policies[1] self.assertEqual("https://event-bridge.twilio.com/v1/wschannels/AC123/WQ789", post_policy['url']) self.assertEqual("POST", post_policy['method']) self.assertTrue(post_policy['allow']) self.assertEqual({}, post_policy['query_filter']) self.assertEqual({}, post_policy['post_filter']) # fetch GET fetch_policy = policies[2] self.assertEqual("https://taskrouter.twilio.com/v1/Workspaces/WS456/TaskQueues/WQ789", fetch_policy['url']) self.assertEqual("GET", fetch_policy['method']) self.assertTrue(fetch_policy['allow']) self.assertEqual({}, fetch_policy['query_filter']) self.assertEqual({}, fetch_policy['post_filter'])
def test_defaults(self): token = self.cap.generate_token() decoded = jwt.decode(token, self.auth_token) self.assertTrue(decoded is not None) websocket_url = ( 'https://event-bridge.twilio.com/v1/wschannels/%s/%s' % (self.account_sid, self.worker_sid) ) expected = [ { 'url': websocket_url, 'method': 'GET', 'allow': True, 'query_filter': {}, 'post_filter': {}, }, { 'url': websocket_url, 'method': 'POST', 'allow': True, 'query_filter': {}, 'post_filter': {}, }, { 'url': 'https://taskrouter.twilio.com/v1/Workspaces/WS456/Activities', 'method': 'GET', 'allow': True, 'query_filter': {}, 'post_filter': {}, }, ] self.assertEqual(expected, decoded['policies'])
def test_worker_default(self): account_sid = "AC123" auth_token = "foobar" workspace_sid = "WS456" worker_sid = "WK789" capability = TaskRouterCapability(account_sid, auth_token, workspace_sid, worker_sid) capability.generate_token() token = capability.generate_token() self.assertIsNotNone(token) decoded = jwt.decode(token, auth_token) self.assertIsNotNone(decoded) self.check_decoded(decoded, account_sid, workspace_sid, worker_sid, worker_sid) policies = decoded["policies"] self.assertEqual(len(policies), 5) for method, url, policy in [ ("GET", "https://taskrouter.twilio.com/v1/Workspaces/WS456/Activities", policies[0]), ("GET", "https://taskrouter.twilio.com/v1/Workspaces/WS456/Tasks/**", policies[1]), ("GET", "https://taskrouter.twilio.com/v1/wschannels/AC123/WK789", policies[2]), ("POST", "https://event-bridge.twilio.com/v1/wschannels/AC123/WK789", policies[3]), ("GET", "https://taskrouter.twilio.com/v1/Workspaces/WS456/Workers/WK789", policies[4]), ]: yield self.check_policy, method, url, policy
def test_empty_grants(self): scat = AccessToken(ACCOUNT_SID, SIGNING_KEY_SID, "secret") token = str(scat) assert_is_not_none(token) payload = decode(token, "secret") self._validate_claims(payload) assert_equal({}, payload["grants"])
def test_generate_token_with_default_ttl(self): token = self.capability.generate_token() self.assertIsNotNone(token) decoded = jwt.decode(token, self.auth_token) self.assertIsNotNone(decoded) self.assertEqual(int(time.time()) + 3600, decoded["exp"])
def test_generate_token(self): token = self.capability.generate_token() self.assertIsNotNone(token) decoded = jwt.decode(token, self.auth_token) self.assertIsNotNone(decoded) self.check_decoded(decoded, self.account_sid, self.workspace_sid, self.worker_sid, self.worker_sid)
def test_nbf(self): now = int(time.mktime(datetime.now().timetuple())) scat = AccessToken(ACCOUNT_SID, SIGNING_KEY_SID, 'secret', nbf=now) token = str(scat) assert_is_not_none(token) payload = decode(token, 'secret') self._validate_claims(payload) assert_equal(now, payload['nbf'])
def test_single_grant(self): scat = AccessToken(SIGNING_KEY_SID, ACCOUNT_SID, 'secret') scat.add_grant('https://api.twilio.com/**') token = str(scat) assert_is_not_none(token) payload = decode(token, 'secret') self._validate_claims(payload) assert_equal(1, len(payload['grants'])) assert_equal('https://api.twilio.com/**', payload['grants'][0]['res']) assert_equal(['*'], payload['grants'][0]['act'])
def test_ip_messaging_grant(self): scat = AccessToken(ACCOUNT_SID, SIGNING_KEY_SID, "secret") scat.add_grant(IpMessagingGrant()) token = str(scat) assert_is_not_none(token) payload = decode(token, "secret") self._validate_claims(payload) assert_equal(1, len(payload["grants"])) assert_equal({}, payload["grants"]["ip_messaging"])
def test_conversations_grant(self): scat = AccessToken(ACCOUNT_SID, SIGNING_KEY_SID, "secret") scat.add_grant(ConversationsGrant()) token = str(scat) assert_is_not_none(token) payload = decode(token, "secret") self._validate_claims(payload) assert_equal(1, len(payload["grants"])) assert_equal({}, payload["grants"]["rtc"])
def test_generate_token_with_custom_ttl(self): ttl = 10000 token = self.capability.generate_token(ttl) self.assertIsNotNone(token) decoded = jwt.decode(token, self.auth_token) self.assertIsNotNone(decoded) self.assertEqual(int(time.time()) + 10000, decoded["exp"])
def test_allow_task_reservation_updates(self): self.cap.allow_task_reservation_updates() token = self.cap.generate_token() decoded = jwt.decode(token, self.auth_token) self.assertTrue(decoded is not None) url = "https://taskrouter.twilio.com/v1/Workspaces/{0}/Tasks/**".format(self.workspace_sid) expected = {"url": url, "method": "POST", "allow": True, "query_filter": {}, "post_filter": {}} self.assertEqual(expected, decoded["policies"][-1])
def test_identity(self): scat = AccessToken(ACCOUNT_SID, SIGNING_KEY_SID, 'secret', identity='*****@*****.**') token = str(scat) assert_is_not_none(token) payload = decode(token, 'secret') self._validate_claims(payload) assert_equal({ 'identity': '*****@*****.**' }, payload['grants'])
def test_endpoint_grant(self): scat = AccessToken(SIGNING_KEY_SID, ACCOUNT_SID, 'secret') scat.add_endpoint_grant('bob') token = str(scat) assert_is_not_none(token) payload = decode(token, 'secret') self._validate_claims(payload) assert_equal(1, len(payload['grants'])) assert_equal('sip:[email protected]', payload['grants'][0]['res']) assert_equal(['listen', 'invite'], payload['grants'][0]['act'])
def test_enable_nts(self): scat = AccessToken(SIGNING_KEY_SID, ACCOUNT_SID, 'secret') scat.enable_nts() token = str(scat) assert_is_not_none(token) payload = decode(token, 'secret') self._validate_claims(payload) assert_equal(1, len(payload['grants'])) assert_equal('https://api.twilio.com/2010-04-01/Accounts/AC123/Tokens.json', payload['grants'][0]['res']) assert_equal(['POST'], payload['grants'][0]['act'])
def test_allow_worker_fetch_attributes(self): self.cap.allow_worker_fetch_attributes() token = self.cap.generate_token() decoded = jwt.decode(token, self.auth_token) self.assertTrue(decoded is not None) url = "https://taskrouter.twilio.com/v1/Workspaces/{0}/Workers/{1}".format(self.workspace_sid, self.worker_sid) expected = {"url": url, "method": "GET", "allow": True, "query_filter": {}, "post_filter": {}} self.assertEqual(expected, decoded["policies"][-1])
def test_grants(self): scat = AccessToken(ACCOUNT_SID, SIGNING_KEY_SID, 'secret') scat.add_grant(ConversationsGrant()) scat.add_grant(IpMessagingGrant()) token = str(scat) assert_is_not_none(token) payload = decode(token, 'secret') self._validate_claims(payload) assert_equal(2, len(payload['grants'])) assert_equal({}, payload['grants']['rtc']) assert_equal({}, payload['grants']['ip_messaging'])
def test_conversations_grant(self): scat = AccessToken(ACCOUNT_SID, SIGNING_KEY_SID, 'secret') scat.add_grant(ConversationsGrant(configuration_profile_sid='CP123')) token = str(scat) assert_is_not_none(token) payload = decode(token, 'secret') self._validate_claims(payload) assert_equal(1, len(payload['grants'])) assert_equal({ 'configuration_profile_sid': 'CP123' }, payload['grants']['rtc'])
def test_deprecated_worker(self): account_sid = "AC123" auth_token = "foobar" workspace_sid = "WS456" worker_sid = "WK789" capability = TaskRouterCapability(account_sid, auth_token, workspace_sid, worker_sid) capability.generate_token() token = capability.generate_token() self.assertNotEqual(None, token) decoded = jwt.decode(token, auth_token) self.assertNotEqual(None, decoded) self.check_decoded(decoded, account_sid, workspace_sid, worker_sid, worker_sid) policies = decoded['policies'] self.assertEqual(len(policies), 6) # should expect 6 policies for method, url, policy in [ ('GET', "https://event-bridge.twilio.com/v1/wschannels/AC123/WK789", policies[0]), ('POST', "https://event-bridge.twilio.com/v1/wschannels/AC123/WK789", policies[1]), ('GET', "https://taskrouter.twilio.com/v1/Workspaces/WS456/Activities", policies[2]), ('GET', "https://taskrouter.twilio.com/v1/Workspaces/WS456/Tasks/**", policies[3]), ('GET', "https://taskrouter.twilio.com/v1/Workspaces/WS456/Workers/WK789/Reservations/**", policies[4]), ('GET', "https://taskrouter.twilio.com/v1/Workspaces/WS456/Workers/WK789", policies[5]) ]: yield self.check_policy, method, url, policy # check deprecated warnings with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") capability.allow_worker_fetch_attributes() assert len(w) == 1 assert issubclass(w[-1].category, DeprecationWarning) assert "deprecated" in str(w[-1].message) with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") capability.allow_worker_activity_updates() assert len(w) == 1 assert issubclass(w[-1].category, DeprecationWarning) assert "deprecated" in str(w[-1].message) with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") capability.allow_task_reservation_updates() assert len(w) == 1 assert issubclass(w[-1].category, DeprecationWarning) assert "deprecated" in str(w[-1].message)
def test_ip_messaging_grant(self): scat = AccessToken(ACCOUNT_SID, SIGNING_KEY_SID, 'secret') scat.add_grant(IpMessagingGrant(service_sid='IS123', push_credential_sid='CR123')) token = str(scat) assert_is_not_none(token) payload = decode(token, 'secret') self._validate_claims(payload) assert_equal(1, len(payload['grants'])) assert_equal({ 'service_sid': 'IS123', 'push_credential_sid': 'CR123' }, payload['grants']['ip_messaging'])
def test_sync_grant(self): scat = AccessToken(ACCOUNT_SID, SIGNING_KEY_SID, 'secret') scat.add_grant(SyncGrant(service_sid='IS123', endpoint_id='some-endpoint')) token = str(scat) assert_is_not_none(token) payload = decode(token, 'secret') self._validate_claims(payload) assert_equal(1, len(payload['grants'])) assert_equal({ 'service_sid': 'IS123', 'endpoint_id': 'some-endpoint' }, payload['grants']['data_sync'])
def test_generate_token(self): token = self.capability.generate_token() self.assertNotEqual(None, token) decoded = jwt.decode(token, self.auth_token) self.assertNotEqual(None, decoded) self.assertEqual(decoded["iss"], self.account_sid) self.assertEqual(decoded["account_sid"], self.account_sid) self.assertEqual(decoded["workspace_sid"], self.workspace_sid) self.assertEqual(decoded["taskqueue_sid"], self.taskqueue_sid) self.assertEqual(decoded["channel"], self.taskqueue_sid) self.assertEqual(decoded["version"], "v1") self.assertEqual(decoded["friendly_name"], self.taskqueue_sid)
def test_default(self): token = self.capability.generate_token() self.assertIsNotNone(token) decoded = jwt.decode(token, self.auth_token) self.assertIsNotNone(decoded) policies = decoded['policies'] self.assertEqual(len(policies), 3) for method, url, policy in [ ('GET', "https://event-bridge.twilio.com/v1/wschannels/AC123/WS456", policies[0]), ('POST', "https://event-bridge.twilio.com/v1/wschannels/AC123/WS456", policies[1]), ('GET', "https://taskrouter.twilio.com/v1/Workspaces/WS456", policies[2]) ]: yield self.check_policy, method, url, policy
def test_allow_updates_subresources(self): self.capability.allow_updates_subresources() token = self.capability.generate_token() self.assertIsNotNone(token) decoded = jwt.decode(token, self.auth_token) self.assertIsNotNone(decoded) policies = decoded['policies'] self.assertEqual(len(policies), 4) # confirm the additional policy generated with allow_updates_subresources() policy = policies[3] self.check_policy('POST', "https://taskrouter.twilio.com/v1/Workspaces/WS456/**", policy)
def test_decode(self): token = TwilioCapability("AC123", "XXXXX") token.allow_client_outgoing("AP123", foobar=3) token.allow_client_incoming("andy") token.allow_event_stream() outgoing_uri = "scope:client:outgoing?appParams=foobar%3D3&appSid=AP123&clientName=andy" incoming_uri = "scope:client:incoming?clientName=andy" event_uri = "scope:stream:subscribe?path=%2F2010-04-01%2FEvents" result = jwt.decode(token.generate(), "XXXXX") scope = result["scope"].split(" ") self.assertIn(outgoing_uri, scope) self.assertIn(incoming_uri, scope) self.assertIn(event_uri, scope)
def test_defaults(self): token = self.cap.generate_token() decoded = jwt.decode(token, self.auth_token) self.assertTrue(decoded is not None) websocket_url = "https://event-bridge.twilio.com/v1/wschannels/{0}/{1}".format( self.account_sid, self.worker_sid ) expected = [ {"url": websocket_url, "method": "GET", "allow": True, "query_filter": {}, "post_filter": {}}, {"url": websocket_url, "method": "POST", "allow": True, "query_filter": {}, "post_filter": {}}, { "url": "https://taskrouter.twilio.com/v1/Workspaces/WS456/Activities", "method": "GET", "allow": True, "query_filter": {}, "post_filter": {}, }, { "url": "https://taskrouter.twilio.com/v1/Workspaces/{0}/Tasks/**".format(self.workspace_sid), "method": "GET", "allow": True, "query_filter": {}, "post_filter": {}, }, { "url": "https://taskrouter.twilio.com/v1/Workspaces/{0}/Workers/{1}/Reservations/**".format( self.workspace_sid, self.worker_sid ), "method": "GET", "allow": True, "query_filter": {}, "post_filter": {}, }, { "url": "https://taskrouter.twilio.com/v1/Workspaces/{0}/Workers/{1}".format( self.workspace_sid, self.worker_sid ), "method": "GET", "allow": True, "query_filter": {}, "post_filter": {}, }, ] self.assertEqual(expected, decoded["policies"])
def test_generate_token(self): token = self.cap.generate_token() decoded = jwt.decode(token, self.auth_token) self.assertTrue(decoded is not None) del decoded["exp"] del decoded["policies"] expected = { "iss": self.account_sid, "account_sid": self.account_sid, "workspace_sid": self.workspace_sid, "worker_sid": self.worker_sid, "channel": self.worker_sid, "version": "v1", "friendly_name": self.worker_sid, } self.assertEqual(expected, decoded)
def test_generate_token(self): token = self.cap.generate_token() decoded = jwt.decode(token, self.auth_token) self.assertTrue(decoded is not None) del decoded['exp'] del decoded['policies'] expected = { 'iss': self.account_sid, 'account_sid': self.account_sid, 'workspace_sid': self.workspace_sid, 'worker_sid': self.worker_sid, 'channel': self.worker_sid, 'version': 'v1', 'friendly_name': self.worker_sid, } self.assertEqual(expected, decoded)
def test_encode_decode(self): secret = 'secret' jwt_message = jwt.encode(self.payload, secret) decoded_payload = jwt.decode(jwt_message, secret) self.assertEqual(decoded_payload, self.payload)
def test_allow_skip_verification(self): right_secret = 'foo' jwt_message = jwt.encode(self.payload, right_secret) decoded_payload = jwt.decode(jwt_message, verify=False) self.assertEqual(decoded_payload, self.payload)
def test_decodes_valid_jwt(self): example_payload = {"hello": "world"} example_secret = "secret" example_jwt = "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJoZWxsbyI6ICJ3b3JsZCJ9.tvagLDLoaiJKxOKqpBXSEGy7SYSifZhjntgm9ctpyj8" decoded_payload = jwt.decode(example_jwt, example_secret) self.assertEqual(decoded_payload, example_payload)
def test_generate_token_custom_ttl(self): token = self.cap.generate_token(10000) decoded = jwt.decode(token, self.auth_token) self.assertTrue(decoded is not None) self.assertEqual(int(time.time()) + 10000, decoded['exp'])
def test_deprecated_worker(self): account_sid = "AC123" auth_token = "foobar" workspace_sid = "WS456" worker_sid = "WK789" capability = TaskRouterCapability(account_sid, auth_token, workspace_sid, worker_sid) capability.generate_token() token = capability.generate_token() self.assertNotEqual(None, token) decoded = jwt.decode(token, auth_token) self.assertNotEqual(None, decoded) self.check_decoded(decoded, account_sid, workspace_sid, worker_sid, worker_sid) policies = decoded['policies'] self.assertEqual(len(policies), 5) # should expect 5 policies for method, url, policy in [ ('GET', "https://taskrouter.twilio.com/v1/Workspaces/WS456/Activities", policies[0]), ('GET', "https://taskrouter.twilio.com/v1/Workspaces/WS456/Tasks/**", policies[1]), ('GET', "https://event-bridge.twilio.com/v1/wschannels/AC123/WK789", policies[2]), ('POST', "https://event-bridge.twilio.com/v1/wschannels/AC123/WK789", policies[3]), ('GET', "https://taskrouter.twilio.com/v1/Workspaces/WS456/Workers/WK789", policies[4]) ]: yield self.check_policy, method, url, policy # check deprecated warnings with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") capability.allow_worker_fetch_attributes() assert len(w) == 1 assert issubclass(w[-1].category, DeprecationWarning) assert "deprecated" in str(w[-1].message) with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") capability.allow_worker_activity_updates() assert len(w) == 1 assert issubclass(w[-1].category, DeprecationWarning) assert "deprecated" in str(w[-1].message) with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") capability.allow_task_reservation_updates() assert len(w) == 1 assert issubclass(w[-1].category, DeprecationWarning) assert "deprecated" in str(w[-1].message)