aboutsummaryrefslogtreecommitdiff
path: root/VNLib.Plugins.Extensions.Loading/VaultSecrets.cs
diff options
context:
space:
mode:
authorLibravatar vman <public@vaughnnugent.com>2022-12-28 14:15:04 -0500
committerLibravatar vman <public@vaughnnugent.com>2022-12-28 14:15:04 -0500
commit0c2fa662f60cf8b6b771fef3ff4c740eae17a83d (patch)
tree91495d460ceb12fba8cc274e77a8cbf4019c028d /VNLib.Plugins.Extensions.Loading/VaultSecrets.cs
parent8b5f3eebb9f8d9bd55e922a809ffa3bd52e33401 (diff)
Global cache client, asm loading, plugin local cache, and event managment
Diffstat (limited to 'VNLib.Plugins.Extensions.Loading/VaultSecrets.cs')
-rw-r--r--VNLib.Plugins.Extensions.Loading/VaultSecrets.cs100
1 files changed, 59 insertions, 41 deletions
diff --git a/VNLib.Plugins.Extensions.Loading/VaultSecrets.cs b/VNLib.Plugins.Extensions.Loading/VaultSecrets.cs
index 468600f..cd67903 100644
--- a/VNLib.Plugins.Extensions.Loading/VaultSecrets.cs
+++ b/VNLib.Plugins.Extensions.Loading/VaultSecrets.cs
@@ -26,10 +26,8 @@ using System;
using System.Linq;
using System.Text;
using System.Text.Json;
-using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
-using System.Runtime.CompilerServices;
using System.Security.Cryptography.X509Certificates;
using VaultSharp;
@@ -64,8 +62,6 @@ namespace VNLib.Plugins.Extensions.Loading
public const string VAULT_URL_SCHEME = "vault://";
- private static readonly ConditionalWeakTable<PluginBase, Lazy<IVaultClient?>> _vaults = new();
-
/// <summary>
/// <para>
/// Gets a secret from the "secrets" element.
@@ -135,7 +131,7 @@ namespace VNLib.Plugins.Extensions.Loading
async Task<SecretResult?> execute()
{
//Try load client
- IVaultClient? client = _vaults.GetValue(plugin, TryGetVaultLoader).Value;
+ IVaultClient? client = plugin.GetVault();
_ = client ?? throw new KeyNotFoundException("Vault client not found");
//run read async
@@ -209,7 +205,7 @@ namespace VNLib.Plugins.Extensions.Loading
async Task<X509Certificate?> execute()
{
//Try load client
- IVaultClient? client = _vaults.GetValue(plugin, TryGetVaultLoader).Value;
+ IVaultClient? client = plugin.GetVault();
_ = client ?? throw new KeyNotFoundException("Vault client not found");
@@ -239,7 +235,7 @@ namespace VNLib.Plugins.Extensions.Loading
/// <returns>The ambient <see cref="IVaultClient"/> if loaded, null otherwise</returns>
/// <exception cref="KeyNotFoundException"></exception>
/// <exception cref="ObjectDisposedException"></exception>
- public static IVaultClient? GetVault(this PluginBase plugin) => _vaults.GetValue(plugin, TryGetVaultLoader).Value;
+ public static IVaultClient? GetVault(this PluginBase plugin) => LoadingExtensions.GetOrCreateSingleton(plugin, TryGetVaultLoader);
private static string? TryGetSecretInternal(PluginBase plugin, string secretName)
{
@@ -283,47 +279,41 @@ namespace VNLib.Plugins.Extensions.Loading
return conf != null && conf.TryGetValue(secretName, out JsonElement el) ? el.GetString() : null;
}
- private static Lazy<IVaultClient?> TryGetVaultLoader(PluginBase pbase)
+ private static IVaultClient? TryGetVaultLoader(PluginBase pbase)
{
- //Local func to load the vault client
- IVaultClient? LoadVault()
+ //Get vault config
+ IReadOnlyDictionary<string, JsonElement>? conf = pbase.TryGetConfig(VAULT_OBJECT_NAME);
+
+ if (conf == null)
{
- //Get vault config
- IReadOnlyDictionary<string, JsonElement>? conf = pbase.TryGetConfig(VAULT_OBJECT_NAME);
+ return null;
+ }
- if(conf == null)
- {
- return null;
- }
+ //try get servre address creds from config
+ string? serverAddress = conf[VAULT_URL_KEY].GetString() ?? throw new KeyNotFoundException($"Failed to load the key {VAULT_URL_KEY} from object {VAULT_OBJECT_NAME}");
- //try get servre address creds from config
- string? serverAddress = conf[VAULT_URL_KEY].GetString() ?? throw new KeyNotFoundException($"Failed to load the key {VAULT_URL_KEY} from object {VAULT_OBJECT_NAME}");
+ IAuthMethodInfo authMethod;
- IAuthMethodInfo authMethod;
+ //Get authentication method from config
+ if (conf.TryGetValue(VAULT_TOKEN_KEY, out JsonElement tokenEl))
+ {
+ //Init token
+ authMethod = new TokenAuthMethodInfo(tokenEl.GetString());
+ }
+ else if (conf.TryGetValue(VAULT_ROLE_KEY, out JsonElement roleEl) && conf.TryGetValue(VAULT_SECRET_KEY, out JsonElement secretEl))
+ {
+ authMethod = new AppRoleAuthMethodInfo(roleEl.GetString(), secretEl.GetString());
+ }
+ else
+ {
+ throw new KeyNotFoundException($"Failed to load the vault authentication method from {VAULT_OBJECT_NAME}");
+ }
- //Get authentication method from config
- if (conf.TryGetValue(VAULT_TOKEN_KEY, out JsonElement tokenEl))
- {
- //Init token
- authMethod = new TokenAuthMethodInfo(tokenEl.GetString());
- }
- else if(conf.TryGetValue(VAULT_ROLE_KEY, out JsonElement roleEl) && conf.TryGetValue(VAULT_SECRET_KEY, out JsonElement secretEl))
- {
- authMethod = new AppRoleAuthMethodInfo(roleEl.GetString(), secretEl.GetString());
- }
- else
- {
- throw new KeyNotFoundException($"Failed to load the vault authentication method from {VAULT_OBJECT_NAME}");
- }
+ //Settings
+ VaultClientSettings settings = new(serverAddress, authMethod);
- //Settings
- VaultClientSettings settings = new(serverAddress, authMethod);
-
- //create vault client
- return new VaultClient(settings);
- }
- //init lazy
- return new (LoadVault, LazyThreadSafetyMode.PublicationOnly);
+ //create vault client
+ return new VaultClient(settings);
}
/// <summary>
@@ -355,6 +345,20 @@ namespace VNLib.Plugins.Extensions.Loading
}
/// <summary>
+ /// Converts the secret recovery task to
+ /// </summary>
+ /// <param name="secret"></param>
+ /// <returns>A task whos result the base64 decoded secret as a byte[]</returns>
+ /// <exception cref="ArgumentNullException"></exception>
+ /// <exception cref="InternalBufferTooSmallException"></exception>
+ public static async Task<byte[]?> ToBase64Bytes(this Task<SecretResult?> secret)
+ {
+ _ = secret ?? throw new ArgumentNullException(nameof(secret));
+ using SecretResult? sec = await secret.ConfigureAwait(false);
+ return sec?.GetFromBase64();
+ }
+
+ /// <summary>
/// Recovers a certificate from a PEM encoded secret
/// </summary>
/// <param name="secret"></param>
@@ -431,5 +435,19 @@ namespace VNLib.Plugins.Extensions.Loading
int count = Encoding.UTF8.GetBytes(secret.Result, buffer.Span);
return new ReadOnlyJsonWebKey(buffer.Span[..count]);
}
+
+ /// <summary>
+ /// Gets a task that resolves a <see cref="ReadOnlyJsonWebKey"/>
+ /// from a <see cref="SecretResult"/> task
+ /// </summary>
+ /// <param name="secret"></param>
+ /// <returns>The <see cref="ReadOnlyJsonWebKey"/> from the secret, or null if the secret was not found</returns>
+ /// <exception cref="ArgumentNullException"></exception>
+ public static async Task<ReadOnlyJsonWebKey?> ToJsonWebKey(this Task<SecretResult?> secret)
+ {
+ _ = secret ?? throw new ArgumentNullException(nameof(secret));
+ using SecretResult? sec = await secret.ConfigureAwait(false);
+ return sec?.GetJsonWebKey();
+ }
}
}