< Summary - Envilder .NET SDK

Information
Class: Envilder.Infrastructure.Aws.AwsSsmSecretProvider
Assembly: Envilder
File(s): /home/runner/work/envilder/envilder/src/sdks/dotnet/Infrastructure/Aws/AwsSsmSecretProvider.cs
Tag: 427_29134414720
Line coverage
92%
Covered lines: 25
Uncovered lines: 2
Coverable lines: 27
Total lines: 87
Line coverage: 92.5%
Branch coverage
50%
Covered branches: 3
Total branches: 6
Branch coverage: 50%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)50%22100%
GetSecretAsync()50%2290.91%
GetSecret(...)50%2291.67%

File(s)

/home/runner/work/envilder/envilder/src/sdks/dotnet/Infrastructure/Aws/AwsSsmSecretProvider.cs

#LineLine coverage
 1namespace Envilder.Infrastructure.Aws;
 2
 3using Amazon.SimpleSystemsManagement;
 4using Amazon.SimpleSystemsManagement.Model;
 5using global::Envilder.Domain.Ports;
 6using System;
 7using System.Threading;
 8using System.Threading.Tasks;
 9
 10/// <summary>
 11/// <see cref="ISecretProvider"/> backed by AWS Systems Manager Parameter Store.
 12/// Parameters are retrieved with decryption enabled so that <c>SecureString</c>
 13/// values are returned in plain text.
 14/// </summary>
 15public class AwsSsmSecretProvider : ISecretProvider
 16{
 17  private readonly IAmazonSimpleSystemsManagement _ssmClient;
 18  private readonly string? _profile;
 19
 20  /// <summary>
 21  /// Initializes a new instance using the supplied SSM client.
 22  /// </summary>
 23  /// <param name="ssmClient">A configured <see cref="IAmazonSimpleSystemsManagement"/> instance.</param>
 24  /// <param name="profile">The AWS profile in use, surfaced when an SSO session has expired.</param>
 125  public AwsSsmSecretProvider(IAmazonSimpleSystemsManagement ssmClient, string? profile = null)
 26  {
 127    _ssmClient = ssmClient ?? throw new ArgumentNullException(nameof(ssmClient));
 128    _profile = profile;
 129  }
 30
 31  /// <inheritdoc />
 32  public async Task<string?> GetSecretAsync(string name, CancellationToken cancellationToken = default)
 33  {
 134    if (string.IsNullOrWhiteSpace(name))
 35    {
 036      throw new ArgumentException("Secret name cannot be null or whitespace.", nameof(name));
 37    }
 38
 39    try
 40    {
 141      var response = await _ssmClient.GetParameterAsync(new() { Name = name, WithDecryption = true }, cancellationToken)
 142      return response.Parameter.Value;
 43    }
 144    catch (ParameterNotFoundException)
 45    {
 146      return null;
 47    }
 148    catch (Exception ex) when (SsoSessionExpiredDetector.IsSsoSessionExpired(ex))
 49    {
 150      throw new SsoSessionExpiredException(_profile, ex);
 51    }
 152    catch (Exception ex) when (ExpiredCredentialsDetector.IsExpiredCredentials(ex))
 53    {
 154      throw new ExpiredCredentialsException(ex);
 55    }
 156  }
 57
 58  /// <inheritdoc />
 59  public string? GetSecret(string name)
 60  {
 161    if (string.IsNullOrWhiteSpace(name))
 62    {
 063      throw new ArgumentException("Secret name cannot be null or whitespace.", nameof(name));
 64    }
 65
 66    try
 67    {
 168      using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(60));
 69#pragma warning disable VSTHRD002 // AWS SDK v4 has no synchronous GetParameter API
 170      var response = Task.Run(() => _ssmClient.GetParameterAsync(new() { Name = name, WithDecryption = true }, cts.Token
 71#pragma warning restore VSTHRD002
 172      return response.Parameter.Value;
 73    }
 174    catch (ParameterNotFoundException)
 75    {
 176      return null;
 77    }
 178    catch (Exception ex) when (SsoSessionExpiredDetector.IsSsoSessionExpired(ex))
 79    {
 180      throw new SsoSessionExpiredException(_profile, ex);
 81    }
 182    catch (Exception ex) when (ExpiredCredentialsDetector.IsExpiredCredentials(ex))
 83    {
 184      throw new ExpiredCredentialsException(ex);
 85    }
 186  }
 87}