From a1b77bcbbd9053463404fe0177d42961a3aae044 Mon Sep 17 00:00:00 2001 From: pmaytak <34331512+pmaytak@users.noreply.github.com> Date: Thu, 11 Feb 2021 21:59:32 -0800 Subject: [PATCH] Minor fixes. Update tests. --- .../Validation/AdfsWebFingerResponse.cs | 1 - .../OAuth2/MsalTokenResponse.cs | 53 ++- .../UtilTests/JsonHelperTests.cs | 309 ++++++++++-------- 3 files changed, 220 insertions(+), 143 deletions(-) diff --git a/src/client/Microsoft.Identity.Client/Instance/Validation/AdfsWebFingerResponse.cs b/src/client/Microsoft.Identity.Client/Instance/Validation/AdfsWebFingerResponse.cs index 512f1eb083..16fc214a4f 100644 --- a/src/client/Microsoft.Identity.Client/Instance/Validation/AdfsWebFingerResponse.cs +++ b/src/client/Microsoft.Identity.Client/Instance/Validation/AdfsWebFingerResponse.cs @@ -64,7 +64,6 @@ internal class AdfsWebFingerResponse : OAuth2ResponseBase, IJsonSerializable new LinksList().DeserializeFromJson(c.ToString())).ToList(); - base.DeserializeFromJson(json); return this; diff --git a/src/client/Microsoft.Identity.Client/OAuth2/MsalTokenResponse.cs b/src/client/Microsoft.Identity.Client/OAuth2/MsalTokenResponse.cs index d987ecd967..f19774ceb6 100644 --- a/src/client/Microsoft.Identity.Client/OAuth2/MsalTokenResponse.cs +++ b/src/client/Microsoft.Identity.Client/OAuth2/MsalTokenResponse.cs @@ -11,6 +11,7 @@ using Microsoft.Identity.Client.Http; using Microsoft.Identity.Client.Core; using System.Text; +using System.Net; namespace Microsoft.Identity.Client.OAuth2 { @@ -36,6 +37,13 @@ internal class TokenResponseClaim : OAuth2ResponseBaseClaim [Preserve(AllMembers = true)] internal class MsalTokenResponse : OAuth2ResponseBase, IJsonSerializable { + private const string WamAccountIdPropertyName = "WamAccountId"; + private const string AccessTokenExpiresOnPropertyName = "AccessTokenExpiresOn"; + private const string AccessTokenExtendedExpiresOnPropertyName = "AccessTokenExtendedExpiresOn"; + private const string AccessTokenRefreshOnPropertyName = "AccessTokenRefreshOn"; + private const string TokenSourcePropertyName = "TokenSource"; + private const string HttpResponsePropertyName = "HttpResponse"; + private long _expiresIn; private long _extendedExpiresIn; private long _refreshIn; @@ -122,8 +130,30 @@ public long RefreshIn ExtendedExpiresIn = long.Parse(jObject[TokenResponseClaim.ExtendedExpiresIn]?.ToString(), CultureInfo.InvariantCulture); RefreshIn = long.Parse(jObject[TokenResponseClaim.RefreshIn]?.ToString(), CultureInfo.InvariantCulture); FamilyId = jObject[TokenResponseClaim.FamilyId]?.ToString(); + WamAccountId = jObject[WamAccountIdPropertyName]?.ToString(); + AccessTokenExpiresOn = DateTime.Parse(jObject[AccessTokenExpiresOnPropertyName]?.ToString(), CultureInfo.CurrentCulture); + AccessTokenExtendedExpiresOn = DateTime.Parse(jObject[AccessTokenExtendedExpiresOnPropertyName]?.ToString(), CultureInfo.CurrentCulture); + AccessTokenRefreshOn = DateTime.Parse(jObject[AccessTokenRefreshOnPropertyName]?.ToString(), CultureInfo.CurrentCulture); + TokenSource = (TokenSource)Convert.ToInt32(jObject[TokenSourcePropertyName]?.ToString(), CultureInfo.InvariantCulture); + HttpResponse = DeserializeHttpResponse(jObject[HttpResponsePropertyName]); base.DeserializeFromJson(json); + HttpResponse DeserializeHttpResponse(JToken httpResponseJson) + { + if (httpResponseJson != null) + { + HttpResponse = new HttpResponse() + { + Headers = null, + StatusCode = (HttpStatusCode)int.Parse(httpResponseJson["StatusCode"]?.ToString(), CultureInfo.InvariantCulture), + UserAgent = jObject["UserAgent"]?.ToString(), + Body = jObject["Body"]?.ToString() + }; + } + + return HttpResponse; + } + return this; } @@ -140,14 +170,31 @@ public long RefreshIn new JProperty(TokenResponseClaim.ExtendedExpiresIn, ExtendedExpiresIn), new JProperty(TokenResponseClaim.RefreshIn, RefreshIn), new JProperty(TokenResponseClaim.FamilyId, FamilyId), + new JProperty(WamAccountIdPropertyName, WamAccountId), + new JProperty(AccessTokenExpiresOnPropertyName, AccessTokenExpiresOn), + new JProperty(AccessTokenExtendedExpiresOnPropertyName, AccessTokenExtendedExpiresOn), + new JProperty(AccessTokenRefreshOnPropertyName, AccessTokenRefreshOn), + new JProperty(TokenSourcePropertyName, TokenSource), + new JProperty(HttpResponsePropertyName, SerializeHttpResponse()), JObject.Parse(base.SerializeToJson()).Properties()); + JObject SerializeHttpResponse() + { + return new JObject( + new JProperty("Headers", new JArray()), + new JProperty("HeadersAsDictionary", new JObject()), + new JProperty("StatusCode", (int)HttpResponse.StatusCode), + new JProperty("UserAgent", HttpResponse.UserAgent), + new JProperty("Body", HttpResponse.Body) + ); + } + return jObject.ToString(Formatting.None); } internal static MsalTokenResponse CreateFromiOSBrokerResponse(Dictionary responseDictionary) { - if (responseDictionary.TryGetValue(BrokerResponseConst.BrokerErrorCode, out string errorCode)) + if (responseDictionary.TryGetValue(BrokerResponseConst.BrokerErrorCode, out string errorCode)) { return new MsalTokenResponse { @@ -178,7 +225,7 @@ internal static MsalTokenResponse CreateFromiOSBrokerResponse(Dictionary(expected); - var jsonSerializedNew = JsonHelper.SerializeNew(expected); + // Act - serialize + string jsonSerializedLegacy = JsonHelper.SerializeToJson(expected); + string jsonSerializedNew = JsonHelper.SerializeNew(expected); // Assert serialization Assert.AreEqual(jsonSerializedLegacy, jsonSerializedNew); - var objectDeserializedNew = JsonHelper.DeserializeNew(jsonSerializedLegacy); + // Act - deserialize + OAuth2ResponseBase objectDeserializedNew = JsonHelper.DeserializeNew(jsonSerializedLegacy); // Assert deserialization - Assert.AreEqual(expected.Error, objectDeserializedNew.Error); - Assert.AreEqual(expected.SubError, objectDeserializedNew.SubError); - Assert.AreEqual(expected.ErrorDescription, objectDeserializedNew.ErrorDescription); - CollectionAssert.AreEqual(expected.ErrorCodes, objectDeserializedNew.ErrorCodes); - Assert.AreEqual(expected.CorrelationId, objectDeserializedNew.CorrelationId); - Assert.AreEqual(expected.Claims, objectDeserializedNew.Claims); + AssertOAuth2ResponseBaseProperties(expected, objectDeserializedNew); } [TestMethod] public void IJsonSerializable_InstanceDiscoveryMetadataEntry_Test() { - var expected = new InstanceDiscoveryMetadataEntry() - { - Aliases = new[] { "login.windows.net", "login.microsoftonline.com" }, - PreferredCache = "login.windows.net", - PreferredNetwork = "login.microsoftonline.com" - }; + // Arrange + InstanceDiscoveryMetadataEntry expected = SetInstanceDiscoveryMetadataEntryProperties(new InstanceDiscoveryMetadataEntry()); - var jsonSerializedLegacy = JsonHelper.SerializeToJson(expected); - var jsonSerializedNew = JsonHelper.SerializeNew(expected); + // Act - serialize + string jsonSerializedLegacy = JsonHelper.SerializeToJson(expected); + string jsonSerializedNew = JsonHelper.SerializeNew(expected); // Assert serialization Assert.AreEqual(jsonSerializedLegacy, jsonSerializedNew); - var objectDeserializedNew = JsonHelper.DeserializeNew(jsonSerializedLegacy); + // Act - deserialize + InstanceDiscoveryMetadataEntry objectDeserializedNew = JsonHelper.DeserializeNew(jsonSerializedLegacy); // Assert deserialization - Assert.AreEqual(expected.PreferredCache, objectDeserializedNew.PreferredCache); - Assert.AreEqual(expected.PreferredNetwork, objectDeserializedNew.PreferredNetwork); - CollectionAssert.AreEqual(expected.Aliases, objectDeserializedNew.Aliases); + AssertInstanceDiscoveryMetadataEntryProperties(expected, objectDeserializedNew); } [TestMethod] public void IJsonSerializable_InstanceDiscoveryResponse_Test() { - var expected = new InstanceDiscoveryResponse() - { - TenantDiscoveryEndpoint = TestConstants.DiscoveryEndPoint, - Metadata = new[] - { - new InstanceDiscoveryMetadataEntry() - { - Aliases = new[] { "login.windows.net", "login.microsoftonline.com" }, - PreferredCache = "login.windows.net", - PreferredNetwork = "login.microsoftonline.com" - }, - new InstanceDiscoveryMetadataEntry() - { - Aliases = new[] { "centralus.login.microsoft.com" }, - PreferredCache = "login.microsoftonline.com", - PreferredNetwork = "centralus.login.microsoft.com" - } - }, - Error = "OAuth error", - SubError = "OAuth suberror", - ErrorDescription = "OAuth error description", - ErrorCodes = new[] { "error1", "error2", "error3" }, - CorrelationId = "1234-123-1234", - Claims = "claim1 claim2" - }; + // Arrange + InstanceDiscoveryResponse expected = SetInstanceDiscoveryResponseProperties(new InstanceDiscoveryResponse()); - var jsonSerializedLegacy = JsonHelper.SerializeToJson(expected); - var jsonSerializedNew = JsonHelper.SerializeNew(expected); + // Act - serialize + string jsonSerializedLegacy = JsonHelper.SerializeToJson(expected); + string jsonSerializedNew = JsonHelper.SerializeNew(expected); // Assert serialization Assert.AreEqual(jsonSerializedLegacy, jsonSerializedNew); - var objectDeserializedNew = JsonHelper.DeserializeNew(jsonSerializedLegacy); + // Act - deserialize + InstanceDiscoveryResponse objectDeserializedNew = JsonHelper.DeserializeNew(jsonSerializedLegacy); // Assert deserialization - Assert.AreEqual(expected.TenantDiscoveryEndpoint, objectDeserializedNew.TenantDiscoveryEndpoint); - Assert.AreEqual(expected.Metadata.Length, objectDeserializedNew.Metadata.Length); - // AssertCollectionItemsEqualByValue(expected.Metadata, objectDeserializedManually.Metadata); - Assert.AreEqual(expected.Error, objectDeserializedNew.Error); - Assert.AreEqual(expected.SubError, objectDeserializedNew.SubError); - Assert.AreEqual(expected.ErrorDescription, objectDeserializedNew.ErrorDescription); - CollectionAssert.AreEqual(expected.ErrorCodes, objectDeserializedNew.ErrorCodes); - Assert.AreEqual(expected.CorrelationId, objectDeserializedNew.CorrelationId); - Assert.AreEqual(expected.Claims, objectDeserializedNew.Claims); + AssertInstanceDiscoveryResponseProperties(expected, objectDeserializedNew); } [TestMethod] public void IJsonSerializable_DeviceCodeResponse_Test() { - var expected = new DeviceCodeResponse() - { - UserCode = "user code", - DeviceCode = "device code", - VerificationUrl = "verification url", - VerificationUri = "verification uri", - ExpiresIn = 1234, - Interval = 12345, - Message = "device message", - Error = "OAuth error", - SubError = "OAuth suberror", - ErrorDescription = "OAuth error description", - ErrorCodes = new[] { "error1", "error2", "error3" }, - CorrelationId = "1234-123-1234", - Claims = "claim1 claim2" - }; + // Arrange + DeviceCodeResponse expected = SetDeviceCodeResponseProperties(new DeviceCodeResponse()); - var jsonSerializedLegacy = JsonHelper.SerializeToJson(expected); - var jsonSerializedNew = JsonHelper.SerializeNew(expected); + // Act - serialize + string jsonSerializedLegacy = JsonHelper.SerializeToJson(expected); + string jsonSerializedNew = JsonHelper.SerializeNew(expected); // Assert serialization Assert.AreEqual(jsonSerializedLegacy, jsonSerializedNew); - var objectDeserializedNew = JsonHelper.DeserializeNew(jsonSerializedLegacy); + // Act - deserialize + DeviceCodeResponse objectDeserializedNew = JsonHelper.DeserializeNew(jsonSerializedLegacy); // Assert deserialization - Assert.AreEqual(expected.UserCode, objectDeserializedNew.UserCode); - Assert.AreEqual(expected.DeviceCode, objectDeserializedNew.DeviceCode); - Assert.AreEqual(expected.VerificationUrl, objectDeserializedNew.VerificationUrl); - Assert.AreEqual(expected.VerificationUri, objectDeserializedNew.VerificationUri); - Assert.AreEqual(expected.ExpiresIn, objectDeserializedNew.ExpiresIn); - Assert.AreEqual(expected.Interval, objectDeserializedNew.Interval); - Assert.AreEqual(expected.Message, objectDeserializedNew.Message); - Assert.AreEqual(expected.Error, objectDeserializedNew.Error); - Assert.AreEqual(expected.SubError, objectDeserializedNew.SubError); - Assert.AreEqual(expected.ErrorDescription, objectDeserializedNew.ErrorDescription); - CollectionAssert.AreEqual(expected.ErrorCodes, objectDeserializedNew.ErrorCodes); - Assert.AreEqual(expected.CorrelationId, objectDeserializedNew.CorrelationId); - Assert.AreEqual(expected.Claims, objectDeserializedNew.Claims); + AssertDeviceCodeResponseProperties(expected, objectDeserializedNew); } [TestMethod] public void IJsonSerializable_MsalTokenResponse_Test() { - var expected = new MsalTokenResponse() - { - TokenType = "token type", - AccessToken = "access token", - RefreshToken = "refresh token", - Scope = "scope scope", - ClientInfo = "client info", - IdToken = "id token", - ExpiresIn = 1234, - ExtendedExpiresIn = 12345, - RefreshIn = 12333, - FamilyId = "family id", - HttpResponse = new Client.Http.HttpResponse(), - Error = "OAuth error", - SubError = "OAuth suberror", - ErrorDescription = "OAuth error description", - ErrorCodes = new[] { "error1", "error2", "error3" }, - CorrelationId = "1234-123-1234", - Claims = "claim1 claim2" - }; + MsalTokenResponse expected = SetMsalTokenResponseProperties(new MsalTokenResponse()); - var jsonSerializedLegacy = JsonHelper.SerializeToJson(expected); - var jsonSerializedNew = JsonHelper.SerializeNew(expected); + // Act - serialize + string jsonSerializedLegacy = JsonHelper.SerializeToJson(expected); + string jsonSerializedNew = JsonHelper.SerializeNew(expected); // Assert serialization Assert.AreEqual(jsonSerializedLegacy, jsonSerializedNew); - var objectDeserializedNew = JsonHelper.DeserializeNew(jsonSerializedLegacy); + // Act - deserialize + MsalTokenResponse objectDeserializedNew = JsonHelper.DeserializeNew(jsonSerializedLegacy); // Assert deserialization - Assert.AreEqual(expected.TokenType, objectDeserializedNew.TokenType); - Assert.AreEqual(expected.AccessToken, objectDeserializedNew.AccessToken); - Assert.AreEqual(expected.RefreshToken, objectDeserializedNew.RefreshToken); - Assert.AreEqual(expected.Scope, objectDeserializedNew.Scope); - Assert.AreEqual(expected.ClientInfo, objectDeserializedNew.ClientInfo); - Assert.AreEqual(expected.IdToken, objectDeserializedNew.IdToken); - Assert.AreEqual(expected.ExpiresIn, objectDeserializedNew.ExpiresIn); - Assert.AreEqual(expected.ExtendedExpiresIn, objectDeserializedNew.ExtendedExpiresIn); - Assert.AreEqual(expected.RefreshIn, objectDeserializedNew.RefreshIn); - Assert.AreEqual(expected.FamilyId, objectDeserializedNew.FamilyId); - Assert.AreEqual(expected.Error, objectDeserializedNew.Error); - Assert.AreEqual(expected.SubError, objectDeserializedNew.SubError); - Assert.AreEqual(expected.ErrorDescription, objectDeserializedNew.ErrorDescription); - CollectionAssert.AreEqual(expected.ErrorCodes, objectDeserializedNew.ErrorCodes); - Assert.AreEqual(expected.CorrelationId, objectDeserializedNew.CorrelationId); - Assert.AreEqual(expected.Claims, objectDeserializedNew.Claims); + AssertMsalTokenResponseProperties(expected, objectDeserializedNew); } [TestMethod] @@ -478,6 +381,134 @@ public void IJsonSerializable_AdfsWebFingerResponse_Test() Assert.AreEqual(expected.CorrelationId, objectDeserializedNew.CorrelationId); Assert.AreEqual(expected.Claims, objectDeserializedNew.Claims); } + + private OAuth2ResponseBase SetOAuth2ResponseBaseProperties(OAuth2ResponseBase oAuth2ResponseBase) + { + oAuth2ResponseBase.Error = "OAuth error"; + oAuth2ResponseBase.SubError = "OAuth suberror"; + oAuth2ResponseBase.ErrorDescription = "OAuth error description"; + oAuth2ResponseBase.ErrorCodes = new[] { "error1", "error2", "error3" }; + oAuth2ResponseBase.CorrelationId = "1234-123-1234"; + oAuth2ResponseBase.Claims = "claim1 claim2"; + + return oAuth2ResponseBase; + } + + private void AssertOAuth2ResponseBaseProperties(OAuth2ResponseBase expected, OAuth2ResponseBase actual) + { + Assert.AreEqual(expected.Error, actual.Error); + Assert.AreEqual(expected.SubError, actual.SubError); + Assert.AreEqual(expected.ErrorDescription, actual.ErrorDescription); + CollectionAssert.AreEqual(expected.ErrorCodes, actual.ErrorCodes); + Assert.AreEqual(expected.CorrelationId, actual.CorrelationId); + Assert.AreEqual(expected.Claims, actual.Claims); + } + + private InstanceDiscoveryMetadataEntry SetInstanceDiscoveryMetadataEntryProperties(InstanceDiscoveryMetadataEntry instanceDiscoveryMetadataEntry) + { + instanceDiscoveryMetadataEntry.Aliases = new[] { "login.windows.net", "login.microsoftonline.com" }; + instanceDiscoveryMetadataEntry.PreferredCache = "login.windows.net"; + instanceDiscoveryMetadataEntry.PreferredNetwork = "login.microsoftonline.com"; + + return instanceDiscoveryMetadataEntry; + } + + private void AssertInstanceDiscoveryMetadataEntryProperties(InstanceDiscoveryMetadataEntry expected, InstanceDiscoveryMetadataEntry actual) + { + Assert.AreEqual(expected.PreferredCache, actual.PreferredCache); + Assert.AreEqual(expected.PreferredNetwork, actual.PreferredNetwork); + CollectionAssert.AreEqual(expected.Aliases, actual.Aliases); + } + + private InstanceDiscoveryResponse SetInstanceDiscoveryResponseProperties(InstanceDiscoveryResponse instanceDiscoveryResponse) + { + instanceDiscoveryResponse.TenantDiscoveryEndpoint = TestConstants.DiscoveryEndPoint; + instanceDiscoveryResponse.Metadata = new[] + { + SetInstanceDiscoveryMetadataEntryProperties(new InstanceDiscoveryMetadataEntry()) + }; + SetOAuth2ResponseBaseProperties(instanceDiscoveryResponse); + + return instanceDiscoveryResponse; + } + + private void AssertInstanceDiscoveryResponseProperties(InstanceDiscoveryResponse expected, InstanceDiscoveryResponse actual) + { + Assert.AreEqual(expected.TenantDiscoveryEndpoint, actual.TenantDiscoveryEndpoint); + Assert.AreEqual(expected.Metadata.Length, actual.Metadata.Length); + for (int i = 0; i < expected.Metadata.Length; i++) + { + AssertInstanceDiscoveryMetadataEntryProperties(expected.Metadata[i], actual.Metadata[i]); + } + AssertOAuth2ResponseBaseProperties(expected, actual); + } + + private DeviceCodeResponse SetDeviceCodeResponseProperties(DeviceCodeResponse deviceCodeResponse) + { + deviceCodeResponse.UserCode = "user code"; + deviceCodeResponse.DeviceCode = "device code"; + deviceCodeResponse.VerificationUrl = "verification url"; + deviceCodeResponse.VerificationUri = "verification uri"; + deviceCodeResponse.ExpiresIn = 1234; + deviceCodeResponse.Interval = 12345; + deviceCodeResponse.Message = "device message"; + SetOAuth2ResponseBaseProperties(deviceCodeResponse); + + return deviceCodeResponse; + } + + private void AssertDeviceCodeResponseProperties(DeviceCodeResponse expected, DeviceCodeResponse actual) + { + Assert.AreEqual(expected.UserCode, actual.UserCode); + Assert.AreEqual(expected.DeviceCode, actual.DeviceCode); + Assert.AreEqual(expected.VerificationUrl, actual.VerificationUrl); + Assert.AreEqual(expected.VerificationUri, actual.VerificationUri); + Assert.AreEqual(expected.ExpiresIn, actual.ExpiresIn); + Assert.AreEqual(expected.Interval, actual.Interval); + Assert.AreEqual(expected.Message, actual.Message); + AssertOAuth2ResponseBaseProperties(expected, actual); + } + + private MsalTokenResponse SetMsalTokenResponseProperties(MsalTokenResponse msalTokenResponse) + { + msalTokenResponse.TokenType = "token type"; + msalTokenResponse.AccessToken = "access token"; + msalTokenResponse.RefreshToken = "refresh token"; + msalTokenResponse.Scope = "scope scope"; + msalTokenResponse.ClientInfo = "client info"; + msalTokenResponse.IdToken = "id token"; + msalTokenResponse.ExpiresIn = 123; + msalTokenResponse.ExtendedExpiresIn = 12345; + msalTokenResponse.RefreshIn = 12333; + msalTokenResponse.FamilyId = "family id"; + msalTokenResponse.WamAccountId = "wam id"; + msalTokenResponse.TokenSource = Client.TokenSource.Cache; + msalTokenResponse.HttpResponse = new Client.Http.HttpResponse() + { + Headers = new HttpResponseMessage().Headers, + StatusCode = HttpStatusCode.OK, + Body = "HTTP body", + UserAgent = "User Agent" + }; + SetOAuth2ResponseBaseProperties(msalTokenResponse); + + return msalTokenResponse; + } + + private void AssertMsalTokenResponseProperties(MsalTokenResponse expected, MsalTokenResponse actual) + { + Assert.AreEqual(expected.TokenType, actual.TokenType); + Assert.AreEqual(expected.AccessToken, actual.AccessToken); + Assert.AreEqual(expected.RefreshToken, actual.RefreshToken); + Assert.AreEqual(expected.Scope, actual.Scope); + Assert.AreEqual(expected.ClientInfo, actual.ClientInfo); + Assert.AreEqual(expected.IdToken, actual.IdToken); + Assert.AreEqual(expected.ExpiresIn, actual.ExpiresIn); + Assert.AreEqual(expected.ExtendedExpiresIn, actual.ExtendedExpiresIn); + Assert.AreEqual(expected.RefreshIn, actual.RefreshIn); + Assert.AreEqual(expected.FamilyId, actual.FamilyId); + AssertOAuth2ResponseBaseProperties(expected, actual); + } #endregion } }