-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Modified code from Microsot.Extensions.Configuration
- Loading branch information
Showing
30 changed files
with
2,246 additions
and
0 deletions.
There are no files selected for viewing
28 changes: 28 additions & 0 deletions
28
src/Accounts/Authentication/Config/Internal/BinderOptions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// ---------------------------------------------------------------------------------- | ||
// | ||
// Copyright Microsoft Corporation | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// ---------------------------------------------------------------------------------- | ||
|
||
namespace Microsoft.Azure.Commands.Common.Authentication.Config.Internal | ||
{ | ||
/// <summary> | ||
/// Options class used by the <see cref="ConfigurationBinder"/>. | ||
/// </summary> | ||
internal class BinderOptions | ||
{ | ||
/// <summary> | ||
/// When false (the default), the binder will only attempt to set public properties. | ||
/// If true, the binder will attempt to set all non read-only properties. | ||
/// </summary> | ||
public bool BindNonPublicProperties { get; set; } | ||
} | ||
} |
587 changes: 587 additions & 0 deletions
587
src/Accounts/Authentication/Config/Internal/ConfigurationBinder.cs
Large diffs are not rendered by default.
Oops, something went wrong.
72 changes: 72 additions & 0 deletions
72
src/Accounts/Authentication/Config/Internal/ConfigurationBuilder.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
// ---------------------------------------------------------------------------------- | ||
// | ||
// Copyright Microsoft Corporation | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// ---------------------------------------------------------------------------------- | ||
|
||
using Microsoft.Azure.Commands.Common.Authentication.Config.Internal.Interfaces; | ||
using System; | ||
using System.Collections.Generic; | ||
|
||
namespace Microsoft.Azure.Commands.Common.Authentication.Config.Internal | ||
{ | ||
/// <summary> | ||
/// Used to build key/value based configuration settings for use in an application. | ||
/// </summary> | ||
internal class ConfigurationBuilder : IConfigurationBuilder | ||
{ | ||
/// <summary> | ||
/// Returns the sources used to obtain configuration values. | ||
/// </summary> | ||
public IList<IConfigurationSource> Sources { get; } = new List<IConfigurationSource>(); | ||
|
||
private IDictionary<IConfigurationSource, string> _ids = new Dictionary<IConfigurationSource, string>(); | ||
|
||
/// <summary> | ||
/// Gets a key/value collection that can be used to share data between the <see cref="IConfigurationBuilder"/> | ||
/// and the registered <see cref="IConfigurationProvider"/>s. | ||
/// </summary> | ||
public IDictionary<string, object> Properties { get; } = new Dictionary<string, object>(); | ||
|
||
/// <summary> | ||
/// Adds a new configuration source. | ||
/// </summary> | ||
/// <param name="source">The configuration source to add.</param> | ||
/// <returns>The same <see cref="IConfigurationBuilder"/>.</returns> | ||
public IConfigurationBuilder Add(string id, IConfigurationSource source) | ||
{ | ||
if (source == null) | ||
{ | ||
throw new ArgumentNullException(nameof(source)); | ||
} | ||
|
||
Sources.Add(source); | ||
_ids[source] = id; | ||
return this; | ||
} | ||
|
||
/// <summary> | ||
/// Builds an <see cref="IConfiguration"/> with keys and values from the set of providers registered in | ||
/// <see cref="Sources"/>. | ||
/// </summary> | ||
/// <returns>An <see cref="IConfigurationRoot"/> with keys and values from the registered providers.</returns> | ||
public IConfigurationRoot Build() | ||
{ | ||
var providers = new List<IConfigurationProvider>(); | ||
foreach (IConfigurationSource source in Sources) | ||
{ | ||
IConfigurationProvider provider = source.Build(this, _ids[source]); | ||
providers.Add(provider); | ||
} | ||
return new ConfigurationRoot(providers); | ||
} | ||
} | ||
} |
97 changes: 97 additions & 0 deletions
97
src/Accounts/Authentication/Config/Internal/ConfigurationExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// ---------------------------------------------------------------------------------- | ||
// | ||
// Copyright Microsoft Corporation | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// ---------------------------------------------------------------------------------- | ||
|
||
using Microsoft.Azure.Commands.Common.Authentication.Config.Internal.Interfaces; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
|
||
namespace Microsoft.Azure.Commands.Common.Authentication.Config.Internal | ||
{ | ||
/// <summary> | ||
/// Extension methods for configuration classes./>. | ||
/// </summary> | ||
internal static class ConfigurationExtensions | ||
{ | ||
/// <summary> | ||
/// Adds a new configuration source. | ||
/// </summary> | ||
/// <param name="builder">The <see cref="IConfigurationBuilder"/> to add to.</param> | ||
/// <param name="configureSource">Configures the source secrets.</param> | ||
/// <returns>The <see cref="IConfigurationBuilder"/>.</returns> | ||
public static IConfigurationBuilder Add<TSource>(this IConfigurationBuilder builder, string id, Action<TSource> configureSource) where TSource : IConfigurationSource, new() | ||
{ | ||
var source = new TSource(); | ||
configureSource?.Invoke(source); | ||
return builder.Add(id, source); | ||
} | ||
|
||
/// <summary> | ||
/// Shorthand for GetSection("ConnectionStrings")[name]. | ||
/// </summary> | ||
/// <param name="configuration">The configuration.</param> | ||
/// <param name="name">The connection string key.</param> | ||
/// <returns>The connection string.</returns> | ||
public static string GetConnectionString(this IConfiguration configuration, string name) | ||
{ | ||
return configuration?.GetSection("ConnectionStrings")?[name]; | ||
} | ||
|
||
/// <summary> | ||
/// Get the enumeration of key value pairs within the <see cref="IConfiguration" /> | ||
/// </summary> | ||
/// <param name="configuration">The <see cref="IConfiguration"/> to enumerate.</param> | ||
/// <returns>An enumeration of key value pairs.</returns> | ||
public static IEnumerable<KeyValuePair<string, string>> AsEnumerable(this IConfiguration configuration) => configuration.AsEnumerable(makePathsRelative: false); | ||
|
||
/// <summary> | ||
/// Get the enumeration of key value pairs within the <see cref="IConfiguration" /> | ||
/// </summary> | ||
/// <param name="configuration">The <see cref="IConfiguration"/> to enumerate.</param> | ||
/// <param name="makePathsRelative">If true, the child keys returned will have the current configuration's Path trimmed from the front.</param> | ||
/// <returns>An enumeration of key value pairs.</returns> | ||
public static IEnumerable<KeyValuePair<string, string>> AsEnumerable(this IConfiguration configuration, bool makePathsRelative) | ||
{ | ||
var stack = new Stack<IConfiguration>(); | ||
stack.Push(configuration); | ||
var rootSection = configuration as IConfigurationSection; | ||
int prefixLength = (makePathsRelative && rootSection != null) ? rootSection.Path.Length + 1 : 0; | ||
while (stack.Count > 0) | ||
{ | ||
IConfiguration config = stack.Pop(); | ||
// Don't include the sections value if we are removing paths, since it will be an empty key | ||
if (config is IConfigurationSection section && (!makePathsRelative || config != configuration)) | ||
{ | ||
yield return new KeyValuePair<string, string>(section.Path.Substring(prefixLength), section.Value); | ||
} | ||
foreach (IConfigurationSection child in config.GetChildren()) | ||
{ | ||
stack.Push(child); | ||
} | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Determines whether the section has a <see cref="IConfigurationSection.Value"/> or has children | ||
/// </summary> | ||
public static bool Exists(this IConfigurationSection section) | ||
{ | ||
if (section == null) | ||
{ | ||
return false; | ||
} | ||
return section.Value != null || section.GetChildren().Any(); | ||
} | ||
} | ||
} |
82 changes: 82 additions & 0 deletions
82
src/Accounts/Authentication/Config/Internal/ConfigurationKeyComparer.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// ---------------------------------------------------------------------------------- | ||
// | ||
// Copyright Microsoft Corporation | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// ---------------------------------------------------------------------------------- | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
|
||
namespace Microsoft.Azure.Commands.Common.Authentication.Config.Internal | ||
{ | ||
internal class ConfigurationKeyComparer : IComparer<string> | ||
{ | ||
private static readonly string[] _keyDelimiterArray = new[] { ConfigurationPath.KeyDelimiter }; | ||
|
||
/// <summary> | ||
/// The default instance. | ||
/// </summary> | ||
public static ConfigurationKeyComparer Instance { get; } = new ConfigurationKeyComparer(); | ||
|
||
/// <summary> | ||
/// Compares two strings. | ||
/// </summary> | ||
/// <param name="x">First string.</param> | ||
/// <param name="y">Second string.</param> | ||
/// <returns>Less than 0 if x is less than y, 0 if x is equal to y and greater than 0 if x is greater than y.</returns> | ||
public int Compare(string x, string y) | ||
{ | ||
string[] xParts = x?.Split(_keyDelimiterArray, StringSplitOptions.RemoveEmptyEntries) ?? Array.Empty<string>(); | ||
string[] yParts = y?.Split(_keyDelimiterArray, StringSplitOptions.RemoveEmptyEntries) ?? Array.Empty<string>(); | ||
|
||
// Compare each part until we get two parts that are not equal | ||
for (int i = 0; i < Math.Min(xParts.Length, yParts.Length); i++) | ||
{ | ||
x = xParts[i]; | ||
y = yParts[i]; | ||
|
||
int value1 = 0; | ||
int value2 = 0; | ||
|
||
bool xIsInt = x != null && int.TryParse(x, out value1); | ||
bool yIsInt = y != null && int.TryParse(y, out value2); | ||
|
||
int result; | ||
|
||
if (!xIsInt && !yIsInt) | ||
{ | ||
// Both are strings | ||
result = string.Compare(x, y, StringComparison.OrdinalIgnoreCase); | ||
} | ||
else if (xIsInt && yIsInt) | ||
{ | ||
// Both are int | ||
result = value1 - value2; | ||
} | ||
else | ||
{ | ||
// Only one of them is int | ||
result = xIsInt ? -1 : 1; | ||
} | ||
|
||
if (result != 0) | ||
{ | ||
// One of them is different | ||
return result; | ||
} | ||
} | ||
|
||
// If we get here, the common parts are equal. | ||
// If they are of the same length, then they are totally identical | ||
return xParts.Length - yParts.Length; | ||
} | ||
} | ||
} |
90 changes: 90 additions & 0 deletions
90
src/Accounts/Authentication/Config/Internal/ConfigurationPath.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// ---------------------------------------------------------------------------------- | ||
// | ||
// Copyright Microsoft Corporation | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// ---------------------------------------------------------------------------------- | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
|
||
namespace Microsoft.Azure.Commands.Common.Authentication.Config.Internal | ||
{ | ||
/// <summary> | ||
/// Utility methods and constants for manipulating Configuration paths | ||
/// </summary> | ||
internal static class ConfigurationPath | ||
{ | ||
/// <summary> | ||
/// The delimiter ":" used to separate individual keys in a path. | ||
/// </summary> | ||
public static readonly string KeyDelimiter = ":"; | ||
|
||
/// <summary> | ||
/// Combines path segments into one path. | ||
/// </summary> | ||
/// <param name="pathSegments">The path segments to combine.</param> | ||
/// <returns>The combined path.</returns> | ||
public static string Combine(params string[] pathSegments) | ||
{ | ||
if (pathSegments == null) | ||
{ | ||
throw new ArgumentNullException(nameof(pathSegments)); | ||
} | ||
return string.Join(KeyDelimiter, pathSegments); | ||
} | ||
|
||
/// <summary> | ||
/// Combines path segments into one path. | ||
/// </summary> | ||
/// <param name="pathSegments">The path segments to combine.</param> | ||
/// <returns>The combined path.</returns> | ||
public static string Combine(IEnumerable<string> pathSegments) | ||
{ | ||
if (pathSegments == null) | ||
{ | ||
throw new ArgumentNullException(nameof(pathSegments)); | ||
} | ||
return string.Join(KeyDelimiter, pathSegments); | ||
} | ||
|
||
/// <summary> | ||
/// Extracts the last path segment from the path. | ||
/// </summary> | ||
/// <param name="path">The path.</param> | ||
/// <returns>The last path segment of the path.</returns> | ||
public static string GetSectionKey(string path) | ||
{ | ||
if (string.IsNullOrEmpty(path)) | ||
{ | ||
return path; | ||
} | ||
|
||
int lastDelimiterIndex = path.LastIndexOf(KeyDelimiter, StringComparison.OrdinalIgnoreCase); | ||
return lastDelimiterIndex == -1 ? path : path.Substring(lastDelimiterIndex + 1); | ||
} | ||
|
||
/// <summary> | ||
/// Extracts the path corresponding to the parent node for a given path. | ||
/// </summary> | ||
/// <param name="path">The path.</param> | ||
/// <returns>The original path minus the last individual segment found in it. Null if the original path corresponds to a top level node.</returns> | ||
public static string GetParentPath(string path) | ||
{ | ||
if (string.IsNullOrEmpty(path)) | ||
{ | ||
return null; | ||
} | ||
|
||
int lastDelimiterIndex = path.LastIndexOf(KeyDelimiter, StringComparison.OrdinalIgnoreCase); | ||
return lastDelimiterIndex == -1 ? null : path.Substring(0, lastDelimiterIndex); | ||
} | ||
} | ||
} |
Oops, something went wrong.