// Test that Secret shortcut access the actual backing value correctly. Vault pushes public void SecretVersion() { KV2SecretWrapper <KV2Secret> secretA = new KV2SecretWrapper <KV2Secret> { Secret = new KV2Secret("test", "/"), Version = 2 }; Assert.AreEqual(2, secretA.Version); Assert.AreEqual(2, secretA.Data.Metadata.Version); }
/// <summary> /// Reads the secret from Vault. It defaults to reading the most recent version. Set secretVersion to non zero to /// retrieve a /// specific version. /// <para>Returns [VaultForbiddenException] if you do not have permission to read from the path.</para> /// <para>Returns the IKV2SecretWrapper if a secret was found at the location.</para> /// <para>Returns Null if no secret found at location.</para> /// </summary> /// <param name="secretPath">The Name (path) to the secret you wish to read.</param> /// <param name="secretVersion">The version of the secret to retrieve. (Default) set to 0 to read most recent version. </param> /// <returns>IKV2Secret of the secret as read from Vault. Returns null if there is no secret at that path.</returns> public async Task <T> ReadSecret <T>(string secretPath, int secretVersion = 0) where T : KV2SecretBase <T> { string path = MountPointPath + "data/" + secretPath; Dictionary <string, string> contentParams = new Dictionary <string, string>(); // TODO - Read secret will return an object for a version that has been destroyed or deleted. We need to interrogate that // and try and find the next non deleted version. try { if (secretVersion > 0) { contentParams.Add("version", secretVersion.ToString()); } VaultDataResponseObjectB vdro = await ParentVault._httpConnector.GetAsync_B(path, "ReadSecret", contentParams); if (vdro.Success) { KV2SecretWrapper <T> secretReadReturnObj = await vdro.GetDotNetObject <KV2SecretWrapper <T> >(""); // We now need to move some fields from the IKV2SecretWrapper into the IKV2Secret which is embedded in the // wrapper class. secretReadReturnObj.Secret.CreatedTime = secretReadReturnObj.Data.Metadata.CreatedTime; secretReadReturnObj.Secret.DeletionTime = (DateTimeOffset)secretReadReturnObj.Data.Metadata.DeletionTime; secretReadReturnObj.Secret.IsDestroyed = secretReadReturnObj.Data.Metadata.Destroyed; secretReadReturnObj.Secret.Version = secretReadReturnObj.Data.Metadata.Version; // Now get the secret obj, remove it from the wrapper - so the class can be deleted and then return to caller. T secret = secretReadReturnObj.Secret; secretReadReturnObj.Secret = null; return(secret); } throw new ApplicationException("SecretBackEnd: ReadSecret - Arrived at an unexpected code path."); } // VaultInvalidPathExceptions are not permission problems - despite what the error text hints at. Instead they just mean no secret exists at that path. We return null. catch (VaultInvalidPathException) { return(null); } catch (VaultForbiddenException e) { if (e.Message.Contains("* permission denied")) { e.SpecificErrorCode = EnumVaultExceptionCodes.PermissionDenied; } throw e; } }