Skip to content

Commit

Permalink
Feature/get debug view value processing (#60391)
Browse files Browse the repository at this point in the history
* Added parameter for processing the value of the configuration e.g. for obfuscation

* Rename

* Extension methods separated

* After review suggestion changes

* Documentation update

* Build fixes

* Documentation for ConfigurationDebugViewContext added

* Nullable string error fix

* Changed to nullable string

* PR fixes

* Definition fix

* Missing definition

* Added getters to the definition

* Update src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/ConfigurationRootExtensions.cs

Co-authored-by: Santiago Fernandez Madero <[email protected]>

* Tests added

* Update src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/ConfigurationDebugViewContext.cs

Docs update

Co-authored-by: Eric Erhardt <[email protected]>

* Update src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/ConfigurationDebugViewContext.cs

Docs updateDocs update

Co-authored-by: Eric Erhardt <[email protected]>

* Update src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/ConfigurationDebugViewContext.cs

Docs update

Co-authored-by: Eric Erhardt <[email protected]>

* Update src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/ConfigurationDebugViewContext.cs

Docs update

Co-authored-by: Eric Erhardt <[email protected]>

* Update src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/ConfigurationRootExtensions.cs

Docs update

Co-authored-by: Eric Erhardt <[email protected]>

* Update src/libraries/Microsoft.Extensions.Configuration.Abstractions/src/ConfigurationDebugViewContext.cs

Docs update

Co-authored-by: Eric Erhardt <[email protected]>

Co-authored-by: Santiago Fernandez Madero <[email protected]>
Co-authored-by: Eric Erhardt <[email protected]>
  • Loading branch information
3 people authored Dec 1, 2021
1 parent cc2cb04 commit 5528e84
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 1 deletion.
46 changes: 46 additions & 0 deletions src/libraries/Common/tests/Extensions/ConfigurationRootTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ namespace Microsoft.Extensions.Configuration.Test
{
public class ConfigurationRootTest
{
private const string SecretCover = "*****";

[Fact]
public void RootDisposesProviders()
{
Expand Down Expand Up @@ -77,12 +79,56 @@ public void ChainedConfigurationIsDisposed(bool shouldDispose)
Assert.Equal(shouldDispose, provider.IsDisposed);
}

[Fact]
public void SecretsAreConcealed()
{
var provider = new SecretConfigurationProvider("secret", "secret-value");

var config = new ConfigurationRoot(new IConfigurationProvider[] {
provider
});

var debugView = config.GetDebugView(ProcessValue);

Assert.Contains(SecretCover, debugView);
}

[Fact]
public void NonSecretsAreNotConcealed()
{
var provider = new TestConfigurationProvider("foo", "foo-value");

var config = new ConfigurationRoot(new IConfigurationProvider[] {
provider
});

var debugView = config.GetDebugView(ProcessValue);

Assert.DoesNotContain(SecretCover, debugView);
}

private string ProcessValue(ConfigurationDebugViewContext context)
{
if (context.ConfigurationProvider.ToString() == nameof(SecretConfigurationProvider))
{
return SecretCover;
}

return context.Value;
}

private class TestConfigurationProvider : ConfigurationProvider
{
public TestConfigurationProvider(string key, string value)
=> Data.Add(key, value);
}

private class SecretConfigurationProvider : ConfigurationProvider
{
public SecretConfigurationProvider(string key, string value)
=> Data.Add(key, value);
}

private class DisposableTestConfigurationProvider : ConfigurationProvider, IDisposable
{
public bool IsDisposed { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ public static partial class ConfigurationPath
public static partial class ConfigurationRootExtensions
{
public static string GetDebugView(this Microsoft.Extensions.Configuration.IConfigurationRoot root) { throw null; }
public static string GetDebugView(this IConfigurationRoot root, System.Func<ConfigurationDebugViewContext, string>? processValue) { throw null; }
}
public readonly partial struct ConfigurationDebugViewContext
{
public ConfigurationDebugViewContext(string path, string key, string? value, IConfigurationProvider configurationProvider) { throw null; }
public string Path { get; }
public string Key { get; }
public string? Value { get; }
public IConfigurationProvider ConfigurationProvider { get; }
}
public partial interface IConfiguration
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Microsoft.Extensions.Configuration
{
/// <summary>
/// Provides the data about current item of the configuration.
/// </summary>
public readonly struct ConfigurationDebugViewContext
{
public ConfigurationDebugViewContext(string path, string key, string? value, IConfigurationProvider configurationProvider)
{
Path = path;
Key = key;
Value = value;
ConfigurationProvider = configurationProvider;
}

/// <summary>
/// Gets the path of the current item.
/// </summary>
public string Path { get; }

/// <summary>
/// Gets the key of the current item.
/// </summary>
public string Key { get; }

/// <summary>
/// Gets the value of the current item.
/// </summary>
public string? Value { get; }

/// <summary>
/// Gets the <see cref="IConfigurationProvider" /> that was used to get the value of the current item.
/// </summary>
public IConfigurationProvider ConfigurationProvider { get; }
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
Expand All @@ -17,6 +18,22 @@ public static class ConfigurationRootExtensions
/// </summary>
/// <returns> The debug view. </returns>
public static string GetDebugView(this IConfigurationRoot root)
{
return GetDebugView(root, processValue: null);
}

/// <summary>
/// Generates a human-readable view of the configuration showing where each value came from.
/// </summary>
/// <param name="root">Configuration root</param>
/// <param name="processValue">
/// Function for processing the value e.g. hiding secrets
/// Parameters:
/// ConfigurationDebugViewContext: Context of the current configuration item
/// returns: A string value is used to assign as the Value of the configuration section
/// </param>
/// <returns> The debug view. </returns>
public static string GetDebugView(this IConfigurationRoot root, Func<ConfigurationDebugViewContext, string>? processValue)
{
void RecurseChildren(
StringBuilder stringBuilder,
Expand All @@ -29,11 +46,15 @@ void RecurseChildren(

if (valueAndProvider.Provider != null)
{
string? value = processValue != null
? processValue(new ConfigurationDebugViewContext(child.Key, child.Path, valueAndProvider.Value, valueAndProvider.Provider))
: valueAndProvider.Value;

stringBuilder
.Append(indent)
.Append(child.Key)
.Append('=')
.Append(valueAndProvider.Value)
.Append(value)
.Append(" (")
.Append(valueAndProvider.Provider)
.AppendLine(")");
Expand Down

0 comments on commit 5528e84

Please sign in to comment.