From 323dda347889c3998cb08ef86f6c9c75d2eaf4a4 Mon Sep 17 00:00:00 2001
From: Westin Musser <127992899+westin-m@users.noreply.github.com>
Date: Fri, 12 Jul 2024 15:56:29 -0700
Subject: [PATCH] Additional Write API take a Stream (#2698)
* new api takes stream
* rename method
* remove usings
* void when takes a stream, comment strings
* add testing, add api to public namespace
* review feedback
---
.../OpenIdConnectConfiguration.cs | 24 ++++++-
.../OpenIdConnectConfigurationSerializer.cs | 14 +++++
.../OpenIdConnectConfigurationTests.cs | 63 +++++++++++++++++++
3 files changed, 100 insertions(+), 1 deletion(-)
diff --git a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Configuration/OpenIdConnectConfiguration.cs b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Configuration/OpenIdConnectConfiguration.cs
index 892dde5e5a..6ff1c65483 100644
--- a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Configuration/OpenIdConnectConfiguration.cs
+++ b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Configuration/OpenIdConnectConfiguration.cs
@@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
+using System.IO;
using System.Text.Json.Serialization;
using System.Threading;
using Microsoft.IdentityModel.Abstractions;
@@ -81,7 +82,7 @@ public static OpenIdConnectConfiguration Create(string json)
///
/// object to serialize.
/// json string representing the configuration object.
- /// Thrown if is null.
+ /// Thrown if is .
public static string Write(OpenIdConnectConfiguration configuration)
{
if (configuration == null)
@@ -93,6 +94,27 @@ public static string Write(OpenIdConnectConfiguration configuration)
return OpenIdConnectConfigurationSerializer.Write(configuration);
}
+ ///
+ /// Writes an as JSON to the .
+ ///
+ /// The to serialize.
+ /// The to write to.
+ /// Because a is provided, this method does not return a value.
+ /// Thrown if or is .
+ public static void Write(OpenIdConnectConfiguration configuration, Stream stream)
+ {
+ if (configuration == null)
+ throw LogHelper.LogArgumentNullException(nameof(configuration));
+
+ if (stream == null)
+ throw LogHelper.LogArgumentNullException(nameof(stream));
+
+ if (LogHelper.IsEnabled(EventLogLevel.Verbose))
+ LogHelper.LogVerbose(LogMessages.IDX21809);
+
+ OpenIdConnectConfigurationSerializer.Write(configuration, stream);
+ }
+
///
/// Initializes an new instance of .
///
diff --git a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Json/OpenIdConnectConfigurationSerializer.cs b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Json/OpenIdConnectConfigurationSerializer.cs
index 33f5308f9a..6fa2a9bd8c 100644
--- a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Json/OpenIdConnectConfigurationSerializer.cs
+++ b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Json/OpenIdConnectConfigurationSerializer.cs
@@ -617,6 +617,20 @@ public static string Write(OpenIdConnectConfiguration OpenIdConnectConfiguration
}
}
+ public static void Write(OpenIdConnectConfiguration OpenIdConnectConfiguration, Stream stream)
+ {
+ Utf8JsonWriter writer = null;
+ try
+ {
+ writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping });
+ Write(ref writer, OpenIdConnectConfiguration);
+ }
+ finally
+ {
+ writer?.Dispose();
+ }
+ }
+
public static void Write(ref Utf8JsonWriter writer, OpenIdConnectConfiguration config)
{
writer.WriteStartObject();
diff --git a/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectConfigurationTests.cs b/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectConfigurationTests.cs
index 5437bface4..87ddf99d3e 100644
--- a/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectConfigurationTests.cs
+++ b/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectConfigurationTests.cs
@@ -5,7 +5,10 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
+using System.IO;
using System.Reflection;
+using System.Security.Cryptography;
+using System.Text;
using System.Text.Json;
using Microsoft.IdentityModel.TestUtils;
using Microsoft.IdentityModel.Tokens;
@@ -276,6 +279,32 @@ public void RoundTripFromJson()
TestUtilities.AssertFailIfErrors(context);
}
+ [Fact]
+ public void RoundTripFromJsonWithStream()
+ {
+ using MemoryStream stream = new();
+
+ var context = new CompareContext { Title = "RoundTripFromJson" };
+ var oidcConfig1 = OpenIdConnectConfiguration.Create(OpenIdConfigData.JsonAllValues);
+ var oidcConfig2 = new OpenIdConnectConfiguration(OpenIdConfigData.JsonAllValues);
+
+ OpenIdConnectConfiguration.Write(oidcConfig1, stream);
+ var oidcJson1 = Encoding.UTF8.GetString(stream.ToArray());
+ var oidcConfig3 = OpenIdConnectConfiguration.Create(oidcJson1);
+ stream.SetLength(0);
+
+ OpenIdConnectConfiguration.Write(oidcConfig2, stream);
+ var oidcJson2 = Encoding.UTF8.GetString(stream.ToArray());
+ var oidcConfig4 = new OpenIdConnectConfiguration(oidcJson2);
+
+ IdentityComparer.AreEqual(oidcConfig1, oidcConfig2, context);
+ IdentityComparer.AreEqual(oidcConfig1, oidcConfig3, context);
+ IdentityComparer.AreEqual(oidcConfig1, oidcConfig4, context);
+ IdentityComparer.AreEqual(oidcJson1, oidcJson2, context);
+
+ TestUtilities.AssertFailIfErrors(context);
+ }
+
[Fact]
public void EmptyCollectionSerialization()
{
@@ -289,6 +318,22 @@ public void EmptyCollectionSerialization()
TestUtilities.AssertFailIfErrors(context);
}
+ [Fact]
+ public void EmptyCollectionSerializationWithStream()
+ {
+ using MemoryStream stream = new();
+
+ var context = new CompareContext {Title = "EmptyCollectionSerialization"};
+ // Initialize an OpenIdConnectConfiguration object with all collections empty.
+ var oidcWithEmptyCollections = new OpenIdConnectConfiguration();
+ OpenIdConnectConfiguration.Write(oidcWithEmptyCollections, stream);
+ var emptyCollectionBytes = Encoding.UTF8.GetBytes("{}");
+
+ IdentityComparer.AreEqual(stream.ToArray(), emptyCollectionBytes, context);
+
+ TestUtilities.AssertFailIfErrors(context);
+ }
+
[Fact]
public void NonemptyCollectionSerialization()
{
@@ -345,5 +390,23 @@ public void NonemptyCollectionSerialization()
}
TestUtilities.AssertFailIfErrors(context);
}
+
+ [Fact]
+ public void NonemptyCollectionSerializationWithStream()
+ {
+ using MemoryStream stream = new();
+
+ var context = new CompareContext { Title = "NonemptyCollectionSerialization" };
+ // Initialize an OpenIdConnectConfiguration object that has at least one element in each Collection.
+ var oidcWithAllCollections = OpenIdConnectConfiguration.Create(OpenIdConfigData.JsonAllValues);
+ var oidcWithAllCollectionsJson = OpenIdConnectConfiguration.Write(oidcWithAllCollections);
+ var oidcWithAllCollectionsBytes = Encoding.UTF8.GetBytes(oidcWithAllCollectionsJson);
+
+ OpenIdConnectConfiguration.Write(oidcWithAllCollections, stream);
+
+ IdentityComparer.AreBytesEqual(oidcWithAllCollectionsBytes, stream.GetBuffer(), context);
+
+ TestUtilities.AssertFailIfErrors(context);
+ }
}
}