Skip to content

Commit

Permalink
feat: add EditAsync method to ISecretManager and implement in SOPSLoc…
Browse files Browse the repository at this point in the history
…alAgeSecretManager (#164)

Signed-off-by: Nikolai Emil Damm <neq@energinet.dk>
  • Loading branch information
devantler authored Feb 17, 2025
1 parent ea756dd commit 24bb803
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 0 deletions.
8 changes: 8 additions & 0 deletions Devantler.SecretManager.Core/ISecretManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,12 @@ public interface ISecretManager<T> where T : IKey
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<string> DecryptAsync(string filePath, CancellationToken cancellationToken = default);

/// <summary>
/// Edit a file.
/// </summary>
/// <param name="filePath"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task EditAsync(string filePath, CancellationToken cancellationToken = default);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
namespace Devantler.SecretManager.SOPS.LocalAge.Tests.SOPSLocalAgeSecretManagerTests;

/// <summary>
/// Tests for <see cref="SOPSLocalAgeSecretManager.EncryptAsync(string, string, CancellationToken)"/>.
/// </summary>
[Collection("SOPSLocalAgeSecretManager")]
public class EditAsyncTests
{
readonly SOPSLocalAgeSecretManager _secretManager = new();

/// <summary>
/// Tests that <see cref="SOPSLocalAgeSecretManager.EncryptAsync(string, string, CancellationToken)"/> encrypts a file with a public key.
/// </summary>
/// <returns></returns>
[Fact]
public async Task EncryptAsync_GivenPathAndPublicKey_ReturnsEncryptedString()
{
// Arrange
var key = await _secretManager.CreateKeyAsync();
string plainText = """
secret: |
AGE-SECRET-KEY-1VZQ
""";
string filePath = Path.GetTempPath() + "edit-async-test.yaml";
File.WriteAllText(filePath, plainText);

// Act
string encryptedText = await _secretManager.EncryptAsync(filePath, key.PublicKey);
async Task task() => await _secretManager.EditAsync(filePath);

// Assert
Assert.NotEqual(plainText, encryptedText);
var exception = await Record.ExceptionAsync(async () => await Task.WhenAny(task(), Task.Delay(5000)));
Assert.Null(exception);

// Cleanup
_ = await _secretManager.DeleteKeyAsync(key);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,13 @@ public async Task<AgeKey> DeleteKeyAsync(string publicKey, CancellationToken can
return key;
}

/// <inheritdoc/>
public Task EditAsync(string filePath, CancellationToken cancellationToken = default)
{
List<string> args = ["edit", filePath];
return SOPSCLI.SOPS.RunAsync([.. args], cancellationToken: cancellationToken);
}

/// <summary>
/// Encrypt a file with an Age public key.
/// </summary>
Expand Down

0 comments on commit 24bb803

Please sign in to comment.