use ClientSecretCredentialOptions & friends
b45ecf92
Alexander Nosenko
committed
21 changed files
ConnectionStringExtensions.cs
/src/Refactorius.Authentication/Core/ConnectionStringExtensions.cs+54
/src/Refactorius.Authentication/Core/ConnectionStringExtensions.cs
Add comment 1 Plus  using System.Data.Common;
Add comment 2 Plus  
Add comment 3 Plus  namespace Refactorius.Authentication.Core;
Add comment 4 Plus  
Add comment 5 Plus  public static class ConnectionStringExtensions
Add comment 6 Plus  {
Add comment 7 Plus   /// <summary>
Add comment 8 Plus   /// Converts a ; separated string into a dictionary.
Add comment 9 Plus   /// </summary>
Add comment 10 Plus   /// <param name="connectionString">String to parse.</param>
Add comment 11 Plus   /// <param name="lowercaseKeys">True to lower-case resulting keys lower-case, otherwise upper-case.</param>
Add comment 12 Plus   /// <returns>Dictionary of properties from the connection string.</returns>
Add comment 13 Plus   public static IDictionary<string, string?> ToConnectionStringDictionary(this string connectionString, bool lowercaseKeys)
Add comment 14 Plus   {
Add comment 15 Plus   var result = new Dictionary<string, string?>(StringComparer.OrdinalIgnoreCase);
Add comment 16 Plus   if (string.IsNullOrWhiteSpace(connectionString))
Add comment 17 Plus   return result;
Add comment 18 Plus  
Add comment 19 Plus   try
Add comment 20 Plus   {
Add comment 21 Plus   DbConnectionStringBuilder source = new DbConnectionStringBuilder
Add comment 22 Plus   {
Add comment 23 Plus   ConnectionString = connectionString
Add comment 24 Plus   };
Add comment 25 Plus  
Add comment 26 Plus   source
Add comment 27 Plus   .Cast<KeyValuePair<string, object>>()
Add comment 28 Plus   .ForEach(kvp => result.Add(
Add comment 29 Plus   lowercaseKeys
Add comment 30 Plus   ? kvp.Key.ToLowerInvariant()
Add comment 31 Plus   : kvp.Key.ToUpperInvariant(),
Add comment 32 Plus   kvp.Value?.ToString()?.Trim() ?? string.Empty));
Add comment 33 Plus   return result;
Add comment 34 Plus   }
Add comment 35 Plus   catch
Add comment 36 Plus   {
Add comment 37 Plus   throw new FormatException("Invalid connection string format.");
Add comment 38 Plus   }
Add comment 39 Plus   }
Add comment 40 Plus  
Add comment 41 Plus   /// <summary>
Add comment 42 Plus   /// Extension to get the first item in a dictionary if the dictionary contains the key.
Add comment 43 Plus   /// </summary>
Add comment 44 Plus   /// <param name="dictionary">Dictionary to search.</param>
Add comment 45 Plus   /// <param name="keys">Collection of keys to find.</param>
Add comment 46 Plus   /// <returns>The value corresponding to the first of <paramref name="keys"/> found in <paramref name="dictionary"/>.</returns>
Add comment 47 Plus   public static string? FirstNotNullOrEmpty(this IDictionary<string, string?> dictionary, params string[] keys)
Add comment 48 Plus   {
Add comment 49 Plus   return keys
Add comment 50 Plus   .Where(key => dictionary.ContainsKey(key) && !string.IsNullOrEmpty(dictionary[key]))
Add comment 51 Plus   .Select(key => dictionary[key])
Add comment 52 Plus   .FirstOrDefault();
Add comment 53 Plus   }
Add comment 54 Plus  }
StringExtensions.cs
/src/Refactorius.Authentication/Core/StringExtensions.cs-128+18
/src/Refactorius.Authentication/Core/StringExtensions.cs
Add comment 1 Minus  using System;
Add comment 2 1 using System.Collections.Generic;
Add comment 3 Minus  using System.Data.Common;
Add comment 4 Minus  using System.Linq;
Add comment 5 Minus  using System.Security;
Add comment 6 2
Add comment 7 3 namespace Refactorius.Authentication.Core;
Add comment 8 4
Add comment 9 5 /// <summary>
Add comment 10 6 /// The locally useful extension methods.
Add comment 11 7 /// </summary>
Add comment 12 Minus  internal static class StringExtensions
Add comment 8 Plus  public static class AzureCredentialConfigExtensions
Add comment 13 9 {
Add comment 14 Minus   public static SecureString ToSecureString(this string s)
Add comment 15 Minus   {
Add comment 16 Minus   var secure = new SecureString();
Add comment 17 Minus   if (string.IsNullOrEmpty(s))
Add comment 18 Minus   return null;
Add comment 19 Minus  
Add comment 20 Minus   foreach (char c in s)
Add comment 21 Minus   {
Add comment 22 Minus   secure.AppendChar(c);
Add comment 23 Minus   }
Add comment 24 Minus  
Add comment 25 Minus   secure.MakeReadOnly();
Add comment 26 Minus   return secure;
Add comment 27 Minus   }
Add comment 28 Minus  
Add comment 29 Minus   public static string EnsureTrailingSlash(this string s)
Add comment 30 Minus   => s?.TrimEnd('/') + "/";
Add comment 31 Minus  
Add comment 32 Minus   public static Uri AsRootUri(this string url)
Add comment 33 Minus   {
Add comment 34 Minus   url.MustHaveText(nameof(url));
Add comment 35 Minus   return new Uri(url.EnsureTrailingSlash(), UriKind.Absolute);
Add comment 36 Minus   }
Add comment 37 Minus  
Add comment 10 Plus  #if NOT_USED
Add comment 38 11 /// <summary>
Add comment 39 12 /// Split a string into individual elements by the specified delimiter, where
Add comment 40 13 /// a delimiter enclosed within double-quotes '"' is considered to be part of the same
Add comment 43 16 /// <param name="input">Delimited string</param>
Add comment 44 17 /// <param name="delimiter">Element delimiter</param>
Add comment 45 18 /// <param name="quote">The quote character.</param>
Add comment 46 Minus   /// <returns>List of elements</returns>
Add comment 47 Minus   public static string[] SplitWithQuotes(this string input, char delimiter, char quote = '"')
Add comment 19 Plus   /// <returns>List of elements. It is empty if <paramref name="input"/> is <see langword="null"/> or empty.</returns>
Add comment 20 Plus   public static string[] SplitWithQuotes(this string? input, char delimiter, char quote = '"')
Add comment 48 21 {
Add comment 49 22 if (string.IsNullOrWhiteSpace(input))
Add comment 50 23 {
Add comment 85 58 /// <summary>
Add comment 86 59 /// Parse a delimited string of key-value pairs in to a dictionary.
Add comment 87 60 /// </summary>
Add comment 88 Minus   /// <param name="input">Delimited string of key-value pairs</param>
Add comment 89 Minus   /// <param name="delimiter">Character used as a delimiter between key-value pairs</param>
Add comment 61 Plus   /// <param name="input">Delimited string of key-value pairs.</param>
Add comment 62 Plus   /// <param name="delimiter">Character used as a delimiter between key-value pairs.</param>
Add comment 90 63 /// <param name="urlDecode">True to perform URL decoding of both the keys and values</param>
Add comment 91 Minus   /// <param name="lowercaseKeys">True to make all resulting keys lower-case</param>
Add comment 92 Minus   /// <param name="strict">Throw <see cref="ArgumentException"/> when the input string contains a malformed key-value pair</param>
Add comment 93 Minus   /// <exception cref="ArgumentException">Thrown if <paramref name="strict"/> is true and a malformed key-value pair is present in <paramref name="input"/></exception>
Add comment 94 Minus   /// <returns>Dictionary of string key-value pairs</returns>
Add comment 64 Plus   /// <param name="lowercaseKeys">True to lower-case resulting keys lower-case, otherwise upper-case.</param>
Add comment 65 Plus   /// <param name="strict">Throw <see cref="FormatException"/> when the input string contains a malformed key-value pair.</param>
Add comment 66 Plus   /// <exception cref="FormatException">Thrown if <paramref name="strict"/> is true and a malformed key-value pair is present in <paramref name="input"/>.</exception>
Add comment 67 Plus   /// <returns>Dictionary of string key-value pairs.</returns>
Add comment 95 68 public static Dictionary<string, string> ParseKeyValueList(this string input, char delimiter, bool urlDecode, bool lowercaseKeys,
Add comment 96 69 bool strict)
Add comment 97 70 {
Add comment 115 88 value = UrlDecode(value);
Add comment 116 89 }
Add comment 117 90
Add comment 118 Minus   if (lowercaseKeys)
Add comment 119 Minus   {
Add comment 120 Minus   key = key.Trim().ToLowerInvariant();
Add comment 121 Minus   }
Add comment 91 Plus   key = lowercaseKeys
Add comment 92 Plus   ? key.Trim().ToLowerInvariant()
Add comment 93 Plus   : key.Trim().ToUpperInvariant();
Add comment 122 94
Add comment 123 95 value = value.Trim().Trim(new[] {'\"'}).Trim();
Add comment 124 96
Add comment 126 98 }
Add comment 127 99 else if (strict && pair.Length > 2)
Add comment 128 100 {
Add comment 129 Minus   throw new ArgumentException(nameof(input));
Add comment 101 Plus   throw new FormatException(nameof(input));
Add comment 130 102 }
Add comment 131 103 }
Add comment 132 104
Add comment 133 105 return response;
Add comment 134 106 }
Add comment 135 107
Add comment 136 Minus   /// <summary>
Add comment 137 Minus   /// Decode the given URL encoded string.
Add comment 138 Minus   /// </summary>
Add comment 139 Minus   /// <param name="message">URL encoded string to decode</param>
Add comment 140 Minus   /// <returns>Decoded string</returns>
Add comment 141 Minus   /// <remarks>This method decodes "+" (as well as "%20") into the space character ' '.</remarks>
Add comment 142 Minus   public static string UrlDecode(this string message)
Add comment 143 Minus   {
Add comment 144 Minus   if (string.IsNullOrEmpty(message))
Add comment 145 Minus   return message;
Add comment 146 Minus  
Add comment 147 Minus   message = message.Replace("+", "%20");
Add comment 148 Minus   message = Uri.UnescapeDataString(message);
Add comment 149 Minus  
Add comment 150 Minus   return message;
Add comment 151 Minus   }
Add comment 152 Minus  
Add comment 153 Minus   /// <summary>
Add comment 154 Minus   /// Converts a ; separated string into a dictionary
Add comment 155 Minus   /// </summary>
Add comment 156 Minus   /// <param name="connectionString">String to parse</param>
Add comment 157 Minus   /// <returns>Dictionary of properties from the connection string</returns>
Add comment 158 Minus   public static IDictionary<string, string> ToConnectionStringDictionary(this string connectionString)
Add comment 159 Minus   {
Add comment 160 Minus   if (string.IsNullOrWhiteSpace(connectionString))
Add comment 161 Minus   return new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
Add comment 162 Minus  
Add comment 163 Minus   try
Add comment 164 Minus   {
Add comment 165 Minus   DbConnectionStringBuilder source = new DbConnectionStringBuilder
Add comment 166 Minus   {
Add comment 167 Minus   ConnectionString = connectionString
Add comment 168 Minus   };
Add comment 169 Minus  
Add comment 170 Minus   return source
Add comment 171 Minus   .Cast<KeyValuePair<string, object>>()
Add comment 172 Minus   .ToDictionary(
Add comment 173 Minus   kvp => kvp.Key,
Add comment 174 Minus   kvp =>
Add comment 175 Minus   kvp.Value?.ToString()?.Trim() ?? string.Empty);
Add comment 176 Minus   }
Add comment 177 Minus   catch
Add comment 178 Minus   {
Add comment 179 Minus   throw new FormatException("Invalid connection string format");
Add comment 180 Minus   }
Add comment 181 Minus   }
Add comment 182 Minus  
Add comment 183 Minus   /// <summary>
Add comment 184 Minus   /// Extension to get the first item in a dictionary if the dictionary contains the key.
Add comment 185 Minus   /// </summary>
Add comment 186 Minus   /// <param name="dictionary">Dictionary to search</param>
Add comment 187 Minus   /// <param name="keys">Collection of Keys to find.</param>
Add comment 188 Minus   /// <returns></returns>
Add comment 189 Minus   public static string FirstNotNullOrEmpty(this IDictionary<string, string> dictionary, params string[] keys)
Add comment 190 Minus   {
Add comment 191 Minus   return (
Add comment 192 Minus   from key in keys
Add comment 193 Minus   where dictionary.ContainsKey(key) && !string.IsNullOrEmpty(dictionary[key])
Add comment 194 Minus   select dictionary[key]).FirstOrDefault<string>();
Add comment 195 Minus   }
Add comment 196 Minus  
Add comment 197 108 public static AzureCredentialConfig ToAzureCredentialConfig(this string connectionString)
Add comment 198 109 {
Add comment 199 110 connectionString.MustHaveText(nameof(connectionString));
Add comment 200 Minus   return connectionString.ToConnectionStringDictionary().ToAzureCredentialConfig();
Add comment 111 Plus   return connectionString.ToConnectionStringDictionary(false).ToAzureCredentialConfig();
Add comment 201 112 }
Add comment 202 113
Add comment 203 Minus   public static AzureCredentialConfig ToAzureCredentialConfig(this IDictionary<string, string> connection)
Add comment 204 Minus   {
Add comment 205 Minus   return new AzureCredentialConfig()
Add comment 114 Plus   public static AzureCredentialConfig ToAzureCredentialConfig(this IDictionary<string, string> props)
Add comment 206 115 {
Add comment 207 Minus   Resource = connection.FirstNotNullOrEmpty(ConnectionStringConstants.ServiceUri),
Add comment 208 Minus   UserName = connection.FirstNotNullOrEmpty(ConnectionStringConstants.UserName),
Add comment 209 Minus   Password = connection.FirstNotNullOrEmpty(ConnectionStringConstants.Password),
Add comment 210 Minus   //connection.FirstNotNullOrEmpty(ConnectionStringConstants.Domain);
Add comment 211 Minus   //connection.FirstNotNullOrEmpty(ConnectionStringConstants.HomeRealmUri);
Add comment 212 Minus   //connection.FirstNotNullOrEmpty(ConnectionStringConstants.RequireNewInstance);
Add comment 213 Minus   ApplicationId = connection.FirstNotNullOrEmpty(ConnectionStringConstants.ClientId),
Add comment 214 Minus   //connection.FirstNotNullOrEmpty(ConnectionStringConstants.RedirectUri);
Add comment 215 Minus   //connection.FirstNotNullOrEmpty(ConnectionStringConstants.TokenCacheStorePath);
Add comment 216 Minus   //connection.FirstNotNullOrEmpty(ConnectionStringConstants.LoginPrompt);
Add comment 217 Minus   CertificatePath = connection.FirstNotNullOrEmpty(ConnectionStringConstants.CertStoreName),
Add comment 218 Minus   CertificateThumbprint = connection.FirstNotNullOrEmpty(ConnectionStringConstants.CertThumbprint),
Add comment 219 Minus   //connection.FirstNotNullOrEmpty(ConnectionStringConstants.SkipDiscovery);
Add comment 220 Minus   //connection.FirstNotNullOrEmpty(ConnectionStringConstants.IntegratedSecurity);
Add comment 221 Minus   ClientSecret = connection.FirstNotNullOrEmpty(ConnectionStringConstants.ClientSecret),
Add comment 222 Minus  
Add comment 223 Minus   TenantId = connection.FirstNotNullOrEmpty("TenantId"),
Add comment 224 Minus   CertificatePassword = connection.FirstNotNullOrEmpty("CertificatePassword"),
Add comment 225 Minus  
Add comment 226 Minus   // TODO: UserAgent, Scope
Add comment 227 Minus   };
Add comment 116 Plus   return new AzureCredentialConfig().SetFromProps(props);
Add comment 228 117 }
Add comment 118 Plus  #endif
Add comment 229 119 }
TaskExtensions.cs
/src/Refactorius.Authentication/Core/TaskExtensions.cs-1
/src/Refactorius.Authentication/Core/TaskExtensions.cs
Add comment 1 Minus  using System;
Add comment 2 1 using System.Linq;
Add comment 3 2 using System.Threading.Tasks;
Add comment 4 3
UrlStringExtensions.cs
/src/Refactorius.Authentication/Core/UrlStringExtensions.cs
/src/Refactorius.Authentication/Core/UrlStringExtensions.cs
AuthenticationTokenProvider.cs
/src/Refactorius.Authentication/AuthenticationTokenProvider.cs
/src/Refactorius.Authentication/AuthenticationTokenProvider.cs
AzureAuthenticationMethod.cs
/src/Refactorius.Authentication/AzureAuthenticationMethod.cs
/src/Refactorius.Authentication/AzureAuthenticationMethod.cs
AzureAuthenticationTokenProvider.cs
/src/Refactorius.Authentication/AzureAuthenticationTokenProvider.cs
/src/Refactorius.Authentication/AzureAuthenticationTokenProvider.cs
AzureCredentialConfig.cs
/src/Refactorius.Authentication/AzureCredentialConfig.cs
/src/Refactorius.Authentication/AzureCredentialConfig.cs
AzureCredentialSettings.cs
/src/Refactorius.Authentication/AzureCredentialSettings.cs
/src/Refactorius.Authentication/AzureCredentialSettings.cs
AzureTokenCredentialProvider.cs
/src/Refactorius.Authentication/AzureTokenCredentialProvider.cs
/src/Refactorius.Authentication/AzureTokenCredentialProvider.cs
CertificateProvider.cs
/src/Refactorius.Authentication/CertificateProvider.cs
/src/Refactorius.Authentication/CertificateProvider.cs
CertificateSettings.cs
/src/Refactorius.Authentication/CertificateSettings.cs
/src/Refactorius.Authentication/CertificateSettings.cs
ConnectionStringConstants.cs
/src/Refactorius.Authentication/ConnectionStringConstants.cs
/src/Refactorius.Authentication/ConnectionStringConstants.cs
GlobalUsings.cs
/src/Refactorius.Authentication/GlobalUsings.cs
/src/Refactorius.Authentication/GlobalUsings.cs
IAzureAuthenticationTokenProvider.cs
/src/Refactorius.Authentication/IAzureAuthenticationTokenProvider.cs
/src/Refactorius.Authentication/IAzureAuthenticationTokenProvider.cs
IRequestAuthenticationFactory.cs
/src/Refactorius.Authentication/IRequestAuthenticationFactory.cs
/src/Refactorius.Authentication/IRequestAuthenticationFactory.cs
IRequestAuthenticationProvider.cs
/src/Refactorius.Authentication/IRequestAuthenticationProvider.cs
/src/Refactorius.Authentication/IRequestAuthenticationProvider.cs
Refactorius.Authentication.csproj
/src/Refactorius.Authentication/Refactorius.Authentication.csproj
/src/Refactorius.Authentication/Refactorius.Authentication.csproj
RequestAuthenticationProviderExtensions.cs
/src/Refactorius.Authentication/RequestAuthenticationProviderExtensions.cs
/src/Refactorius.Authentication/RequestAuthenticationProviderExtensions.cs
Refactorius.Authentication.Tests.csproj
/tests/Refactorius.Authentication.Tests/Refactorius.Authentication.Tests.csproj
/tests/Refactorius.Authentication.Tests/Refactorius.Authentication.Tests.csproj
Refactorius.Authentication.sln.DotSettings
/Refactorius.Authentication.sln.DotSettings
/Refactorius.Authentication.sln.DotSettings