diff --git a/CHANGELOG.md b/CHANGELOG.md index 64ba8548..276e51a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ **ENTERPRISE VAULT FEATURES:** * [GH-122] Add support for ```KMIP``` Secrets Engine. + * [GH-129] Add support for ```Transform``` Secrets Engine. **BREAKING CHANGES:** diff --git a/README.md b/README.md index bc22c6fd..139738ae 100644 --- a/README.md +++ b/README.md @@ -1019,6 +1019,54 @@ This endpoint deletes the key definition. await vaultClient.V1.Secrets.TOTP.DeleteKeyAsync(keyName); ``` +#### Transform Secrets Engine + +##### Encode Method + +###### Encode Single Item + +```cs + +var encodeOptions = new EncodeRequestOptions { Value = "ipsem" }; +Secret response = await _authenticatedVaultClient.V1.Secrets.Transit.EncodeAsync(roleName, encodeOptions); +response.Data.EncodedText; + +``` + +###### Encode Batched Items + +```cs +var encodeOptions = new EncodeRequestOptions +{ + BatchItems = new List { new EncodingItem { Value = "ipsem1" }, new EncodingItem { Value = "ipsem2" } } +}; + +Secret response = await _authenticatedVaultClient.V1.Secrets.Transit.EncodeAsync(roleName, encodeOptions); +response.Data.BatchResults; +``` + +##### Decode Method + +###### Decode Single Item + +```cs +var decodeOptions = new DecodeRequestOptions { Value = "ipsem" }; +Secret response = await _authenticatedVaultClient.V1.Secrets.Transit.DecodeAsync(roleName, decodeOptions); +response.Data.DecodedText; +``` + +###### Decode Batched Item + +```cs +var decodeOptions = new DecodeRequestOptions +{ + BatchItems = new List { new DecodingItem { Value = "ipsem1" }, new DecodingItem { Value = "ipsem2" } } +}; + +Secret response = await _authenticatedVaultClient.V1.Secrets.Transit.DecodeAsync(roleName, decodeOptions); +response.Data.BatchResults; +``` + #### Transit Secrets Engine ##### Encrypt Method diff --git a/src/VaultSharp/V1/SecretsEngines/ISecretsEngine.cs b/src/VaultSharp/V1/SecretsEngines/ISecretsEngine.cs index 2c0eeed4..1cd070c9 100644 --- a/src/VaultSharp/V1/SecretsEngines/ISecretsEngine.cs +++ b/src/VaultSharp/V1/SecretsEngines/ISecretsEngine.cs @@ -17,6 +17,7 @@ using VaultSharp.V1.SecretsEngines.RabbitMQ; using VaultSharp.V1.SecretsEngines.SSH; using VaultSharp.V1.SecretsEngines.TOTP; +using VaultSharp.V1.SecretsEngines.Transform; using VaultSharp.V1.SecretsEngines.Transit; namespace VaultSharp.V1.SecretsEngines @@ -121,6 +122,11 @@ public interface ISecretsEngine /// ITOTPSecretsEngine TOTP { get; } + /// + /// The Transform Secrets Engine. + /// + ITransformSecretsEngine Transform { get; } + /// /// The Transit Secrets Engine. /// diff --git a/src/VaultSharp/V1/SecretsEngines/SecretsEngineDefaultPaths.cs b/src/VaultSharp/V1/SecretsEngines/SecretsEngineDefaultPaths.cs index 8f41cdab..ab8ffc44 100644 --- a/src/VaultSharp/V1/SecretsEngines/SecretsEngineDefaultPaths.cs +++ b/src/VaultSharp/V1/SecretsEngines/SecretsEngineDefaultPaths.cs @@ -24,6 +24,7 @@ public class SecretsEngineDefaultPaths public const string RabbitMQ = "rabbitmq"; public const string SSH = "ssh"; public const string TOTP = "totp"; + public const string Transform = "transform"; public const string Transit = "transit"; public const string Cassandra = "cassandra"; diff --git a/src/VaultSharp/V1/SecretsEngines/SecretsEngineProvider.cs b/src/VaultSharp/V1/SecretsEngines/SecretsEngineProvider.cs index 731b8587..e5f29eb2 100644 --- a/src/VaultSharp/V1/SecretsEngines/SecretsEngineProvider.cs +++ b/src/VaultSharp/V1/SecretsEngines/SecretsEngineProvider.cs @@ -18,6 +18,7 @@ using VaultSharp.V1.SecretsEngines.RabbitMQ; using VaultSharp.V1.SecretsEngines.SSH; using VaultSharp.V1.SecretsEngines.TOTP; +using VaultSharp.V1.SecretsEngines.Transform; using VaultSharp.V1.SecretsEngines.Transit; namespace VaultSharp.V1.SecretsEngines @@ -45,6 +46,7 @@ public SecretsEngineProvider(Polymath polymath) RabbitMQ = new RabbitMQSecretsEngineProvider(polymath); SSH = new SSHSecretsEngineProvider(polymath); TOTP = new TOTPSecretsEngineProvider(polymath); + Transform = new TransformSecretsEngineProvider(polymath); Transit = new TransitSecretsEngineProvider(polymath); } @@ -86,6 +88,8 @@ public SecretsEngineProvider(Polymath polymath) public ITOTPSecretsEngine TOTP { get; } + public ITransformSecretsEngine Transform { get; } + public ITransitSecretsEngine Transit { get; } } } \ No newline at end of file diff --git a/src/VaultSharp/V1/SecretsEngines/Transform/DecodeRequestOptions.cs b/src/VaultSharp/V1/SecretsEngines/Transform/DecodeRequestOptions.cs new file mode 100644 index 00000000..7d86d192 --- /dev/null +++ b/src/VaultSharp/V1/SecretsEngines/Transform/DecodeRequestOptions.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace VaultSharp.V1.SecretsEngines.Transform +{ + /// + /// Represents the Decode Request Options. + /// + public class DecodeRequestOptions : DecodingItem + { + /// + /// Specifies the transformation within the role that should be used for this decode operation. + /// If a single transformation exists for role, this parameter may be skipped and will be inferred. + /// If multiple transformations exist, one must be specified. + /// + [JsonProperty("batch_input")] + public List BatchItems { get; set; } + } +} \ No newline at end of file diff --git a/src/VaultSharp/V1/SecretsEngines/Transform/DecodedItem.cs b/src/VaultSharp/V1/SecretsEngines/Transform/DecodedItem.cs new file mode 100644 index 00000000..47dc41b2 --- /dev/null +++ b/src/VaultSharp/V1/SecretsEngines/Transform/DecodedItem.cs @@ -0,0 +1,22 @@ +using Newtonsoft.Json; + +namespace VaultSharp.V1.SecretsEngines.Transform +{ + /// + /// Represents a single Decoded item. + /// + public class DecodedItem + { + /// + /// Specifies the decoded value. + /// + [JsonProperty("decoded_value")] + public string DecodedValue { get; set; } + + /// + /// Specifies the base64 encoded tweak that was provided during encoding. + /// + [JsonProperty("tweak")] + public string Tweak { get; set; } + } +} \ No newline at end of file diff --git a/src/VaultSharp/V1/SecretsEngines/Transform/DecodedResponse.cs b/src/VaultSharp/V1/SecretsEngines/Transform/DecodedResponse.cs new file mode 100644 index 00000000..99eae8c5 --- /dev/null +++ b/src/VaultSharp/V1/SecretsEngines/Transform/DecodedResponse.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace VaultSharp.V1.SecretsEngines.Transform +{ + /// + /// Response for decoding. + /// + public class DecodedResponse : DecodedItem + { + /// + /// Decoded items. + /// + [JsonProperty("batch_results")] + public List DecodedItems { get; set; } + } +} \ No newline at end of file diff --git a/src/VaultSharp/V1/SecretsEngines/Transform/DecodingItem.cs b/src/VaultSharp/V1/SecretsEngines/Transform/DecodingItem.cs new file mode 100644 index 00000000..3881b6dd --- /dev/null +++ b/src/VaultSharp/V1/SecretsEngines/Transform/DecodingItem.cs @@ -0,0 +1,31 @@ +using Newtonsoft.Json; + +namespace VaultSharp.V1.SecretsEngines.Transform +{ + /// + /// Represents a single Decoding item. + /// + public class DecodingItem + { + /// + /// Specifies the value to be decoded. + /// + [JsonProperty("value")] + public string Value { get; set; } + + /// + /// Specifies the transformation within the role that should be used for this decode operation. + /// If a single transformation exists for role, this parameter may be skipped and will be inferred. + /// If multiple transformations exist, one must be specified. + /// + [JsonProperty("transformation")] + public string Transformation { get; set; } + + /// + /// Specifies the base64 decoded tweak to use. + /// Only applicable for FPE transformations with supplied as the tweak source. + /// + [JsonProperty("tweak")] + public string Tweak { get; set; } + } +} \ No newline at end of file diff --git a/src/VaultSharp/V1/SecretsEngines/Transform/EncodeRequestOptions.cs b/src/VaultSharp/V1/SecretsEngines/Transform/EncodeRequestOptions.cs new file mode 100644 index 00000000..6838f314 --- /dev/null +++ b/src/VaultSharp/V1/SecretsEngines/Transform/EncodeRequestOptions.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace VaultSharp.V1.SecretsEngines.Transform +{ + /// + /// Represents the Encode Request Options. + /// + public class EncodeRequestOptions : EncodingItem + { + /// + /// Specifies a list of items to be encoded in a single batch. + /// When this parameter is set, the 'value', 'transformation' and 'tweak' parameters are ignored. + /// Instead, the aforementioned parameters should be provided within each object in the list. + /// + [JsonProperty("batch_input")] + public List BatchItems { get; set; } + } +} \ No newline at end of file diff --git a/src/VaultSharp/V1/SecretsEngines/Transform/EncodedItem.cs b/src/VaultSharp/V1/SecretsEngines/Transform/EncodedItem.cs new file mode 100644 index 00000000..f7974497 --- /dev/null +++ b/src/VaultSharp/V1/SecretsEngines/Transform/EncodedItem.cs @@ -0,0 +1,22 @@ +using Newtonsoft.Json; + +namespace VaultSharp.V1.SecretsEngines.Transform +{ + /// + /// Represents a single Encoded item. + /// + public class EncodedItem + { + /// + /// Specifies the encoded value. + /// + [JsonProperty("encoded_value")] + public string EncodedValue { get; set; } + + /// + /// Specifies the base64 encoded tweak that was provided during encoding. + /// + [JsonProperty("tweak")] + public string Tweak { get; set; } + } +} \ No newline at end of file diff --git a/src/VaultSharp/V1/SecretsEngines/Transform/EncodedResponse.cs b/src/VaultSharp/V1/SecretsEngines/Transform/EncodedResponse.cs new file mode 100644 index 00000000..6f212980 --- /dev/null +++ b/src/VaultSharp/V1/SecretsEngines/Transform/EncodedResponse.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace VaultSharp.V1.SecretsEngines.Transform +{ + /// + /// Response for encoding. + /// + public class EncodedResponse : EncodedItem + { + /// + /// Encoded items. + /// + [JsonProperty("batch_results")] + public List EncodedItems { get; set; } + } +} \ No newline at end of file diff --git a/src/VaultSharp/V1/SecretsEngines/Transform/EncodingItem.cs b/src/VaultSharp/V1/SecretsEngines/Transform/EncodingItem.cs new file mode 100644 index 00000000..e3185d24 --- /dev/null +++ b/src/VaultSharp/V1/SecretsEngines/Transform/EncodingItem.cs @@ -0,0 +1,31 @@ +using Newtonsoft.Json; + +namespace VaultSharp.V1.SecretsEngines.Transform +{ + /// + /// Represents a single Encoding item. + /// + public class EncodingItem + { + /// + /// Specifies the value to be encoded. + /// + [JsonProperty("value")] + public string Value { get; set; } + + /// + /// Specifies the transformation within the role that should be used for this encode operation. + /// If a single transformation exists for role, this parameter may be skipped and will be inferred. + /// If multiple transformations exist, one must be specified. + /// + [JsonProperty("transformation")] + public string Transformation { get; set; } + + /// + /// Specifies the base64 encoded tweak to use. + /// Only applicable for FPE transformations with supplied as the tweak source. + /// + [JsonProperty("tweak")] + public string Tweak { get; set; } + } +} \ No newline at end of file diff --git a/src/VaultSharp/V1/SecretsEngines/Transform/ITransformSecretsEngine.cs b/src/VaultSharp/V1/SecretsEngines/Transform/ITransformSecretsEngine.cs new file mode 100644 index 00000000..8b02b54e --- /dev/null +++ b/src/VaultSharp/V1/SecretsEngines/Transform/ITransformSecretsEngine.cs @@ -0,0 +1,57 @@ +using System.Threading.Tasks; +using VaultSharp.V1.Commons; + +namespace VaultSharp.V1.SecretsEngines.Transform +{ + /// + /// The Transform Secrets Engine. + /// + public interface ITransformSecretsEngine + { + /// + /// This endpoint encodes the provided value using a named role. + /// + /// + /// [required] + /// Specifies the role name to use for this operation. + /// + /// [required] + /// The options. + /// + /// [optional] + /// The mount point for the Transform backend. Defaults to + /// Provide a value only if you have customized the mount point. + /// + /// + /// [optional] + /// The TTL for the token and can be either an integer number of seconds or a string duration of seconds. + /// + /// + /// The secret with encoded text. + /// + Task> EncodeAsync(string roleName, EncodeRequestOptions encodeRequestOptions, string mountPoint = SecretsEngineDefaultPaths.Transform, string wrapTimeToLive = null); + + /// + /// This endpoint decodes the provided value using a named role. + /// + /// + /// [required] + /// Specifies the role name to use for this operation. + /// + /// [required] + /// The options. + /// + /// [optional] + /// The mount point for the Transform backend. Defaults to + /// Provide a value only if you have customized the mount point. + /// + /// + /// [optional] + /// The TTL for the token and can be either an integer number of seconds or a string duration of seconds. + /// + /// + /// The secret with decoded text. + /// + Task> DecodeAsync(string roleName, DecodeRequestOptions decodeRequestOptions, string mountPoint = SecretsEngineDefaultPaths.Transform, string wrapTimeToLive = null); + } +} \ No newline at end of file diff --git a/src/VaultSharp/V1/SecretsEngines/Transform/TransformSecretsEngineProvider.cs b/src/VaultSharp/V1/SecretsEngines/Transform/TransformSecretsEngineProvider.cs new file mode 100644 index 00000000..41a191cd --- /dev/null +++ b/src/VaultSharp/V1/SecretsEngines/Transform/TransformSecretsEngineProvider.cs @@ -0,0 +1,33 @@ +using System.Net.Http; +using System.Threading.Tasks; +using VaultSharp.Core; +using VaultSharp.V1.Commons; + +namespace VaultSharp.V1.SecretsEngines.Transform +{ + internal class TransformSecretsEngineProvider : ITransformSecretsEngine + { + private readonly Polymath _polymath; + + public TransformSecretsEngineProvider(Polymath polymath) + { + _polymath = polymath; + } + + public async Task> EncodeAsync(string roleName, EncodeRequestOptions encodeRequestOptions, string mountPoint = "transform", string wrapTimeToLive = null) + { + Checker.NotNull(roleName, "roleName"); + Checker.NotNull(encodeRequestOptions, "encodeRequestOptions"); + + return await _polymath.MakeVaultApiRequest>("v1/" + mountPoint.Trim('/') + "/encode/" + roleName.Trim('/'), HttpMethod.Post, encodeRequestOptions, wrapTimeToLive: wrapTimeToLive).ConfigureAwait(_polymath.VaultClientSettings.ContinueAsyncTasksOnCapturedContext); + } + + public async Task> DecodeAsync(string roleName, DecodeRequestOptions decodeRequestOptions, string mountPoint = "transform", string wrapTimeToLive = null) + { + Checker.NotNull(roleName, "roleName"); + Checker.NotNull(decodeRequestOptions, "decodeRequestOptions"); + + return await _polymath.MakeVaultApiRequest>("v1/" + mountPoint.Trim('/') + "/decode/" + roleName.Trim('/'), HttpMethod.Post, decodeRequestOptions, wrapTimeToLive: wrapTimeToLive).ConfigureAwait(_polymath.VaultClientSettings.ContinueAsyncTasksOnCapturedContext); + } + } +} \ No newline at end of file