Skip to content

Commit

Permalink
[Communication] - Phone Number Management - Added support for AAD auth (
Browse files Browse the repository at this point in the history
#16075)

* Added support for AAD auth

* added successful test recording

* Addressed comments

* Edited readme

* Fixed README
  • Loading branch information
jbeauregardb authored Feb 3, 2021
1 parent ab3a17d commit 1c69e0c
Show file tree
Hide file tree
Showing 10 changed files with 138 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ Caller must provide one of the following:
- Added `MicrosoftTeamsUserIdentifier`

##### `IdentityClient`
- Added support for Azure Active Directory authentication for the Identity client

- Added support for Azure Active Directory authentication

#### `PhoneNumberAdministrationClient`
- Added support for Azure Active Directory authentication
## 1.0.0b3 (2020-11-16)

### Breaking Changes
Expand Down
17 changes: 17 additions & 0 deletions sdk/communication/azure-communication-administration/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,22 @@ pip install azure-communication-administration

## CommunicationPhoneNumberClient
### Initializing Phone Number Client
```python
# You can find your endpoint and access token from your resource in the Azure Portal
import os
from azure.communication.administration import PhoneNumberAdministrationClient
from azure.identity import DefaultAzureCredential

endpoint = os.getenv('AZURE_COMMUNICATION_SERVICE_ENDPOINT')

# To use Azure Active Directory Authentication (DefaultAzureCredential) make sure to have your
# AZURE_TENANT_ID, AZURE_CLIENT_ID and AZURE_CLIENT_SECRET as env variables.
phone_number_administration_client = PhoneNumberAdministrationClient(endpoint, DefaultAzureCredential())

```
### Initializing Phone Number Client Using Connection String
Connection string authentication is also available for Phone Number Client.

```python
# You can find your endpoint and access token from your resource in the Azure Portal
import os
Expand All @@ -28,6 +44,7 @@ from azure.communication.administration import PhoneNumberAdministrationClient
connection_str = os.getenv('AZURE_COMMUNICATION_SERVICE_CONNECTION_STRING')
phone_number_administration_client = PhoneNumberAdministrationClient.from_connection_string(connection_str)
```

### Phone plans overview

Phone plans come in two types; Geographic and Toll-Free. Geographic phone plans are phone plans associated with a location, whose phone numbers' area codes are associated with the area code of a geographic location. Toll-Free phone plans are phone plans not associated location. For example, in the US, toll-free numbers can come with area codes such as 800 or 888.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@
UpdatePhoneNumberCapabilitiesResponse
)

from ._shared.utils import parse_connection_str
from ._shared.policy import HMACCredentialsPolicy
from ._shared.utils import parse_connection_str, get_authentication_policy
from ._version import SDK_MONIKER

class PhoneNumberAdministrationClient(object):
Expand Down Expand Up @@ -64,7 +63,7 @@ def __init__(
self._endpoint = endpoint
self._phone_number_administration_client = PhoneNumberAdministrationClientGen(
self._endpoint,
authentication_policy=HMACCredentialsPolicy(endpoint, credential),
authentication_policy=get_authentication_policy(endpoint, credential),
sdk_moniker=SDK_MONIKER,
**kwargs)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@
UpdatePhoneNumberCapabilitiesResponse
)

from .._shared.utils import parse_connection_str
from .._shared.policy import HMACCredentialsPolicy
from .._shared.utils import parse_connection_str, get_authentication_policy

class PhoneNumberAdministrationClient(object):
"""Azure Communication Services Phone Number Management client.
Expand Down Expand Up @@ -70,7 +69,7 @@ def __init__(
self._endpoint = endpoint
self._phone_number_administration_client = PhoneNumberAdministrationClientGen(
self._endpoint,
authentication_policy=HMACCredentialsPolicy(endpoint, credential),
authentication_policy=get_authentication_policy(endpoint, credential, is_async=True),
sdk_moniker=SDK_MONIKER,
**kwargs)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# -------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# --------------------------------------------------------------------------
from azure.core.credentials import AccessToken

class FakeTokenCredential(object):
def __init__(self):
self.token = AccessToken("Fake Token", 0)

def get_token(self, *args):
return self.token
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# ------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# -------------------------------------------------------------------------
from .fake_token_credential import FakeTokenCredential
from azure.identity import DefaultAzureCredential

def create_token_credential():
# type: () -> FakeTokenCredential or DefaultAzureCredential
from devtools_testutils import is_live
if not is_live():
return FakeTokenCredential()
return DefaultAzureCredential()
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
User-Agent:
- azsdk-python-communication-administration/1.0.0b4 Python/3.8.5 (Windows-10-10.0.19041-SP0)
method: GET
uri: https://sanitized.communication.azure.com/administration/phonenumbers/phonenumbers?locale=en-US&skip=0&take=100&api-version=2020-07-20-preview1
response:
body:
string: '{"phoneNumbers": "sanitized", "nextLink": null}'
headers:
content-type:
- application/json; charset=utf-8
date:
- Thu, 28 Jan 2021 18:48:48 GMT
ms-cv:
- /rMw3sZH40i74G71li+lDA.0
request-context:
- appId=
transfer-encoding:
- chunked
x-processing-time:
- 1124ms
status:
code: 200
message: OK
version: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
User-Agent:
- azsdk-python-communication-administration/1.0.0b4 Python/3.8.5 (Windows-10-10.0.19041-SP0)
method: GET
uri: https://sanitized.communication.azure.com/administration/phonenumbers/phonenumbers?locale=en-US&skip=0&take=100&api-version=2020-07-20-preview1
response:
body:
string: '{"phoneNumbers": "sanitized", "nextLink": null}'
headers:
content-type: application/json; charset=utf-8
date: Thu, 28 Jan 2021 18:49:47 GMT
ms-cv: jqpEP/JsFUKDau9Y0tMhbw.0
request-context: appId=
transfer-encoding: chunked
x-processing-time: 765ms
status:
code: 200
message: OK
url: https://sanitized.communication.azure.com/administration/phonenumbers/phonenumbers?locale=en-US&skip=0&take=100&api-version=2020-07-20-preview1
version: 1
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,17 @@
NumberUpdateCapabilities,
CreateSearchOptions
)
from azure.core.credentials import AccessToken
from phone_number_helper import PhoneNumberUriReplacer
from phone_number_testcase import PhoneNumberCommunicationTestCase
from _shared.testcase import BodyReplacerProcessor
from _shared.utils import create_token_credential
from azure.communication.administration._shared.utils import parse_connection_str

SKIP_PHONE_NUMBER_TESTS = True
PHONE_NUMBER_TEST_SKIP_REASON= "Phone Number Administration live tests infra not ready yet"

class PhoneNumberAdministrationClientTest(PhoneNumberCommunicationTestCase):

def setUp(self):
super(PhoneNumberAdministrationClientTest, self).setUp()
self.recording_processors.extend([
Expand Down Expand Up @@ -125,6 +127,15 @@ def setUp(self):
self.capabilities_id = "capabilities_id"
self.release_id = "release_id"

@pytest.mark.live_test_only
@pytest.mark.skipif(SKIP_PHONE_NUMBER_TESTS, reason=PHONE_NUMBER_TEST_SKIP_REASON)
def test_list_all_phone_numbers_from_managed_identity(self):
endpoint, access_key = parse_connection_str(self.connection_str)
credential = create_token_credential()
phone_number_client = PhoneNumberAdministrationClient(endpoint, credential)
pages = phone_number_client.list_all_phone_numbers()
assert pages.next()

@pytest.mark.live_test_only
@pytest.mark.skipif(SKIP_PHONE_NUMBER_TESTS, reason=PHONE_NUMBER_TEST_SKIP_REASON)
def test_list_all_phone_numbers(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
# --------------------------------------------------------------------------
import pytest
from azure.communication.administration.aio import PhoneNumberAdministrationClient
from azure.communication.administration._shared.utils import parse_connection_str
from azure.communication.administration import (
PstnConfiguration,
NumberUpdateCapabilities,
Expand All @@ -14,6 +15,7 @@
from phone_number_helper import PhoneNumberUriReplacer
from phone_number_testcase_async import AsyncPhoneNumberCommunicationTestCase
from _shared.testcase import BodyReplacerProcessor, ResponseReplacerProcessor
from _shared.utils import create_token_credential
import os

SKIP_PHONE_NUMBER_TESTS = True
Expand Down Expand Up @@ -126,6 +128,20 @@ def setUp(self):
self.capabilities_id = "capabilities_id"
self.release_id = "release_id"

@AsyncPhoneNumberCommunicationTestCase.await_prepared_test
@pytest.mark.live_test_only
@pytest.mark.skipif(SKIP_PHONE_NUMBER_TESTS, reason=PHONE_NUMBER_TEST_SKIP_REASON)
async def test_list_all_phone_numbers_from_managed_identity(self):
endpoint, access_key = parse_connection_str(self.connection_str)
credential = create_token_credential()
phone_number_client = PhoneNumberAdministrationClient(endpoint, credential)
async with phone_number_client:
pages = phone_number_client.list_all_phone_numbers()
items = []
async for item in pages:
items.append(item)
assert len(items) > 0

@AsyncPhoneNumberCommunicationTestCase.await_prepared_test
@pytest.mark.live_test_only
@pytest.mark.skipif(SKIP_PHONE_NUMBER_TESTS, reason=PHONE_NUMBER_TEST_SKIP_REASON)
Expand Down

0 comments on commit 1c69e0c

Please sign in to comment.