public async Task WhenGetSecretIsCalledCacheIsUsed() { // Arrange const string secretName = "secretname"; const string secretValue = "testValue"; KeyVaultSecret secret = new KeyVaultSecret(secretName, secretValue, null); var mockSecretReader = new Mock <ISecretReader>(); mockSecretReader .Setup(x => x.GetSecretObjectAsync(It.IsAny <string>())) .Returns(Task.FromResult((ISecret)secret)); var cachingSecretReader = new CachingSecretReader(mockSecretReader.Object, int.MaxValue); // Act var value1 = await cachingSecretReader.GetSecretAsync("secretname"); var value2 = await cachingSecretReader.GetSecretAsync("secretname"); // Assert mockSecretReader.Verify(x => x.GetSecretObjectAsync(It.IsAny <string>()), Times.Once); Assert.Equal(secretValue, value1); Assert.Equal(value1, value2); }
private static ISecretInjector GetSecretInjector(IDictionary<string, string> arguments) { ISecretReader secretReader; var vaultName = arguments.GetOrDefault<string>(Arguments.VaultName); if (string.IsNullOrEmpty(vaultName)) { secretReader = new EmptySecretReader(); } else { var clientId = arguments.GetOrThrow<string>(Arguments.ClientId); var certificateThumbprint = arguments.GetOrThrow<string>(Arguments.CertificateThumbprint); var storeName = arguments.GetOrDefault(Arguments.StoreName, StoreName.My); var storeLocation = arguments.GetOrDefault(Arguments.StoreLocation, StoreLocation.LocalMachine); var shouldValidateCert = arguments.GetOrDefault(Arguments.ValidateCertificate, false); var keyVaultConfig = new KeyVaultConfiguration(vaultName, clientId, certificateThumbprint, storeName, storeLocation, shouldValidateCert); secretReader = new CachingSecretReader(new KeyVaultReader(keyVaultConfig), arguments.GetOrDefault(Arguments.RefreshIntervalSec, CachingSecretReader.DefaultRefreshIntervalSec)); } return new SecretInjector(secretReader); }
private static ISecretInjector GetSecretInjector(IDictionary <string, string> arguments) { ISecretReader secretReader; var vaultName = arguments.GetOrDefault <string>(Arguments.VaultName); if (string.IsNullOrEmpty(vaultName)) { secretReader = new EmptySecretReader(); } else { var clientId = arguments.GetOrThrow <string>(Arguments.ClientId); var certificateThumbprint = arguments.GetOrThrow <string>(Arguments.CertificateThumbprint); var storeName = arguments.GetOrDefault(Arguments.StoreName, StoreName.My); var storeLocation = arguments.GetOrDefault(Arguments.StoreLocation, StoreLocation.LocalMachine); var shouldValidateCert = arguments.GetOrDefault(Arguments.ValidateCertificate, true); var keyVaultCertificate = CertificateUtility.FindCertificateByThumbprint(storeName, storeLocation, certificateThumbprint, shouldValidateCert); var keyVaultConfig = new KeyVaultConfiguration(vaultName, clientId, keyVaultCertificate); secretReader = new CachingSecretReader(new KeyVaultReader(keyVaultConfig), arguments.GetOrDefault(Arguments.RefreshIntervalSec, CachingSecretReader.DefaultRefreshIntervalSec)); } return(new SecretInjector(secretReader)); }
public async Task WhenGetSecretIsCalledCacheIsUsedWithoutLogger() { // Arrange const string secretName = "secretname"; const string secretValue = "testValue"; KeyVaultSecret secret = new KeyVaultSecret(secretName, secretValue, null); var mockLogger = new Mock <ILogger>(); var mockSecretReader = new Mock <ISecretReader>(); mockSecretReader .Setup(x => x.GetSecretObjectAsync(It.IsAny <string>())) .Returns(Task.FromResult((ISecret)secret)); var cachingSecretReader = new CachingSecretReader(mockSecretReader.Object, int.MaxValue); // Act var value1 = await cachingSecretReader.GetSecretAsync("secretname"); var value2 = await cachingSecretReader.GetSecretAsync("secretname"); // Assert mockSecretReader.Verify(x => x.GetSecretObjectAsync(It.IsAny <string>()), Times.Once); mockLogger.Verify(x => x.Log(It.IsAny <LogLevel>(), It.IsAny <EventId>(), It.IsAny <FormattedLogValues>(), It.IsAny <Exception>(), It.IsAny <Func <object, Exception, string> >()), Times.Never); }
public async Task WhenGetSecretIsCalledCacheIsRefreshedIfPastInterval() { // Arrange const string secretName = "secretname"; const string firstSecretValue = "secret1"; const string secondSecretValue = "secret2"; KeyVaultSecret firstSecret = new KeyVaultSecret(secretName, firstSecretValue, null); KeyVaultSecret secondSecret = new KeyVaultSecret(secretName, secondSecretValue, null); const int refreshIntervalSec = 1; var mockSecretReader = new Mock <ISecretReader>(); mockSecretReader .SetupSequence(x => x.GetSecretObjectAsync(It.IsAny <string>())) .Returns(Task.FromResult((ISecret)firstSecret)) .Returns(Task.FromResult((ISecret)secondSecret)); var mockLogger = new Mock <ILogger>(); var cachingSecretReader = new CachingSecretReader(mockSecretReader.Object, refreshIntervalSec); // Act var firstValue1 = await cachingSecretReader.GetSecretAsync(secretName, mockLogger.Object); var firstValue2 = await cachingSecretReader.GetSecretAsync(secretName, mockLogger.Object); // Assert mockSecretReader.Verify(x => x.GetSecretObjectAsync(It.IsAny <string>()), Times.Once); mockLogger.Verify(x => x.Log(It.IsAny <LogLevel>(), It.IsAny <EventId>(), It.IsAny <FormattedLogValues>(), It.IsAny <Exception>(), It.IsAny <Func <object, Exception, string> >()), Times.Once); Assert.Equal(firstSecret.Value, firstValue1); Assert.Equal(firstSecret.Value, firstValue2); // Arrange 2 // We are now x seconds later after refreshIntervalSec has passed. await Task.Delay(TimeSpan.FromSeconds(refreshIntervalSec * 2)); // Act 2 var secondValue1 = await cachingSecretReader.GetSecretAsync(secretName, mockLogger.Object); var secondValue2 = await cachingSecretReader.GetSecretAsync(secretName, mockLogger.Object); // Assert 2 mockSecretReader.Verify(x => x.GetSecretObjectAsync(It.IsAny <string>()), Times.Exactly(2)); mockLogger.Verify(x => x.Log(It.IsAny <LogLevel>(), It.IsAny <EventId>(), It.IsAny <FormattedLogValues>(), It.IsAny <Exception>(), It.IsAny <Func <object, Exception, string> >()), Times.Exactly(2)); Assert.Equal(secondSecret.Value, secondValue1); Assert.Equal(secondSecret.Value, secondValue2); }
public ISecretReader CreateSecretReader() { ISecretReader secretReader; // Is KeyVault configured? if (!_configurationDictionary.TryGetValue(VaultNameKey, out var vaultName) || string.IsNullOrEmpty(vaultName)) { secretReader = new EmptySecretReader(); } else { KeyVaultConfiguration keyVaultConfiguration; if (_configurationDictionary.TryGetValue(UseManagedIdentityKey, out var useManagedIdentityStr) && bool.TryParse(useManagedIdentityStr, out var useManagedIdentity) && useManagedIdentity) { keyVaultConfiguration = new KeyVaultConfiguration(vaultName); } else { var clientId = _configurationDictionary[ClientIdKey]; var certificateThumbprint = _configurationDictionary[CertificateThumbprintKey]; var storeLocation = _configurationDictionary[StoreLocationKey]; var storeName = _configurationDictionary[StoreNameKey]; var validateCertificate = _configurationDictionary[ValidateCertificateKey]; var certificate = CertificateUtility.FindCertificateByThumbprint( (StoreName)Enum.Parse(typeof(StoreName), storeName), (StoreLocation)Enum.Parse(typeof(StoreLocation), storeLocation), certificateThumbprint, bool.Parse(validateCertificate)); keyVaultConfiguration = new KeyVaultConfiguration(vaultName, clientId, certificate); } if (!_configurationDictionary.TryGetValue(CacheRefreshIntervalKey, out var cacheRefresh) || !int.TryParse(cacheRefresh, out int refreshIntervalSec)) { refreshIntervalSec = CachingSecretReader.DefaultRefreshIntervalSec; } secretReader = new KeyVaultReader(keyVaultConfiguration); secretReader = new CachingSecretReader(secretReader, refreshIntervalSec); } return(secretReader); }
public async Task WhenGetSecretIsCalledCacheIsRefreshedIfPastSecretExpiry() { // Arrange const string secretName = "secretname"; const string firstSecretValue = "testValue"; DateTime firstSecretExpiration = DateTime.UtcNow.AddSeconds(-1); const string secondSecretValue = "testValue2"; DateTime secondSecretExpiration = DateTime.UtcNow.AddHours(1); KeyVaultSecret secret1 = new KeyVaultSecret(secretName, firstSecretValue, firstSecretExpiration); KeyVaultSecret secret2 = new KeyVaultSecret(secretName, secondSecretValue, secondSecretExpiration); int refreshIntervalSec = 30; int refreshIntervalBeforeExpirySec = 0; var mockSecretReader = new Mock <ISecretReader>(); mockSecretReader .SetupSequence(x => x.GetSecretObjectAsync(It.IsAny <string>())) .Returns(Task.FromResult((ISecret)secret1)) .Returns(Task.FromResult((ISecret)secret2)); var mockLogger = new Mock <ILogger>(); var cachingSecretReader = new CachingSecretReader(mockSecretReader.Object, refreshIntervalSec, refreshIntervalBeforeExpirySec); // Act var secretObject1 = await cachingSecretReader.GetSecretObjectAsync(secretName, mockLogger.Object); var secretObject2 = await cachingSecretReader.GetSecretObjectAsync(secretName, mockLogger.Object); var secretObject3 = await cachingSecretReader.GetSecretObjectAsync(secretName, mockLogger.Object); // Assert mockSecretReader.Verify(x => x.GetSecretObjectAsync(It.IsAny <string>()), Times.Exactly(2)); mockLogger.Verify(x => x.Log(It.IsAny <LogLevel>(), It.IsAny <EventId>(), It.IsAny <FormattedLogValues>(), It.IsAny <Exception>(), It.IsAny <Func <object, Exception, string> >()), Times.Exactly(2)); Assert.Equal(secretObject1.Value, firstSecretValue); Assert.Equal(secretObject1.Expiration, firstSecretExpiration); Assert.Equal(secretObject2.Value, secondSecretValue); Assert.Equal(secretObject2.Expiration, secondSecretExpiration); Assert.Equal(secretObject3.Value, secondSecretValue); Assert.Equal(secretObject3.Expiration, secondSecretExpiration); }
public async Task WhenGetSecretIsCalledCacheIsUsed() { // Arrange const string secret = "secret"; var mockSecretReader = new Mock <ISecretReader>(); mockSecretReader.Setup(x => x.GetSecretAsync(It.IsAny <string>())).Returns(Task.FromResult(secret)); var cachingSecretReader = new CachingSecretReader(mockSecretReader.Object, new DiagnosticsService()); // Act string value = await cachingSecretReader.GetSecretAsync("secretname"); value = await cachingSecretReader.GetSecretAsync("secretname"); // Assert mockSecretReader.Verify(x => x.GetSecretAsync(It.IsAny <string>()), Times.Once); Assert.Equal(secret, value); }
public async Task WhenGetSecretIsCalledCacheIsRefreshedIfPastInterval() { // Arrange const string secretName = "secretname"; const string firstSecret = "secret1"; const string secondSecret = "secret2"; const int refreshIntervalSec = 1; var mockSecretReader = new Mock <ISecretReader>(); mockSecretReader .SetupSequence(x => x.GetSecretAsync(It.IsAny <string>())) .Returns(Task.FromResult(firstSecret)) .Returns(Task.FromResult(secondSecret)); var cachingSecretReader = new CachingSecretReader(mockSecretReader.Object, refreshIntervalSec); // Act var firstValue1 = await cachingSecretReader.GetSecretAsync(secretName); var firstValue2 = await cachingSecretReader.GetSecretAsync(secretName); // Assert mockSecretReader.Verify(x => x.GetSecretAsync(It.IsAny <string>()), Times.Once); Assert.Equal(firstSecret, firstValue1); Assert.Equal(firstSecret, firstValue2); // Arrange 2 // We are now x seconds later after refreshIntervalSec has passed. await Task.Delay(TimeSpan.FromSeconds(refreshIntervalSec * 2)); // Act 2 var secondValue1 = await cachingSecretReader.GetSecretAsync(secretName); var secondValue2 = await cachingSecretReader.GetSecretAsync(secretName); // Assert 2 mockSecretReader.Verify(x => x.GetSecretAsync(It.IsAny <string>()), Times.Exactly(2)); Assert.Equal(secondSecret, secondValue1); Assert.Equal(secondSecret, secondValue2); }
public async Task GetSecretObjectAsyncReturnsSecretExpiry() { // Arrange const string secretName = "secretname"; const string secretValue = "testValue"; DateTime secretExpiration = DateTime.UtcNow.AddSeconds(3); KeyVaultSecret secret = new KeyVaultSecret(secretName, secretValue, secretExpiration); var mockSecretReader = new Mock <ISecretReader>(); mockSecretReader .SetupSequence(x => x.GetSecretObjectAsync(It.IsAny <string>())) .Returns(Task.FromResult((ISecret)secret)); var cachingSecretReader = new CachingSecretReader(mockSecretReader.Object); // Act var secretObject = await cachingSecretReader.GetSecretObjectAsync(secretName); // Assert mockSecretReader.Verify(x => x.GetSecretObjectAsync(It.IsAny <string>()), Times.Once); Assert.Equal(secretObject.Value, secretValue); Assert.Equal(secretObject.Expiration, secretExpiration); }