Skip to content

Commit 25b5b37

Browse files
DominikMecemateia
andauthored
Add new TeamsExtensionUserIdentifier and new computed properties for PhoneNumberIdentifier (Azure#48625)
* add new TeamsExtensionUserIdentifier and new computed properties for PhoneNumberIdentifier * Fix comments from review * fix comment * revert change * reuse assertedId in PhoneNumberIdentifier * update test description --------- Co-authored-by: Cezara Mateiasi <[email protected]>
1 parent f3401ac commit 25b5b37

10 files changed

+333
-10
lines changed

sdk/communication/Azure.Communication.Common/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
### Features Added
66
- Introduced support for `Azure.Core.TokenCredential` with `EntraCommunicationTokenCredentialOptions`, enabling Entra users to authorize Communication Services and allowing an Entra user with a Teams license to use Teams Phone Extensibility features through the Azure Communication Services resource.
7+
- Added support for a new communication identifier `TeamsExtensionUserIdentifier` which maps rawIds with format `8:acs:{resourceId}_{tenantId}_{userId}`.
8+
- Added `IsAnonymous` and `AssertedId` properties to `PhoneNumberIdentifier`.
79

810
### Breaking Changes
911

sdk/communication/Azure.Communication.Common/api/Azure.Communication.Common.net8.0.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,24 @@ public partial class MicrosoftTeamsUserIdentifier : Azure.Communication.Communic
8383
public partial class PhoneNumberIdentifier : Azure.Communication.CommunicationIdentifier
8484
{
8585
public PhoneNumberIdentifier(string phoneNumber, string rawId = null) { }
86+
public string AssertedId { get { throw null; } }
87+
public bool IsAnonymous { get { throw null; } }
8688
public string PhoneNumber { get { throw null; } }
8789
public override string RawId { get { throw null; } }
8890
public override bool Equals(Azure.Communication.CommunicationIdentifier other) { throw null; }
8991
public override string ToString() { throw null; }
9092
}
93+
public partial class TeamsExtensionUserIdentifier : Azure.Communication.CommunicationIdentifier
94+
{
95+
public TeamsExtensionUserIdentifier(string userId, string tenantId, string resourceId, Azure.Communication.CommunicationCloudEnvironment? cloud = default(Azure.Communication.CommunicationCloudEnvironment?), string rawId = null) { }
96+
public Azure.Communication.CommunicationCloudEnvironment Cloud { get { throw null; } }
97+
public override string RawId { get { throw null; } }
98+
public string ResourceId { get { throw null; } }
99+
public string TenantId { get { throw null; } }
100+
public string UserId { get { throw null; } }
101+
public override bool Equals(Azure.Communication.CommunicationIdentifier other) { throw null; }
102+
public override string ToString() { throw null; }
103+
}
91104
public partial class UnknownIdentifier : Azure.Communication.CommunicationIdentifier
92105
{
93106
public UnknownIdentifier(string id) { }

sdk/communication/Azure.Communication.Common/api/Azure.Communication.Common.netstandard2.0.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,24 @@ public partial class MicrosoftTeamsUserIdentifier : Azure.Communication.Communic
8383
public partial class PhoneNumberIdentifier : Azure.Communication.CommunicationIdentifier
8484
{
8585
public PhoneNumberIdentifier(string phoneNumber, string rawId = null) { }
86+
public string AssertedId { get { throw null; } }
87+
public bool IsAnonymous { get { throw null; } }
8688
public string PhoneNumber { get { throw null; } }
8789
public override string RawId { get { throw null; } }
8890
public override bool Equals(Azure.Communication.CommunicationIdentifier other) { throw null; }
8991
public override string ToString() { throw null; }
9092
}
93+
public partial class TeamsExtensionUserIdentifier : Azure.Communication.CommunicationIdentifier
94+
{
95+
public TeamsExtensionUserIdentifier(string userId, string tenantId, string resourceId, Azure.Communication.CommunicationCloudEnvironment? cloud = default(Azure.Communication.CommunicationCloudEnvironment?), string rawId = null) { }
96+
public Azure.Communication.CommunicationCloudEnvironment Cloud { get { throw null; } }
97+
public override string RawId { get { throw null; } }
98+
public string ResourceId { get { throw null; } }
99+
public string TenantId { get { throw null; } }
100+
public string UserId { get { throw null; } }
101+
public override bool Equals(Azure.Communication.CommunicationIdentifier other) { throw null; }
102+
public override string ToString() { throw null; }
103+
}
91104
public partial class UnknownIdentifier : Azure.Communication.CommunicationIdentifier
92105
{
93106
public UnknownIdentifier(string id) { }

sdk/communication/Azure.Communication.Common/src/CommunicationIdentifier.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,33 @@ public static CommunicationIdentifier FromRawId(string rawId)
8787
TeamUserPublicCloud => new MicrosoftTeamsUserIdentifier(suffix, false, CommunicationCloudEnvironment.Public),
8888
TeamUserDodCloud => new MicrosoftTeamsUserIdentifier(suffix, false, CommunicationCloudEnvironment.Dod),
8989
TeamUserGcchCloud => new MicrosoftTeamsUserIdentifier(suffix, false, CommunicationCloudEnvironment.Gcch),
90-
AcsUser or SpoolUser or AcsUserDodCloud or AcsUserGcchCloud => new CommunicationUserIdentifier(rawId),
90+
SpoolUser => new CommunicationUserIdentifier(rawId),
91+
AcsUser or AcsUserDodCloud or AcsUserGcchCloud => (CommunicationIdentifier)TryCreateTeamsExtensionUser(prefix, suffix) ?? new CommunicationUserIdentifier(rawId),
9192
TeamsAppPublicCloud => new MicrosoftTeamsAppIdentifier(suffix, CommunicationCloudEnvironment.Public),
9293
TeamsAppGcchCloud => new MicrosoftTeamsAppIdentifier(suffix, CommunicationCloudEnvironment.Gcch),
9394
TeamsAppDodCloud => new MicrosoftTeamsAppIdentifier(suffix, CommunicationCloudEnvironment.Dod),
9495
_ => new UnknownIdentifier(rawId),
9596
};
9697
}
98+
99+
private static TeamsExtensionUserIdentifier TryCreateTeamsExtensionUser(string prefix, string suffix)
100+
{
101+
var segments = suffix.Split('_');
102+
if (segments.Length != 3)
103+
{
104+
return null;
105+
}
106+
var resourceId = segments[0];
107+
var tenantId = segments[1];
108+
var userId = segments[2];
109+
var cloud = prefix switch
110+
{
111+
AcsUser => CommunicationCloudEnvironment.Public,
112+
AcsUserDodCloud => CommunicationCloudEnvironment.Dod,
113+
AcsUserGcchCloud => CommunicationCloudEnvironment.Gcch,
114+
_ => throw new ArgumentException($"Invalid prefix {prefix} for TeamsExtensionUserIdentifier")
115+
};
116+
return new TeamsExtensionUserIdentifier(userId, tenantId, resourceId, cloud);
117+
}
97118
}
98119
}

sdk/communication/Azure.Communication.Common/src/MicrosoftTeamsUserIdentifier.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public override string RawId
4141
}
4242
}
4343

44-
/// <summary>The id of the Microsoft Teams user. If the user isn't anonymous, the id is the Azure AD object id of the user.</summary>
44+
/// <summary>The id of the Microsoft Teams user. If the user isn't anonymous, the id is the Entra ID object id of the user.</summary>
4545
public string UserId { get; }
4646

4747
/// <summary>True if the user is anonymous, for example when joining a meeting with a share link.</summary>
@@ -53,7 +53,7 @@ public override string RawId
5353
/// <summary>
5454
/// Initializes a new instance of <see cref="MicrosoftTeamsUserIdentifier"/>.
5555
/// </summary>
56-
/// <param name="userId">Id of the Microsoft Teams user. If the user isn't anonymous, the id is the Azure AD object id of the user.</param>
56+
/// <param name="userId">Id of the Microsoft Teams user. If the user isn't anonymous, the id is the Entra ID object id of the user.</param>
5757
/// <param name="isAnonymous">Set this to true if the user is anonymous, for example when joining a meeting with a share link.</param>
5858
/// <param name="cloud">The cloud that the Microsoft Team user belongs to. A null value translates to the Public cloud.</param>
5959
/// <param name="rawId">Raw id of the Microsoft Teams user, optional.</param>

sdk/communication/Azure.Communication.Common/src/PhoneNumberIdentifier.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4+
using System.Linq;
45
using Azure.Core;
56

67
namespace Azure.Communication
@@ -9,6 +10,8 @@ namespace Azure.Communication
910
public class PhoneNumberIdentifier : CommunicationIdentifier
1011
{
1112
private string _rawId;
13+
private string _assertedId;
14+
private const string Anonymous = "anonymous";
1215

1316
/// <summary>
1417
/// Returns the canonical string representation of the <see cref="PhoneNumberIdentifier"/>.
@@ -25,6 +28,38 @@ public override string RawId
2528
/// <summary>The phone number in E.164 format.</summary>
2629
public string PhoneNumber { get; }
2730

31+
/// <summary>True if the phone number is anonymous, e.g. when used to represent a hidden caller Id.</summary>
32+
public bool IsAnonymous => RawId == $"{Phone}{Anonymous}";
33+
34+
/// <summary>The asserted Id is set on a phone number that is already in the same call to distinguish from other connections made through the same number.</summary>
35+
public string AssertedId
36+
{
37+
get
38+
{
39+
if (!string.IsNullOrEmpty(_assertedId))
40+
{
41+
return _assertedId;
42+
}
43+
44+
if (_assertedId == "")
45+
{
46+
return null;
47+
}
48+
49+
var segments = RawId.Substring(Phone.Length).Split('_');
50+
if (segments.Length > 1)
51+
{
52+
_assertedId = segments.Last();
53+
return _assertedId;
54+
}
55+
else
56+
{
57+
_assertedId = "";
58+
return null;
59+
}
60+
}
61+
}
62+
2863
/// <summary> Initializes a new instance of <see cref="PhoneNumberIdentifier"/>.</summary>
2964
/// <param name="phoneNumber">The phone number in E.164 format.</param>
3065
/// <param name="rawId">Raw id of the phone number, optional.</param>
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using Azure.Core;
5+
6+
namespace Azure.Communication
7+
{
8+
/// <summary> A Microsoft Teams Phone user who is using a Communication Services resource to extend their Teams Phone set up. </summary>
9+
public class TeamsExtensionUserIdentifier : CommunicationIdentifier
10+
{
11+
private string _rawId;
12+
13+
/// <summary>
14+
/// Returns the canonical string representation of the <see cref="TeamsExtensionUserIdentifier"/>.
15+
/// You can use the <see cref="RawId"/> for encoding the identifier and then use it as a key in a database.
16+
/// </summary>
17+
public override string RawId
18+
{
19+
get
20+
{
21+
if (_rawId == null)
22+
{
23+
if (Cloud == CommunicationCloudEnvironment.Dod)
24+
{
25+
_rawId = $"{AcsUserDodCloud}{ResourceId}_{TenantId}_{UserId}";
26+
}
27+
else if (Cloud == CommunicationCloudEnvironment.Gcch)
28+
{
29+
_rawId = $"{AcsUserGcchCloud}{ResourceId}_{TenantId}_{UserId}";
30+
}
31+
else
32+
{
33+
_rawId = $"{AcsUser}{ResourceId}_{TenantId}_{UserId}";
34+
}
35+
}
36+
return _rawId;
37+
}
38+
}
39+
40+
/// <summary> The Id of the Microsoft Teams Extension user, i.e. the Entra ID object Id of the user. </summary>
41+
public string UserId { get; }
42+
43+
/// <summary> The tenant Id of the Microsoft Teams Extension user. </summary>
44+
public string TenantId { get; }
45+
46+
/// <summary> The Communication Services resource Id. </summary>
47+
public string ResourceId { get; }
48+
49+
/// <summary> The cloud that the identifier belongs to. </summary>
50+
public CommunicationCloudEnvironment Cloud { get; }
51+
52+
/// <summary>
53+
/// Initializes a new instance of <see cref="TeamsExtensionUserIdentifier"/>.
54+
/// </summary>
55+
/// <param name="userId"> The Id of the Microsoft Teams Extension user, i.e. the Entra ID object Id of the user. </param>
56+
/// <param name="tenantId"> The tenant Id of the Microsoft Teams Extension user. </param>
57+
/// <param name="resourceId"> The Communication Services resource Id. </param>
58+
/// <param name="cloud"> The cloud that the Microsoft Teams Extension user belongs to. By default 'public' if missing. </param>
59+
/// <param name="rawId"> Raw id of the Microsoft Teams user, optional. </param>
60+
/// <exception cref="System.ArgumentNullException">
61+
/// Thrown when any of <paramref name="userId"/>, <paramref name="tenantId"/>, <paramref name="resourceId"/> are null.
62+
/// </exception>
63+
/// <exception cref="System.ArgumentException">
64+
/// Thrown when any of <paramref name="userId"/>, <paramref name="tenantId"/>, <paramref name="resourceId"/> are empty.
65+
/// </exception>
66+
/// /// <exception cref="System.FormatException">
67+
/// Thrown when any of <paramref name="userId"/>, <paramref name="tenantId"/>, <paramref name="resourceId"/> are not in valid Guid format D.
68+
/// </exception>
69+
public TeamsExtensionUserIdentifier(string userId, string tenantId, string resourceId, CommunicationCloudEnvironment? cloud = null, string rawId = null)
70+
{
71+
Argument.AssertNotNullOrEmpty(userId, nameof(userId));
72+
Argument.AssertNotNullOrEmpty(tenantId, nameof(tenantId));
73+
Argument.AssertNotNullOrEmpty(resourceId, nameof(resourceId));
74+
75+
// think whether making them GUIDs is a good idea
76+
UserId = userId;
77+
TenantId = tenantId;
78+
ResourceId = resourceId;
79+
Cloud = cloud ?? CommunicationCloudEnvironment.Public;
80+
_rawId = rawId;
81+
}
82+
83+
/// <inheritdoc />
84+
public override string ToString() => RawId;
85+
86+
/// <inheritdoc />
87+
public override bool Equals(CommunicationIdentifier other)
88+
=> other is TeamsExtensionUserIdentifier otherId
89+
&& otherId.RawId == RawId;
90+
}
91+
}

0 commit comments

Comments
 (0)