Skip to content

Commit

Permalink
[Communication] - Authentication - PhoneNumberAdministrationClient au…
Browse files Browse the repository at this point in the history
…th using token credential (#13271)

* [phoneNumberAdminstrationClient] adding new constructor for phone number to use Token Credential
* [Conflict] taking incoming recordings
* [Recording] Update the query to be true
* [README] update the examples and changelog
* [phoneNumberAdministrationClientWithToken.spec] renmae the test to be more relevant
* [recordedClient] using new common function to create endpoint
* [recordedClient] removing unused COMMUNICATION_ENDPOINT
* [tests.yml] adding the new env vars
JoshuaLai authored Jan 22, 2021

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 40b027d commit 7f89cb1
Showing 20 changed files with 576 additions and 1,191 deletions.
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@
### Added

- `CommunicationIdentityClient` added a constructor that supports `TokenCredential`.
- `PhoneNumberAdministrationClient` added a constructor that supports `TokenCredential`.

## 1.0.0-beta.3 (2020-11-16)

21 changes: 16 additions & 5 deletions sdk/communication/communication-administration/README.md
Original file line number Diff line number Diff line change
@@ -56,18 +56,19 @@ const client = new CommunicationIdentityClient(HOST, credential);
### Using a connection string

```typescript
import { PhoneNumberAdministrationClient } from "@azure/communication-administration";
import { CommunicationIdentityClient } from "@azure/communication-administration";

const connectionString = `endpoint=HOST;accessKey=KEY`;
const client = new CommunicationIdentityClient(connectionString);
```

### Using a `TokenCredential`
### Using Azure Active Directory Authentication

```typescript
import { CommunicationIdentityClient } from "@azure/communication-administration";
import { DefaultAzureCredential } from "@azure/identity";

let credential = new DefaultAzureCredential();
const credential = new DefaultAzureCredential();
const client = new CommunicationIdentityClient(HOST, credential);
```

@@ -134,9 +135,19 @@ await client.deleteUser(user);
#### Creating an instance of PhoneNumberAdministrationClient

```typescript
import { CommunicationIdentityClient } from "@azure/communication-administration";
import { PhoneNumberAdministrationClient } from "@azure/communication-administration";

const client = new CommunicationIdentityClient(CONNECTION_STRING);
const client = new PhoneNumberAdministrationClient(CONNECTION_STRING);
```

#### Creating an instance of PhoneNumberAdministrationClient with Azure Active Directory Authentication

```typescript
import { PhoneNumberAdministrationClient } from "@azure/communication-administration";
import { DefaultAzureCredential } from "@azure/identity";

const credential = new DefaultAzureCredential();
const client = new PhoneNumberAdministrationClient(HOST, credential);
```

#### Getting countries
4 changes: 2 additions & 2 deletions sdk/communication/communication-administration/karma.conf.js
Original file line number Diff line number Diff line change
@@ -60,10 +60,10 @@ module.exports = function(config) {
"TEST_MODE",
"COMMUNICATION_CONNECTION_STRING",
"INCLUDE_PHONENUMBER_TESTS",
"COMMUNICATION_ENDPOINT",
"AZURE_CLIENT_ID",
"AZURE_CLIENT_SECRET",
"AZURE_TENANT_ID"
"AZURE_TENANT_ID",
"AZURE_PHONE_NUMBER"
],

// test results reporter to use

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -289,6 +289,7 @@ export interface PageableOptions extends OperationOptions {
export class PhoneNumberAdministrationClient {
constructor(connectionString: string, options?: PhoneNumberAdministrationClientOptions);
constructor(url: string, credential: KeyCredential, options?: PhoneNumberAdministrationClientOptions);
constructor(url: string, credential: TokenCredential, options?: PhoneNumberAdministrationClientOptions);
beginPurchaseReservation(reservationId: string, options?: BeginPurchaseReservationOptions): Promise<PollerLike<PollOperationState<void>, void>>;
beginReleasePhoneNumbers(phoneNumbers: string[], options?: BeginReleasePhoneNumbersOptions): Promise<PollerLike<PollOperationState<PhoneNumberRelease>, PhoneNumberRelease>>;
beginReservePhoneNumbers(reservationRequest: CreateReservationRequest, options?: BeginReservePhoneNumbersOptions): Promise<PollerLike<PollOperationState<PhoneNumberReservation>, PhoneNumberReservation>>;
Original file line number Diff line number Diff line change
@@ -3,11 +3,11 @@
/// <reference lib="esnext.asynciterable" />

import {
createCommunicationAccessKeyCredentialPolicy,
parseClientArguments,
isKeyCredential
isKeyCredential,
createCommunicationAuthPolicy
} from "@azure/communication-common";
import { KeyCredential } from "@azure/core-auth";
import { KeyCredential, TokenCredential } from "@azure/core-auth";
import {
PipelineOptions,
InternalPipelineOptions,
@@ -116,9 +116,21 @@ export class PhoneNumberAdministrationClient {
options?: PhoneNumberAdministrationClientOptions
);

/**
* Initializes a new instance of the PhoneNumberAdministrationClient class using a TokenCredential.
* @param url The endpoint of the service (ex: https://contoso.eastus.communications.azure.net).
* @param credential TokenCredential that is used to authenticate requests to the service.
* @param options Optional. Options to configure the HTTP pipeline.
*/
public constructor(
url: string,
credential: TokenCredential,
options?: PhoneNumberAdministrationClientOptions
);

public constructor(
connectionStringOrUrl: string,
credentialOrOptions?: KeyCredential | PhoneNumberAdministrationClientOptions,
credentialOrOptions?: KeyCredential | TokenCredential | PhoneNumberAdministrationClientOptions,
maybeOptions: PhoneNumberAdministrationClientOptions = {}
) {
const { url, credential } = parseClientArguments(connectionStringOrUrl, credentialOrOptions);
@@ -146,7 +158,7 @@ export class PhoneNumberAdministrationClient {
}
};

const authPolicy = createCommunicationAccessKeyCredentialPolicy(credential as KeyCredential);
const authPolicy = createCommunicationAuthPolicy(credential);
const pipeline = createPipelineFromOptions(internalPipelineOptions, authPolicy);
this.client = new PhoneNumberRestClient(url, pipeline).phoneNumberAdministration;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import { isPlaybackMode, Recorder } from "@azure/test-utils-recorder";
import { assert } from "chai";
import { PhoneNumberAdministrationClient } from "../src";
import { createRecordedPhoneNumberAdministrationClientWithToken } from "./utils/recordedClient";

describe("PhoneNumberAdministrationClientWithToken [Playback/Live]", function() {
let recorder: Recorder;
let client: PhoneNumberAdministrationClient;
let includePhoneNumberLiveTests: boolean;
let phonePlanGroupId: string;
let shouldSkip = false;
const countryCode = "US";

beforeEach(function() {
const recordedClient = createRecordedPhoneNumberAdministrationClientWithToken(this);
if (!recordedClient) {
shouldSkip = true;
} else {
client = recordedClient.client;
recorder = recordedClient.recorder;
includePhoneNumberLiveTests = recordedClient.includePhoneNumberLiveTests;
}
});

afterEach(async function() {
if (!this.currentTest?.isPending()) {
await recorder.stop();
}
});

it("successfully gets phonePlanGroupId", async function() {
if ((!includePhoneNumberLiveTests && !isPlaybackMode()) || shouldSkip) {
this.skip();
}

for await (const phonePlanGroup of client.listPhonePlanGroups(countryCode)) {
assert.isString(phonePlanGroup.phonePlanGroupId);
({ phonePlanGroupId } = phonePlanGroup);
assert.isString(phonePlanGroupId);
break;
}
}).timeout(5000);
});
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@ import {
import { isNode, TokenCredential } from "@azure/core-http";
import { CommunicationIdentityClient, PhoneNumberAdministrationClient } from "../../src";
import { DefaultAzureCredential } from "@azure/identity";
import { parseConnectionString } from "@azure/communication-common";

if (isNode) {
dotenv.config();
@@ -27,7 +28,6 @@ export interface RecordedClient<T> {
const replaceableVariables: { [k: string]: string } = {
COMMUNICATION_CONNECTION_STRING: "endpoint=https://endpoint/;accesskey=banana",
INCLUDE_PHONENUMBER_LIVE_TESTS: "false",
COMMUNICATION_ENDPOINT: "https://endpoint/",
AZURE_CLIENT_ID: "SomeClientId",
AZURE_CLIENT_SECRET: "SomeClientSecret",
AZURE_TENANT_ID: "SomeTenantId"
@@ -81,7 +81,7 @@ export function createRecordedCommunicationIdentityClientWithToken(
): RecordedClient<CommunicationIdentityClient> | undefined {
const recorder = record(context, environmentSetup);
let credential: TokenCredential;

const endpoint = parseConnectionString(env.COMMUNICATION_CONNECTION_STRING).endpoint;
if (isPlaybackMode()) {
credential = {
getToken: async (_scopes) => {
@@ -90,7 +90,7 @@ export function createRecordedCommunicationIdentityClientWithToken(
};

return {
client: new CommunicationIdentityClient(env.COMMUNICATION_ENDPOINT, credential),
client: new CommunicationIdentityClient(endpoint, credential),
recorder
};
}
@@ -102,7 +102,7 @@ export function createRecordedCommunicationIdentityClientWithToken(
}

return {
client: new CommunicationIdentityClient(env.COMMUNICATION_ENDPOINT, credential),
client: new CommunicationIdentityClient(endpoint, credential),
recorder
};
}
@@ -121,6 +121,44 @@ export function createRecordedPhoneNumberAdministrationClient(
};
}

export function createRecordedPhoneNumberAdministrationClientWithToken(
context: Context
):
| (RecordedClient<PhoneNumberAdministrationClient> & {
includePhoneNumberLiveTests: boolean;
})
| undefined {
const recorder = record(context, environmentSetup);
let credential: TokenCredential;
const endpoint = parseConnectionString(env.COMMUNICATION_CONNECTION_STRING).endpoint;

if (isPlaybackMode()) {
credential = {
getToken: async (_scopes) => {
return { token: "testToken", expiresOnTimestamp: 11111 };
}
};

return {
client: new PhoneNumberAdministrationClient(endpoint, credential),
recorder,
includePhoneNumberLiveTests: env.INCLUDE_PHONENUMBER_LIVE_TESTS == "true"
};
}

try {
credential = new DefaultAzureCredential();
} catch {
return undefined;
}

return {
client: new PhoneNumberAdministrationClient(endpoint, credential),
recorder,
includePhoneNumberLiveTests: env.INCLUDE_PHONENUMBER_LIVE_TESTS == "true"
};
}

export const testPollerOptions = {
pollInterval: isPlaybackMode() ? 0 : undefined
};
4 changes: 4 additions & 0 deletions sdk/communication/communication-administration/tests.yml
Original file line number Diff line number Diff line change
@@ -5,3 +5,7 @@ extends:
parameters:
PackageName: "@azure/communication-administration"
ResourceServiceDirectory: communication
EnvVars:
AZURE_CLIENT_ID: $(aad-azure-sdk-test-client-id)
AZURE_CLIENT_SECRET: $(aad-azure-sdk-test-client-secret)
AZURE_TENANT_ID: $(aad-azure-sdk-test-tenant-id)

0 comments on commit 7f89cb1

Please sign in to comment.