diff --git a/sdk/communication/Azure.Communication.Common/tests/CommunicationRecordedTestSanitizer.cs b/sdk/communication/Azure.Communication.Common/tests/CommunicationRecordedTestSanitizer.cs index 7e2af51b54a9..ce198fde6bfe 100644 --- a/sdk/communication/Azure.Communication.Common/tests/CommunicationRecordedTestSanitizer.cs +++ b/sdk/communication/Azure.Communication.Common/tests/CommunicationRecordedTestSanitizer.cs @@ -12,6 +12,7 @@ public class CommunicationRecordedTestSanitizer : RecordedTestSanitizer { private static readonly Regex _azureResourceRegEx = new Regex(@"[^/]+?(?=(.communication.azure))", RegexOptions.Compiled); private static readonly Regex _identityInRouteRegEx = new Regex(@"(?<=identities/)([^/]+)", RegexOptions.Compiled); + private static readonly Regex _turnInRouteRegEx = new Regex(@"(?<=turn/)([^/]+)", RegexOptions.Compiled); private static readonly Regex _phoneNumberRegEx = new Regex(@"[\\+]?[0-9]{11,15}", RegexOptions.Compiled); private static readonly Regex _guidRegEx = new Regex(@"(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}", RegexOptions.Compiled); @@ -28,6 +29,9 @@ public CommunicationRecordedTestSanitizer() : base() JsonPathSanitizers.Add("$..phonePlanId"); JsonPathSanitizers.Add("$..phonePlanGroupId"); JsonPathSanitizers.Add("$..phonePlanIds[:]"); + JsonPathSanitizers.Add("$..urls"); + JsonPathSanitizers.Add("$..username"); + JsonPathSanitizers.Add("$..credential"); } public override void SanitizeHeaders(IDictionary headers) @@ -76,6 +80,7 @@ internal static string SanitizeConnectionString(string connectionString) public override string SanitizeUri(string uri) { uri = SanitizeAzureResource(_identityInRouteRegEx.Replace(uri, SanitizeValue.ToLower())); + uri = SanitizeAzureResource(_turnInRouteRegEx.Replace(uri, SanitizeValue.ToLower())); return _guidRegEx.Replace(uri, SanitizeValue); } } diff --git a/sdk/communication/Azure.Communication.Identity/api/Azure.Communication.Identity.netstandard2.0.cs b/sdk/communication/Azure.Communication.Identity/api/Azure.Communication.Identity.netstandard2.0.cs index 5b93834db90a..f1141d3c659e 100644 --- a/sdk/communication/Azure.Communication.Identity/api/Azure.Communication.Identity.netstandard2.0.cs +++ b/sdk/communication/Azure.Communication.Identity/api/Azure.Communication.Identity.netstandard2.0.cs @@ -15,6 +15,8 @@ public CommunicationIdentityClient(System.Uri endpoint, Azure.Core.TokenCredenti public virtual System.Threading.Tasks.Task DeleteUserAsync(Azure.Communication.CommunicationUserIdentifier communicationUser, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public virtual Azure.Response IssueToken(Azure.Communication.CommunicationUserIdentifier communicationUser, System.Collections.Generic.IEnumerable scopes, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public virtual System.Threading.Tasks.Task> IssueTokenAsync(Azure.Communication.CommunicationUserIdentifier communicationUser, System.Collections.Generic.IEnumerable scopes, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public virtual Azure.Response IssueTurnCredentials(Azure.Communication.CommunicationUserIdentifier communicationUser, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public virtual System.Threading.Tasks.Task> IssueTurnCredentialsAsync(Azure.Communication.CommunicationUserIdentifier communicationUser, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public virtual Azure.Response RevokeTokens(Azure.Communication.CommunicationUserIdentifier communicationUser, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public virtual System.Threading.Tasks.Task RevokeTokensAsync(Azure.Communication.CommunicationUserIdentifier communicationUser, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } } @@ -45,3 +47,19 @@ public enum ServiceVersion public override string ToString() { throw null; } } } +namespace Azure.Communication.Identity.Models +{ + public partial class CommunicationTurnCredentialsResponse + { + internal CommunicationTurnCredentialsResponse() { } + public System.DateTimeOffset ExpiresOn { get { throw null; } } + public System.Collections.Generic.IReadOnlyList TurnServers { get { throw null; } } + } + public partial class CommunicationTurnServer + { + internal CommunicationTurnServer() { } + public string Credential { get { throw null; } } + public string Urls { get { throw null; } } + public string Username { get { throw null; } } + } +} diff --git a/sdk/communication/Azure.Communication.Identity/samples/README.md b/sdk/communication/Azure.Communication.Identity/samples/README.md index 74f6f18f5faa..e5d14c9a3ecf 100644 --- a/sdk/communication/Azure.Communication.Identity/samples/README.md +++ b/sdk/communication/Azure.Communication.Identity/samples/README.md @@ -16,12 +16,11 @@ To get started you will need to have an Azure Subscription. Once you have this y This client library allows to do following operations: - Generate user tokens that allows the holders to access Azure Communication Services. - - Purchase, configure and release phone numbers. + - Generate TURN server credentials that allows the holders to get access to a TURN server for media relay. #### You can find samples for each of these functions below. - - Generate user tokens [synchronously][sample_identity] or [asynchronously][sample_identity_async] + - Generate user tokens and TURN credentials [synchronously][sample_identity] or [asynchronously][sample_identity_async] [sample_identity]: https://github.com/Azure/azure-sdk-for-net/tree/master/sdk/communication/Azure.Communication.Identity/samples/Sample1_CommunicationIdentityClient.md [sample_identity_async]: https://github.com/Azure/azure-sdk-for-net/tree/master/sdk/communication/Azure.Communication.Identity/samples/Sample1_CommunicationIdentityClientAsync.md -[ diff --git a/sdk/communication/Azure.Communication.Identity/samples/Sample1_CommunicationIdentityClient.md b/sdk/communication/Azure.Communication.Identity/samples/Sample1_CommunicationIdentityClient.md index bcec26c194a9..3b92a4f8971e 100644 --- a/sdk/communication/Azure.Communication.Identity/samples/Sample1_CommunicationIdentityClient.md +++ b/sdk/communication/Azure.Communication.Identity/samples/Sample1_CommunicationIdentityClient.md @@ -55,6 +55,26 @@ Console.WriteLine($"Token: {token}"); Console.WriteLine($"Expires On: {expiresOn}"); ``` +## Generate TURN credentials + +The example code snippet below shows how to generate TURN credentials for an Azure Communication user that was created following the steps above. +A set of TURN credentials are returned for the user. Each TURN credential consists of a url for a TURN server, its corresponding username and a credential. + +Every set of TURN credentials is stamped with an expiry date. Once the credentials are expired, you can renew the token by calling the same method. + +```C# Snippet:CreateTURNTokenAsync +Response turnTokenResponse = await client.IssueTurnCredentialsAsync(user); +DateTimeOffset turnTokenExpiresOn = turnTokenResponse.Value.ExpiresOn; +IReadOnlyList turnServers = turnTokenResponse.Value.TurnServers; +Console.WriteLine($"Expires On: {turnTokenExpiresOn}"); +foreach (CommunicationTurnServer turnServer in turnServers) +{ + Console.WriteLine($"TURN Url: {turnServer.Urls}"); + Console.WriteLine($"TURN Username: {turnServer.Username}"); + Console.WriteLine($"TURN Credential: {turnServer.Credential}"); +} +``` +