Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@

<PropertyGroup Label="Common dependency versions">
<MicrosoftIdentityModelVersion Condition="'$(MicrosoftIdentityModelVersion)' == ''">8.19.1</MicrosoftIdentityModelVersion>
<MicrosoftIdentityClientVersion Condition="'$(MicrosoftIdentityClientVersion)' == ''">4.85.2</MicrosoftIdentityClientVersion>
<MicrosoftIdentityClientKeyAttestationVersion Condition="'$(MicrosoftIdentityClientKeyAttestationVersion)' == ''">4.85.2</MicrosoftIdentityClientKeyAttestationVersion>
<MicrosoftIdentityClientVersion Condition="'$(MicrosoftIdentityClientVersion)' == ''">4.86.0</MicrosoftIdentityClientVersion>
<MicrosoftIdentityClientKeyAttestationVersion Condition="'$(MicrosoftIdentityClientKeyAttestationVersion)' == ''">4.86.0</MicrosoftIdentityClientKeyAttestationVersion>
<MicrosoftIdentityAbstractionsVersion Condition="'$(MicrosoftIdentityAbstractionsVersion)' == ''">12.4.0</MicrosoftIdentityAbstractionsVersion>
<FxCopAnalyzersVersion>3.3.0</FxCopAnalyzersVersion>
<SystemTextEncodingsWebVersion>4.7.2</SystemTextEncodingsWebVersion>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using Microsoft.Identity.Client;
using Microsoft.Identity.Client.Region;
using Abstractions = Microsoft.Identity.Abstractions;

namespace Microsoft.Identity.Web
Expand Down Expand Up @@ -65,8 +66,15 @@ public static Abstractions.AcquireTokenResult FromMsal(AuthenticationResult resu
source is null ? null : new Abstractions.AcquiredTokenRegionDetails
{
RegionUsed = source.RegionUsed,
RegionOutcome = (Abstractions.AcquiredTokenRegionOutcome)source.RegionOutcome,
RegionOutcome = MapRegionOutcome(source.RegionOutcome),
AutoDetectionError = source.AutoDetectionError,
};

private static Abstractions.AcquiredTokenRegionOutcome MapRegionOutcome(RegionOutcome regionOutcome) =>
regionOutcome switch
{
RegionOutcome.UserProvided => Abstractions.AcquiredTokenRegionOutcome.UserProvidedValid,
_ => (Abstractions.AcquiredTokenRegionOutcome)regionOutcome,
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ namespace Microsoft.Identity.Web.Test
{
/// <summary>
/// Pins the numeric lockstep between MSAL enums and their Abstractions counterparts.
/// <see cref="AcquireTokenResultFactory.MapMetadata"/> casts MSAL enum values directly
/// to Abstractions enum values. If MSAL ever renumbers a member or adds a new one
/// out of order, these tests will fail loudly instead of producing silently-wrong
/// telemetry. One assertion per member of every casted enum.
/// <see cref="AcquireTokenResultFactory"/> maps MSAL enum values to their Abstractions
/// counterparts. If MSAL ever renumbers a member or adds a new one out of order,
/// these tests will fail loudly instead of producing silently-wrong telemetry.
/// One assertion per member of every casted enum.
/// </summary>
public class AcquireTokenResultFactoryEnumRoundTripTests
{
Expand Down Expand Up @@ -54,15 +54,15 @@ public void CacheLevel_NumericCast_RoundTrips(CacheLevel msal, Abstractions.Acqu
}

[Theory]
[InlineData(RegionOutcome.None, Abstractions.AcquiredTokenRegionOutcome.None)]
[InlineData(RegionOutcome.UserProvidedValid, Abstractions.AcquiredTokenRegionOutcome.UserProvidedValid)]
[InlineData(RegionOutcome.UserProvidedAutodetectionFailed, Abstractions.AcquiredTokenRegionOutcome.UserProvidedAutodetectionFailed)]
[InlineData(RegionOutcome.UserProvidedInvalid, Abstractions.AcquiredTokenRegionOutcome.UserProvidedInvalid)]
[InlineData(RegionOutcome.AutodetectSuccess, Abstractions.AcquiredTokenRegionOutcome.AutodetectSuccess)]
[InlineData(RegionOutcome.FallbackToGlobal, Abstractions.AcquiredTokenRegionOutcome.FallbackToGlobal)]
public void RegionOutcome_NumericCast_RoundTrips(RegionOutcome msal, Abstractions.AcquiredTokenRegionOutcome expected)
[InlineData((int)RegionOutcome.None, Abstractions.AcquiredTokenRegionOutcome.None)]
[InlineData(1, Abstractions.AcquiredTokenRegionOutcome.UserProvidedValid)]
[InlineData(2, Abstractions.AcquiredTokenRegionOutcome.UserProvidedAutodetectionFailed)]
[InlineData(3, Abstractions.AcquiredTokenRegionOutcome.UserProvidedInvalid)]
[InlineData((int)RegionOutcome.AutodetectSuccess, Abstractions.AcquiredTokenRegionOutcome.AutodetectSuccess)]
[InlineData((int)RegionOutcome.FallbackToGlobal, Abstractions.AcquiredTokenRegionOutcome.FallbackToGlobal)]
public void RegionOutcome_NumericCast_RoundTrips(int msal, Abstractions.AcquiredTokenRegionOutcome expected)
{
Assert.Equal((int)expected, (int)msal);
Assert.Equal((int)expected, msal);
Assert.Equal(expected, (Abstractions.AcquiredTokenRegionOutcome)msal);
}

Expand All @@ -88,7 +88,7 @@ public void EnumMemberCounts_MatchAbstractions()
System.Enum.GetValues(typeof(Abstractions.AcquiredTokenCacheLevel)).Length);

Assert.Equal(
System.Enum.GetValues(typeof(RegionOutcome)).Length,
System.Enum.GetValues(typeof(RegionOutcome)).Length - 1,
System.Enum.GetValues(typeof(Abstractions.AcquiredTokenRegionOutcome)).Length);
}

Expand Down Expand Up @@ -126,6 +126,40 @@ public void GetMetadata_SetsExpiresOn_FromResult_WhenMetadataAvailable()
Assert.Equal(refreshOn, metadata.RefreshOn);
}

[Fact]
public void GetMetadata_MapsUserProvidedRegionOutcome_ToStableAbstractionsOutcome()
{
// Arrange
const string region = "westus2";
DateTimeOffset expiresOn = DateTimeOffset.UtcNow.AddHours(1);
DateTimeOffset extendedExpiresOn = DateTimeOffset.UtcNow.AddHours(2);
var source = new AuthenticationResultMetadata(TokenSource.IdentityProvider)
{
RegionDetails = new RegionDetails(RegionOutcome.UserProvided, region, string.Empty),
};
var result = new AuthenticationResult(
"access-token",
false,
null,
expiresOn,
extendedExpiresOn,
"tenant",
null,
null,
new[] { "scope" },
Guid.NewGuid(),
source);

// Act
Abstractions.TokenAcquisitionMetadata? metadata = AcquireTokenResultFactory.GetMetadata(result);

// Assert
Assert.NotNull(metadata);
Assert.NotNull(metadata!.RegionDetails);
Assert.Equal(region, metadata.RegionDetails!.RegionUsed);
Assert.Equal(Abstractions.AcquiredTokenRegionOutcome.UserProvidedValid, metadata.RegionDetails.RegionOutcome);
}

[Fact]
public void GetMetadata_ReturnsNull_WhenMetadataAbsent()
{
Expand Down
Loading