diff --git a/sdk/communication/Azure.Communication.Administration/README.md b/sdk/communication/Azure.Communication.Administration/README.md index be5b807522238..e4ef12948549d 100644 --- a/sdk/communication/Azure.Communication.Administration/README.md +++ b/sdk/communication/Azure.Communication.Administration/README.md @@ -1,7 +1,7 @@ # Azure Communication Administration client library for .NET > Server Version: -Identity client: 2020-07-20-preview2 +> Identity client: 2020-07-20-preview2 > Phone number administration client: 2020-07-20-preview1 @@ -12,6 +12,7 @@ Azure Communication Administration is managing tokens and phone numbers for Azur ## Getting started ### Install the package + Install the Azure Communication Administration client library for .NET with [NuGet][nuget]: ```Powershell @@ -19,6 +20,7 @@ dotnet add package Azure.Communication.Administration --version 1.0.0-beta.3 ``` ### Prerequisites + You need an [Azure subscription][azure_sub] and a [Communication Service Resource][communication_resource_docs] to use this package. To create a new Communication Service, you can use the [Azure Portal][communication_resource_create_portal] or the [.NET management client library][communication_resource_create_net]. @@ -41,12 +43,22 @@ var connectionString = ""; var client = new CommunicationIdentityClient(connectionString); ``` +Clients also have the option to authenticate using a valid token. + +```C# Snippet:CreateCommunicationIdentityFromToken +var endpoint = ""; +TokenCredential tokenCredential = new DefaultAzureCredential(); +var client = new CommunicationIdentityClient(new Uri(endpoint), tokenCredential); +``` + ### Key concepts + `CommunicationIdentityClient` provides the functionalities to manage user access tokens: creating new ones, renewing and revoking them. ## Examples ### Create a new identity + ```C# Snippet:CreateCommunicationUserAsync Response userResponse = await client.CreateUserAsync(); CommunicationUserIdentifier user = userResponse.Value; @@ -54,6 +66,7 @@ Console.WriteLine($"User id: {user.Id}"); ``` ### Issuing or Refreshing a token for an existing identity + ```C# Snippet:CreateCommunicationTokenAsync Response tokenResponse = await client.IssueTokenAsync(user, scopes: new[] { CommunicationTokenScope.Chat }); string token = tokenResponse.Value.Token; @@ -63,7 +76,9 @@ Console.WriteLine($"Expires On: {expiresOn}"); ``` ### Revoking a user's tokens + In case a user's tokens are compromised or need to be revoked: + ```C# Snippet:RevokeCommunicationUserToken Response revokeResponse = client.RevokeTokens( user, @@ -71,11 +86,13 @@ Response revokeResponse = client.RevokeTokens( ``` ### Deleting a user + ```C# Snippet:DeleteACommunicationUser Response deleteResponse = client.DeleteUser(user); ``` ## Troubleshooting + All User token service operations will throw a RequestFailedException on failure. ```C# Snippet:CommunicationIdentityClient_Troubleshooting @@ -93,8 +110,6 @@ catch (RequestFailedException ex) } ``` - - ### 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. @@ -174,7 +189,6 @@ foreach(var locationOption in locationOprions.Options) Fetching area codes for geographic phone plans will require the the location options queries set. You must include the chain of geographic locations traversing down the location options object returned by the GetLocationOptions API. - ```C# var areaCodesResponse = client.GetAllAreaCodes(locationType, countryCode, planId, locationOptionsQueries); var areaCodes = areaCodesResponse.Value; @@ -225,14 +239,17 @@ Console.WriteLine($"ReleaseId: {releasePhoneNumberOperation.Value.ReleaseId}, St ``` ## Next steps + [Read more about Communication user access tokens][user_access_token] ## Contributing + This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit [cla.microsoft.com][cla]. This project has adopted the [Microsoft Open Source Code of Conduct][coc]. For more information see the [Code of Conduct FAQ][coc_faq] or contact [opencode@microsoft.com][coc_contact] with any additional questions or comments. + [azure_sub]: https://azure.microsoft.com/free/ [azure_portal]: https://portal.azure.com [source]: https://github.com/Azure/azure-sdk-for-net/tree/master/sdk/communication/Azure.Communication.Administration/src @@ -246,5 +263,5 @@ This project has adopted the [Microsoft Open Source Code of Conduct][coc]. For m [nuget]: https://www.nuget.org/ [user_access_token]: https://docs.microsoft.com/azure/communication-services/quickstarts/access-tokens?pivots=programming-language-csharp [communication_resource_docs]: https://docs.microsoft.com/azure/communication-services/quickstarts/create-communication-resource?tabs=windows&pivots=platform-azp -[communication_resource_create_portal]: https://docs.microsoft.com/azure/communication-services/quickstarts/create-communication-resource?tabs=windows&pivots=platform-azp +[communication_resource_create_portal]: https://docs.microsoft.com/azure/communication-services/quickstarts/create-communication-resource?tabs=windows&pivots=platform-azp [communication_resource_create_net]: https://docs.microsoft.com/azure/communication-services/quickstarts/create-communication-resource?tabs=windows&pivots=platform-net diff --git a/sdk/communication/Azure.Communication.Administration/samples/Sample1_CommunicationIdentityClient.md b/sdk/communication/Azure.Communication.Administration/samples/Sample1_CommunicationIdentityClient.md index 2950ebd70efeb..fcdec6fd82235 100644 --- a/sdk/communication/Azure.Communication.Administration/samples/Sample1_CommunicationIdentityClient.md +++ b/sdk/communication/Azure.Communication.Administration/samples/Sample1_CommunicationIdentityClient.md @@ -1,12 +1,14 @@ # Obtain user tokens from Azure Communication Services -This sample demonstrates how to obtain user tokens from Azure Communication Services. You can use this token to authenticate your users to use Azure Communication Services offerings. + +This sample demonstrates how to obtain user tokens from Azure Communication Services. You can use this token to authenticate your users to use Azure Communication Services offerings. To get started you'll need an Azure Communication Services resource. See the README for prerequisites and instructions. + ## Create a `CommunicationIdentityClient` -To create a new `CommunicationIdentityClient` you need a connection string to the Azure Communication Services resource that you can get from the Azure Portal once you have created the resource. +To create a new `CommunicationIdentityClient` you need a connection string to the Azure Communication Services resource that you can get from the Azure Portal once you have created the resource. You can set `connectionString` based on an environment variable, a configuration setting, or any way that works for your application. @@ -16,7 +18,16 @@ var connectionString = ""; var client = new CommunicationIdentityClient(connectionString); ``` +Clients also have the option to authenticate using a valid token. + +```C# Snippet:CreateCommunicationIdentityFromToken +var endpoint = ""; +TokenCredential tokenCredential = new DefaultAzureCredential(); +var client = new CommunicationIdentityClient(new Uri(endpoint), tokenCredential); +``` + ## Create a user + The `CommunicationIdentityClient` can be used to create users and issue tokens. ```C# Snippet:CreateCommunicationUser @@ -34,7 +45,8 @@ You will need to store the `identity` that is returned by Azure Communication Se In the example code snippet below, it is assumed that the token is generated for a user on your application. During token generation you should also pass list of scopes to Azure Communication Services, so the token generated by Azure Communication Services is authorized only to do things determined by `scopes`. -Every token generated has an expiry date stamped on it. Once the token is expired, you can renew the token by calling the same method. +Every token generated has an expiry date stamped on it. Once the token is expired, you can renew the token by calling the same method. + ```C# Snippet:CreateCommunicationToken Response tokenResponse = client.IssueToken(user, scopes: new[] { CommunicationTokenScope.Chat }); string token = tokenResponse.Value.Token; diff --git a/sdk/communication/Azure.Communication.Administration/samples/Sample1_CommunicationIdentityClientAsync.md b/sdk/communication/Azure.Communication.Administration/samples/Sample1_CommunicationIdentityClientAsync.md index f3a5811363006..1708e243cde17 100644 --- a/sdk/communication/Azure.Communication.Administration/samples/Sample1_CommunicationIdentityClientAsync.md +++ b/sdk/communication/Azure.Communication.Administration/samples/Sample1_CommunicationIdentityClientAsync.md @@ -1,12 +1,14 @@ # Obtain user tokens from Azure Communication Services -This sample demonstrates how to obtain user tokens from Azure Communication Services. You can use this token to authenticate your users to use Azure Communication Services offerings. + +This sample demonstrates how to obtain user tokens from Azure Communication Services. You can use this token to authenticate your users to use Azure Communication Services offerings. To get started you'll need an Azure Communication Services resource. See the README for prerequisites and instructions. + ## Create a `CommunicationIdentityClient` -To create a new `CommunicationIdentityClient` you need a connection string to the Azure Communication Services resource that you can get from the Azure Portal once you have created the resource. +To create a new `CommunicationIdentityClient` you need a connection string to the Azure Communication Services resource that you can get from the Azure Portal once you have created the resource. You can set `connectionString` based on an environment variable, a configuration setting, or any way that works for your application. @@ -16,7 +18,16 @@ var connectionString = ""; var client = new CommunicationIdentityClient(connectionString); ``` +Clients also have the option to authenticate using a valid token. + +```C# Snippet:CreateCommunicationIdentityFromToken +var endpoint = ""; +TokenCredential tokenCredential = new DefaultAzureCredential(); +var client = new CommunicationIdentityClient(new Uri(endpoint), tokenCredential); +``` + ## Create a user + The `CommunicationIdentityClient` can be used to create users and issue tokens. ```C# Snippet:CreateCommunicationUserAsync @@ -33,9 +44,11 @@ You will need to store the `identity` that is returned by Azure Communication Se In the example code snippet below, it is assumed that the token is generated for a user on your application. During token generation you should also pass list of scopes to Azure Communication Services, so the token generated by Azure Communication Services is authorized only to do things determined by `scopes`. + -Every token generated has an expiry date stamped on it. Once the token is expired, you can renew the token by calling the same method. +Every token generated has an expiry date stamped on it. Once the token is expired, you can renew the token by calling the same method. + ```C# Snippet:CreateCommunicationTokenAsync Response tokenResponse = await client.IssueTokenAsync(user, scopes: new[] { CommunicationTokenScope.Chat }); string token = tokenResponse.Value.Token; diff --git a/sdk/communication/Azure.Communication.Administration/tests/SessionRecords/Sample1_CommunicationIdentityClient/CreateIdentityWithToken.json b/sdk/communication/Azure.Communication.Administration/tests/SessionRecords/Sample1_CommunicationIdentityClient/CreateIdentityWithToken.json new file mode 100644 index 0000000000000..b43241158861f --- /dev/null +++ b/sdk/communication/Azure.Communication.Administration/tests/SessionRecords/Sample1_CommunicationIdentityClient/CreateIdentityWithToken.json @@ -0,0 +1,39 @@ +{ + "Entries": [ + { + "RequestUri": "https://sanitized.communication.azure.com/identities?api-version=2020-07-20-preview2", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Authorization": "Sanitized", + "traceparent": "00-a6604788dfbca142a2f1351afbc7388e-1a4460b95b492a47-00", + "User-Agent": [ + "azsdk-net-Communication.Administration/1.0.0-alpha.20210106.1", + "(.NET Core 4.6.29220.03; Darwin 20.2.0 Darwin Kernel Version 20.2.0: Wed Dec 2 20:39:59 PST 2020; root:xnu-7195.60.75~1/RELEASE_X86_64)" + ], + "x-ms-client-request-id": "7e2741c9fe4173a6a40d9373496525d3", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": null, + "StatusCode": 200, + "ResponseHeaders": { + "api-supported-versions": "2020-01-15-preview3, 2020-07-20-preview1, 2020-07-20-preview2", + "Content-Type": "application/json; charset=utf-8", + "Date": "Thu, 07 Jan 2021 00:14:39 GMT", + "MS-CV": "zQ6iIgjHsUG2sgFDU9ZReA.0", + "Strict-Transport-Security": "max-age=2592000", + "Transfer-Encoding": "chunked", + "X-Azure-Ref": "0b1L2XwAAAABtsR\u002BI85qRSIZz4njbBLrFRVdSMzBFREdFMDYxNQA5ZmM3YjUxOS1hOGNjLTRmODktOTM1ZS1jOTE0OGFlMDllODE=", + "x-ms-client-request-id": "7e2741c9fe4173a6a40d9373496525d3", + "X-Processing-Time": "343ms" + }, + "ResponseBody": { + "id": "Sanitized" + } + } + ], + "Variables": { + "COMMUNICATION_ENDPOINT_STRING": "https://prototype-communication.communication.azure.com", + "RandomSeed": "1690082112" + } +} \ No newline at end of file diff --git a/sdk/communication/Azure.Communication.Administration/tests/SessionRecords/Sample1_CommunicationIdentityClient/CreateIdentityWithTokenAsync.json b/sdk/communication/Azure.Communication.Administration/tests/SessionRecords/Sample1_CommunicationIdentityClient/CreateIdentityWithTokenAsync.json new file mode 100644 index 0000000000000..ef305d06e13c1 --- /dev/null +++ b/sdk/communication/Azure.Communication.Administration/tests/SessionRecords/Sample1_CommunicationIdentityClient/CreateIdentityWithTokenAsync.json @@ -0,0 +1,39 @@ +{ + "Entries": [ + { + "RequestUri": "https://sanitized.communication.azure.com/identities?api-version=2020-07-20-preview2", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Authorization": "Sanitized", + "traceparent": "00-dd8701dfa904cc48b290b51e6066ad77-05f06f401fbf9843-00", + "User-Agent": [ + "azsdk-net-Communication.Administration/1.0.0-alpha.20210106.1", + "(.NET Core 4.6.29220.03; Darwin 20.2.0 Darwin Kernel Version 20.2.0: Wed Dec 2 20:39:59 PST 2020; root:xnu-7195.60.75~1/RELEASE_X86_64)" + ], + "x-ms-client-request-id": "47ecec28b80d8c30cfb17bfa94a3b08b", + "x-ms-return-client-request-id": "true" + }, + "RequestBody": null, + "StatusCode": 200, + "ResponseHeaders": { + "api-supported-versions": "2020-01-15-preview3, 2020-07-20-preview1, 2020-07-20-preview2", + "Content-Type": "application/json; charset=utf-8", + "Date": "Thu, 07 Jan 2021 00:14:43 GMT", + "MS-CV": "9SJLR/Wk/kO\u002BhnjvwZx86A.0", + "Strict-Transport-Security": "max-age=2592000", + "Transfer-Encoding": "chunked", + "X-Azure-Ref": "0c1L2XwAAAACbijPOL7N/R6AjbJPpM\u002BXSRVdSMzBFREdFMDYxNQA5ZmM3YjUxOS1hOGNjLTRmODktOTM1ZS1jOTE0OGFlMDllODE=", + "x-ms-client-request-id": "47ecec28b80d8c30cfb17bfa94a3b08b", + "X-Processing-Time": "213ms" + }, + "ResponseBody": { + "id": "Sanitized" + } + } + ], + "Variables": { + "COMMUNICATION_ENDPOINT_STRING": "https://prototype-communication.communication.azure.com", + "RandomSeed": "1697946323" + } +} \ No newline at end of file diff --git a/sdk/communication/Azure.Communication.Administration/tests/samples/Sample1_CommunicationIdentityClient.cs b/sdk/communication/Azure.Communication.Administration/tests/samples/Sample1_CommunicationIdentityClient.cs index b2199a01ecc8c..e5e74236d4755 100644 --- a/sdk/communication/Azure.Communication.Administration/tests/samples/Sample1_CommunicationIdentityClient.cs +++ b/sdk/communication/Azure.Communication.Administration/tests/samples/Sample1_CommunicationIdentityClient.cs @@ -5,7 +5,9 @@ using System.Threading.Tasks; using Azure.Communication.Administration.Models; using Azure.Communication.Administration.Tests; +using Azure.Core; using Azure.Core.TestFramework; +using Azure.Identity; using NUnit.Framework; #pragma warning disable IDE0059 // Unnecessary assignment of a value @@ -17,7 +19,7 @@ namespace Azure.Communication.Administration.Samples /// public partial class Sample1_CommunicationIdentityClient : CommunicationIdentityClientLiveTestBase { - public Sample1_CommunicationIdentityClient(bool isAsync): base(isAsync) + public Sample1_CommunicationIdentityClient(bool isAsync) : base(isAsync) => Matcher.IgnoredHeaders.Add("x-ms-content-sha256"); [Test] @@ -97,6 +99,28 @@ public void UserAndTokenLifeCycle() #endregion Snippet:DeleteACommunicationUser } + [Test] + public async Task CreateIdentityWithToken() + { + var endpoint = TestEnvironment.EndpointString; + #region Snippet:CreateCommunicationIdentityFromToken + //@@var endpoint = ""; + TokenCredential tokenCredential = new DefaultAzureCredential(); + var client = new CommunicationIdentityClient(new Uri(endpoint), tokenCredential); + #endregion Snippet:CreateCommunicationIdentityFromToken + + tokenCredential = (Mode == RecordedTestMode.Playback) ? new MockCredential() : new DefaultAzureCredential(); + client = CreateInstrumentedCommunicationIdentityClientWithToken(tokenCredential); + try + { + Response userResponse = await client.CreateUserAsync(); + } + catch (Exception ex) + { + Assert.Fail($"Unexpected error: {ex}"); + } + } + [Test] public async Task Troubleshooting() {