Skip to content

Commit bd2a8eb

Browse files
AikoBBAigerim Beishenbekovapetrsvihlik
authored
[Python] Custom Teams Endpoint (CTE) GA (Azure#22987)
* regenerated & updated new client for GA(2022-06-01) version * updated recordings & unit tests for CTE * updated networktraversal recordings * removed all occurrences of api_version parameter in other SDKs * changed release version * updated helper.py in all test shared folder * synced test shared folders * fix for cspell check Co-authored-by: Aigerim Beishenbekova <[email protected]> Co-authored-by: Petr Švihlík <[email protected]>
1 parent 6d22152 commit bd2a8eb

File tree

113 files changed

+2934
-827
lines changed

Some content is hidden

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

113 files changed

+2934
-827
lines changed

.vscode/cspell.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,9 @@
393393
"FNNHHJT",
394394
"Zwiz",
395395
"nypg",
396-
"PBOF"
396+
"PBOF",
397+
"tzutc",
398+
"gettz"
397399
]
398400
},
399401
{
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
# -------------------------------------------------------------------------
3+
# Copyright (c) Microsoft Corporation. All rights reserved.
4+
# Licensed under the MIT License. See License.txt in the project root for
5+
# license information.
6+
# --------------------------------------------------------------------------
7+
from azure.core.credentials import AccessToken
8+
9+
class AsyncFakeTokenCredential(object):
10+
def __init__(self):
11+
self.token = AccessToken("Fake Token", 0)
12+
13+
async def get_token(self, *args):
14+
return self.token

sdk/communication/azure-communication-chat/tests/_shared/asynctestcase.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
from azure_devtools.scenario_tests.utilities import trim_kwargs_from_test_function
1010
from .testcase import CommunicationTestCase
1111

12-
1312
class AsyncCommunicationTestCase(CommunicationTestCase):
1413

1514
@staticmethod
@@ -24,4 +23,4 @@ def run(test_class_instance, *args, **kwargs):
2423
loop = asyncio.get_event_loop()
2524
return loop.run_until_complete(test_fn(test_class_instance, **kwargs))
2625

27-
return run
26+
return run
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# ------------------------------------
2+
# Copyright (c) Microsoft Corporation.
3+
# Licensed under the MIT License.
4+
# ------------------------------------
5+
6+
import functools
7+
from devtools_testutils import PowerShellPreparer
8+
9+
CommunicationPreparer = functools.partial(
10+
PowerShellPreparer, "communication",
11+
communication_livetest_dynamic_connection_string="endpoint=https://sanitized.communication.azure.com/;accesskey=fake==="
12+
)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
# -------------------------------------------------------------------------
3+
# Copyright (c) Microsoft Corporation. All rights reserved.
4+
# Licensed under the MIT License. See License.txt in the project root for
5+
# license information.
6+
# --------------------------------------------------------------------------
7+
from azure.core.credentials import AccessToken
8+
9+
class FakeTokenCredential(object):
10+
def __init__(self):
11+
self.token = AccessToken("Fake Token", 0)
12+
13+
def get_token(self, *args):
14+
return self.token

sdk/communication/azure-communication-chat/tests/_shared/helper.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,17 @@ def process_request(self, request):
3939
def process_response(self, response):
4040
if 'url' in response:
4141
response['url'] = re.sub('/identities/([^/?]+)', '/identities/sanitized', response['url'])
42+
return response
43+
44+
class URIMsalUsernameReplacer(RecordingProcessor):
45+
"""Replace the MSAL username in request uri"""
46+
def process_request(self, request):
47+
resource = (urlparse(request.uri).netloc).split('.')[0]
48+
request.uri = re.sub('common/userrealm/([^/.]+)', 'common/userrealm/sanitized@test', request.uri)
49+
request.uri = re.sub(resource, 'sanitized', request.uri)
50+
return request
51+
52+
def process_response(self, response):
53+
if 'url' in response:
54+
response['url'] = re.sub('common/userrealm/([^/.]+)', 'common/userrealm/sanitized@test', response['url'])
4255
return response

sdk/communication/azure-communication-chat/tests/_shared/testcase.py

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,31 @@ def process_request(self, request):
4646

4747
def process_response(self, response):
4848
if is_text_payload(response) and response['body']['string']:
49-
response['body'] = self._replace_keys(response['body']['string'])
49+
response['body']['string'] = self._replace_keys(response['body']['string'])
5050

5151
return response
5252

5353
def _replace_keys(self, body):
54+
def _replace_recursively(obj):
55+
if isinstance(obj, dict):
56+
for key in obj:
57+
value = obj[key]
58+
if key in self._keys:
59+
obj[key] = self._replacement
60+
elif key == 'iceServers':
61+
_replace_recursively(value[0])
62+
elif key == 'urls':
63+
obj[key][0] = "turn.skype.com"
64+
else:
65+
_replace_recursively(value)
66+
elif isinstance(obj, list):
67+
for i in obj:
68+
_replace_recursively(i)
69+
5470
import json
5571
try:
5672
body = json.loads(body)
57-
for key in self._keys:
58-
if key in body:
59-
body[key] = self._replacement
73+
_replace_recursively(body)
6074

6175
except (KeyError, ValueError):
6276
return body
@@ -72,9 +86,10 @@ def __init__(self, method_name, *args, **kwargs):
7286
def setUp(self):
7387
super(CommunicationTestCase, self).setUp()
7488
if self.is_playback():
75-
self.connection_str = "endpoint=https://sanitized/;accesskey=fake==="
89+
self.connection_str = "endpoint=https://sanitized.communication.azure.com/;accesskey=fake==="
7690
else:
77-
self.connection_str = os.getenv('COMMUNICATION_LIVETEST_DYNAMIC_CONNECTION_STRING')
91+
self.connection_str = os.getenv('COMMUNICATION_LIVETEST_DYNAMIC_CONNECTION_STRING') or \
92+
os.getenv('COMMUNICATION_LIVETEST_STATIC_CONNECTION_STRING')
7893
endpoint, _ = parse_connection_str(self.connection_str)
7994
self._resource_name = endpoint.split(".")[0]
80-
self.scrubber.register_name_pair(self._resource_name, "sanitized")
95+
self.scrubber.register_name_pair(self._resource_name, "sanitized")

sdk/communication/azure-communication-chat/tests/_shared/utils.py

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,30 @@
33
# Licensed under the MIT License. See License.txt in the project root for
44
# license information.
55
# -------------------------------------------------------------------------
6+
import os
7+
from typing import ( # pylint: disable=unused-import
8+
cast,
9+
Tuple,
10+
)
11+
from azure.core.pipeline.policies import HttpLoggingPolicy, HeadersPolicy
612

7-
from azure.core.pipeline.policies import HttpLoggingPolicy
13+
def create_token_credential():
14+
# type: () -> FakeTokenCredential or DefaultAzureCredential
15+
from devtools_testutils import is_live
16+
if not is_live():
17+
from .fake_token_credential import FakeTokenCredential
18+
return FakeTokenCredential()
19+
from azure.identity import DefaultAzureCredential
20+
return DefaultAzureCredential()
21+
22+
def async_create_token_credential():
23+
# type: () -> AsyncFakeTokenCredential or DefaultAzureCredential
24+
from devtools_testutils import is_live
25+
if not is_live():
26+
from .async_fake_token_credential import AsyncFakeTokenCredential
27+
return AsyncFakeTokenCredential()
28+
from azure.identity.aio import DefaultAzureCredential
29+
return DefaultAzureCredential()
830

931
def get_http_logging_policy(**kwargs):
1032
http_logging_policy = HttpLoggingPolicy(**kwargs)
@@ -14,3 +36,39 @@ def get_http_logging_policy(**kwargs):
1436
}
1537
)
1638
return http_logging_policy
39+
40+
def get_header_policy(**kwargs):
41+
header_policy = HeadersPolicy(**kwargs)
42+
43+
useragent = os.getenv("AZURE_USERAGENT_OVERRIDE")
44+
if useragent:
45+
header_policy.add_header("x-ms-useragent", useragent)
46+
47+
return header_policy
48+
49+
def parse_connection_str(conn_str):
50+
# type: (str) -> Tuple[str, str, str, str]
51+
if conn_str is None:
52+
raise ValueError(
53+
"Connection string is undefined."
54+
)
55+
endpoint = None
56+
shared_access_key = None
57+
for element in conn_str.split(";"):
58+
key, _, value = element.partition("=")
59+
if key.lower() == "endpoint":
60+
endpoint = value.rstrip("/")
61+
elif key.lower() == "accesskey":
62+
shared_access_key = value
63+
if not all([endpoint, shared_access_key]):
64+
raise ValueError(
65+
"Invalid connection string. You can get the connection string from your resource page in the Azure Portal. "
66+
"The format should be as follows: endpoint=https://<ResourceUrl>/;accesskey=<KeyValue>"
67+
)
68+
left_slash_pos = cast(str, endpoint).find("//")
69+
if left_slash_pos != -1:
70+
host = cast(str, endpoint)[left_slash_pos + 2:]
71+
else:
72+
host = str(endpoint)
73+
74+
return host, str(shared_access_key)

sdk/communication/azure-communication-identity/CHANGELOG.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
# Release History
22

3-
## 1.2.0 (Unreleased)
3+
## 1.1.0 (Unreleased)
44

55
### Features Added
6+
- Added support to build a custom Teams endpoint using Microsoft 365 Teams identities:
7+
- Added `get_token_for_teams_user(aad_token, client_id, user_object_id)` method that provides the ability to exchange an Azure AD access token of a Teams user for a Communication Identity access token to `CommunicationIdentityClient`.
8+
- Removed `ApiVersion.V2021_10_31_preview` from API versions.
9+
- Added a new API version `ApiVersion.V2022_06_01` that is now the deafult API version
610

711
### Breaking Changes
812

@@ -16,7 +20,7 @@
1620
### Features Added
1721

1822
- Added support for Microsoft 365 Teams identities
19-
- `CommunicationIdentityClient` added a new method `get_token_for_teams_user` that provides the ability to exchange an AAD access token of a Teams user for a Communication Identity access token
23+
- `CommunicationIdentityClient` added a new method `get_token_for_teams_user` that provides the ability to exchange an Azure AD access token of a Teams user for a Communication Identity access token
2024

2125
## 1.0.1 (2021-06-08)
2226

0 commit comments

Comments
 (0)