Skip to content

Commit

Permalink
totp examples
Browse files Browse the repository at this point in the history
  • Loading branch information
rajanadar committed Jan 23, 2023
1 parent 7fb4c0a commit 8e39258
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 60 deletions.
78 changes: 39 additions & 39 deletions src/VaultSharp/V1/SecretsEngines/TOTP/ITOTPSecretsEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,45 +8,6 @@ namespace VaultSharp.V1.SecretsEngines.TOTP
/// </summary>
public interface ITOTPSecretsEngine
{
/// <summary>
/// Generates a new time-based one-time use password based on the named key.
/// </summary>
/// <param name="keyName"><para>[required]</para>
/// Specifies the name of the key to create credentials against.
/// </param>
/// <param name="mountPoint"><para>[optional]</para>
/// The mount point for the TOTP backend. Defaults to <see cref="SecretsEngineMountPoints.TOTP" />
/// Provide a value only if you have customized the TOTP mount point.</param>
/// <param name="wrapTimeToLive">
/// <para>[optional]</para>
/// The TTL for the token and can be either an integer number of seconds or a string duration of seconds.
/// </param>
/// <returns>
/// The secret with the <see cref="TOTPCode" /> as the data.
/// </returns>
Task<Secret<TOTPCode>> GetCodeAsync(string keyName, string mountPoint = null, string wrapTimeToLive = null);

/// <summary>
/// Generates a new time-based one-time use password based on the named key.
/// </summary>
/// <param name="keyName"><para>[required]</para>
/// Specifies the name of the key to create credentials against.
/// </param>
/// <param name="code"><para>[required]</para>
/// Specifies the the password you want to validate.
/// </param>
/// <param name="mountPoint"><para>[optional]</para>
/// The mount point for the TOTP backend. Defaults to <see cref="SecretsEngineMountPoints.TOTP" />
/// Provide a value only if you have customized the TOTP mount point.</param>
/// <param name="wrapTimeToLive">
/// <para>[optional]</para>
/// The TTL for the token and can be either an integer number of seconds or a string duration of seconds.
/// </param>
/// <returns>
/// The secret with the <see cref="TOTPCode" /> as the data.
/// </returns>
Task<Secret<TOTPCodeValidity>> ValidateCodeAsync(string keyName, string code, string mountPoint = null, string wrapTimeToLive = null);

/// <summary>
/// This endpoint creates or updates a key definition.
/// </summary>
Expand Down Expand Up @@ -101,5 +62,44 @@ public interface ITOTPSecretsEngine
/// The mount point for the TOTP backend. Defaults to <see cref="SecretsEngineMountPoints.TOTP" />
/// Provide a value only if you have customized the TOTP mount point.</param>
Task DeleteKeyAsync(string keyName, string mountPoint = null);

/// <summary>
/// Generates a new time-based one-time use password based on the named key.
/// </summary>
/// <param name="keyName"><para>[required]</para>
/// Specifies the name of the key to create credentials against.
/// </param>
/// <param name="mountPoint"><para>[optional]</para>
/// The mount point for the TOTP backend. Defaults to <see cref="SecretsEngineMountPoints.TOTP" />
/// Provide a value only if you have customized the TOTP mount point.</param>
/// <param name="wrapTimeToLive">
/// <para>[optional]</para>
/// The TTL for the token and can be either an integer number of seconds or a string duration of seconds.
/// </param>
/// <returns>
/// The secret with the <see cref="TOTPCode" /> as the data.
/// </returns>
Task<Secret<TOTPCode>> GetCodeAsync(string keyName, string mountPoint = null, string wrapTimeToLive = null);

/// <summary>
/// Generates a new time-based one-time use password based on the named key.
/// </summary>
/// <param name="keyName"><para>[required]</para>
/// Specifies the name of the key to create credentials against.
/// </param>
/// <param name="code"><para>[required]</para>
/// Specifies the the password you want to validate.
/// </param>
/// <param name="mountPoint"><para>[optional]</para>
/// The mount point for the TOTP backend. Defaults to <see cref="SecretsEngineMountPoints.TOTP" />
/// Provide a value only if you have customized the TOTP mount point.</param>
/// <param name="wrapTimeToLive">
/// <para>[optional]</para>
/// The TTL for the token and can be either an integer number of seconds or a string duration of seconds.
/// </param>
/// <returns>
/// The secret with the <see cref="TOTPCode" /> as the data.
/// </returns>
Task<Secret<TOTPCodeValidity>> ValidateCodeAsync(string keyName, string code, string mountPoint = null, string wrapTimeToLive = null);
}
}
7 changes: 2 additions & 5 deletions src/VaultSharp/V1/SecretsEngines/TOTP/TOTPKey.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json;

namespace VaultSharp.V1.SecretsEngines.TOTP
{
Expand Down Expand Up @@ -40,6 +37,6 @@ public class TOTPKey
/// create a counter for the TOTP code calculation.
/// </summary>
[JsonProperty("period")]
public string Period { get; set; }
public long Period { get; set; }
}
}
32 changes: 16 additions & 16 deletions src/VaultSharp/V1/SecretsEngines/TOTP/TOTPSecretsEngineProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,6 @@ public TOTPSecretsEngineProvider(Polymath polymath)
_polymath = polymath;
}

public async Task<Secret<TOTPCode>> GetCodeAsync(string keyName, string mountPoint = null, string wrapTimeToLive = null)
{
Checker.NotNull(keyName, "keyName");

return await _polymath.MakeVaultApiRequest<Secret<TOTPCode>>(mountPoint ?? _polymath.VaultClientSettings.SecretsEngineMountPoints.TOTP, "/code/" + keyName.Trim('/'), HttpMethod.Get, wrapTimeToLive: wrapTimeToLive).ConfigureAwait(_polymath.VaultClientSettings.ContinueAsyncTasksOnCapturedContext);
}

public async Task<Secret<TOTPCodeValidity>> ValidateCodeAsync(string keyName, string code, string mountPoint = null, string wrapTimeToLive = null)
{
Checker.NotNull(keyName, "keyName");
Checker.NotNull(code, "code");

var requestData = new { code = code };
return await _polymath.MakeVaultApiRequest<Secret<TOTPCodeValidity>>(mountPoint ?? _polymath.VaultClientSettings.SecretsEngineMountPoints.TOTP, "/code/" + keyName.Trim('/'), HttpMethod.Post, requestData, wrapTimeToLive: wrapTimeToLive).ConfigureAwait(_polymath.VaultClientSettings.ContinueAsyncTasksOnCapturedContext);
}

public async Task<Secret<TOTPCreateKeyResponse>> CreateKeyAsync(string keyName, TOTPCreateKeyRequest createKeyRequest, string mountPoint)
{
Checker.NotNull(keyName, "keyName");
Expand Down Expand Up @@ -95,5 +79,21 @@ public async Task DeleteKeyAsync(string keyName, string mountPoint = null)

await _polymath.MakeVaultApiRequest(mountPoint ?? _polymath.VaultClientSettings.SecretsEngineMountPoints.TOTP, "/keys/" + keyName.Trim('/'), HttpMethod.Delete).ConfigureAwait(_polymath.VaultClientSettings.ContinueAsyncTasksOnCapturedContext);
}

public async Task<Secret<TOTPCode>> GetCodeAsync(string keyName, string mountPoint = null, string wrapTimeToLive = null)
{
Checker.NotNull(keyName, "keyName");

return await _polymath.MakeVaultApiRequest<Secret<TOTPCode>>(mountPoint ?? _polymath.VaultClientSettings.SecretsEngineMountPoints.TOTP, "/code/" + keyName.Trim('/'), HttpMethod.Get, wrapTimeToLive: wrapTimeToLive).ConfigureAwait(_polymath.VaultClientSettings.ContinueAsyncTasksOnCapturedContext);
}

public async Task<Secret<TOTPCodeValidity>> ValidateCodeAsync(string keyName, string code, string mountPoint = null, string wrapTimeToLive = null)
{
Checker.NotNull(keyName, "keyName");
Checker.NotNull(code, "code");

var requestData = new { code = code };
return await _polymath.MakeVaultApiRequest<Secret<TOTPCodeValidity>>(mountPoint ?? _polymath.VaultClientSettings.SecretsEngineMountPoints.TOTP, "/code/" + keyName.Trim('/'), HttpMethod.Post, requestData, wrapTimeToLive: wrapTimeToLive).ConfigureAwait(_polymath.VaultClientSettings.ContinueAsyncTasksOnCapturedContext);
}
}
}
110 changes: 110 additions & 0 deletions test/VaultSharp.Samples/Backends/Secrets/TOTPSecretsBackendSamples.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
using System.Linq;
using System;
using Xunit;
using VaultSharp.V1.SecretsEngines;
using VaultSharp.V1.SecretsEngines.TOTP;

namespace VaultSharp.Samples
{
partial class Program
{
private static void RunTOTPSecretsBackendSamples()
{
var mountPoint = Guid.NewGuid().ToString();

var totpSecretsEngine = new SecretsEngine
{
Type = SecretsEngineType.TOTP,
Path = mountPoint
};

_authenticatedVaultClient.V1.System.MountSecretBackendAsync(totpSecretsEngine).Wait();

// Create key 1

var keyName = Guid.NewGuid().ToString();
var createKeyRequest = new TOTPCreateKeyRequest()
{
KeyGenerationOption = new TOTPVaultBasedKeyGeneration
{
Exported = true,
KeySize = 32,
Issuer = "raja-issuer",
AccountName = "raja-account-name",
QRSize = 200,
Skew = 1
},
AccountName = "raja-account-name",
Algorithm = "SHA512",
Issuer = "raja-issuer"
};

var createKeyResponse = _authenticatedVaultClient.V1.Secrets.TOTP.CreateKeyAsync(keyName, createKeyRequest, mountPoint).Result;
DisplayJson(createKeyResponse);
Assert.NotNull(createKeyResponse.Data.Url);
Assert.NotNull(createKeyResponse.Data.Barcode);

// Read key 1

var retrievedKey = _authenticatedVaultClient.V1.Secrets.TOTP.ReadKeyAsync(keyName, mountPoint).Result;
DisplayJson(retrievedKey);
Assert.Equal(createKeyRequest.AccountName, retrievedKey.Data.AccountName);

// Create key 2

var keyName2 = Guid.NewGuid().ToString();
var createKeyRequest2 = new TOTPCreateKeyRequest()
{
KeyGenerationOption = new TOTPVaultBasedKeyGeneration
{
Exported = true,
KeySize = 64,
Issuer = "raja-issuer2",
AccountName = "raja-account-name2",
QRSize = 200,
Skew = 0
},
AccountName = "raja-account-name2",
Algorithm = "SHA256",
Issuer = "raja-issuer2"

};

var createKeyResponse2 = _authenticatedVaultClient.V1.Secrets.TOTP.CreateKeyAsync(keyName2, createKeyRequest2, mountPoint).Result;
DisplayJson(createKeyResponse2);
Assert.NotNull(createKeyResponse2.Data.Url);
Assert.NotNull(createKeyResponse2.Data.Barcode);

// Read all keys

var allKeys = _authenticatedVaultClient.V1.Secrets.TOTP.ReadAllKeysAsync(mountPoint).Result;
DisplayJson(allKeys);
Assert.True(allKeys.Data.Keys.Count() == 2);

// Delete key 2

_authenticatedVaultClient.V1.Secrets.TOTP.DeleteKeyAsync(keyName2, mountPoint).Wait();
allKeys = _authenticatedVaultClient.V1.Secrets.TOTP.ReadAllKeysAsync(mountPoint).Result;
DisplayJson(allKeys);
Assert.True(allKeys.Data.Keys.Count() == 1);

// generate code
var generatedCode = _authenticatedVaultClient.V1.Secrets.TOTP.GetCodeAsync(keyName, mountPoint).Result;
DisplayJson(generatedCode);
Assert.NotNull(generatedCode.Data.Code);

// validate code
var validResponse = _authenticatedVaultClient.V1.Secrets.TOTP.ValidateCodeAsync(keyName, generatedCode.Data.Code, mountPoint).Result;
DisplayJson(validResponse);
Assert.True(validResponse.Data.Valid);

var invalidResponse = _authenticatedVaultClient.V1.Secrets.TOTP.ValidateCodeAsync(keyName, generatedCode.Data.Code + "2", mountPoint).Result;
DisplayJson(invalidResponse);
Assert.False(invalidResponse.Data.Valid);

// unmount

_authenticatedVaultClient.V1.System.UnmountSecretBackendAsync(mountPoint).Wait();
}
}
}
3 changes: 3 additions & 0 deletions test/VaultSharp.Samples/Backends/SecretsBackendSamples.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ private static void RunSecretsEngineSamples()
Console.WriteLine("\n RunKeyValueSecretsBackendSamples \n");
RunKeyValueSecretsBackendSamples();

Console.WriteLine("\n RunTOTPSecretsBackendSamples \n");
RunTOTPSecretsBackendSamples();

Console.WriteLine("\n RunTransitSecretsBackendSamples \n");
RunTransitSecretsBackendSamples();
}
Expand Down

0 comments on commit 8e39258

Please sign in to comment.