public async Task GetHostSecrets_WhenNoHostSecretFileExists_GeneratesSecretsAndPersistsFiles() { using (var directory = new TempDirectory()) { string expectedTraceMessage = Resources.TraceHostSecretGeneration; HostSecretsInfo hostSecrets; using (var secretManager = CreateSecretManager(directory.Path, simulateWriteConversion: false, setStaleValue: false)) { hostSecrets = await secretManager.GetHostSecretsAsync(); } string secretsJson = File.ReadAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName)); HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson); Assert.NotNull(hostSecrets); Assert.NotNull(persistedSecrets); Assert.Equal(1, hostSecrets.FunctionKeys.Count); Assert.NotNull(hostSecrets.MasterKey); Assert.NotNull(hostSecrets.SystemKeys); Assert.Equal(0, hostSecrets.SystemKeys.Count); Assert.Equal(persistedSecrets.MasterKey.Value, hostSecrets.MasterKey); Assert.Equal(persistedSecrets.FunctionKeys.First().Value, hostSecrets.FunctionKeys.First().Value); } }
public void AddOrUpdateFunctionSecrets_WithNoFunctionNameAndProvidedSecret_UsesSecretAndPersistsHostFile() { var secretsPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); try { using (var variables = new TestScopedEnvironmentVariables("AzureWebJobsFeatureFlags", "MultiKey")) { Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false); KeyOperationResult result; using (var secretManager = new SecretManager(secretsPath, mockValueConverterFactory.Object)) { result = secretManager.AddOrUpdateFunctionSecret("TestSecret", "TestSecretValue"); } string secretsJson = File.ReadAllText(Path.Combine(secretsPath, ScriptConstants.HostMetadataFileName)); HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson); Key newSecret = persistedSecrets.FunctionKeys.FirstOrDefault(k => string.Equals(k.Name, "TestSecret", StringComparison.Ordinal)); Assert.Equal(OperationResult.Created, result.Result); Assert.Equal("TestSecretValue", result.Secret, StringComparer.Ordinal); Assert.NotNull(persistedSecrets); Assert.NotNull(newSecret); Assert.Equal(result.Secret, newSecret.Value); Assert.Equal("TestSecret", newSecret.Name, StringComparer.Ordinal); Assert.NotNull(persistedSecrets.MasterKey); } } finally { Directory.Delete(secretsPath, true); } }
public async Task SetMasterKey_WithProvidedKey_UsesProvidedKeyAndPersistsFile() { string testSecret = "abcde0123456789abcde0123456789abcde0123456789"; using (var directory = new TempDirectory()) { Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false); KeyOperationResult result; ISecretsRepository repository = new FileSystemSecretsRepository(directory.Path); using (var secretManager = new SecretManager(repository, mockValueConverterFactory.Object, NullLogger.Instance)) { result = await secretManager.SetMasterKeyAsync(testSecret); } bool functionSecretsExists = File.Exists(Path.Combine(directory.Path, "testfunction.json")); string secretsJson = File.ReadAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName)); HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson); Assert.NotNull(persistedSecrets); Assert.NotNull(persistedSecrets.MasterKey); Assert.Equal(OperationResult.Updated, result.Result); Assert.Equal(testSecret, result.Secret); } }
public void DeserializeHostSecrets_ReturnsExpectedResult(string serializedSecret, string hostName) { var serializer = new ScriptSecretSerializerV1(); var expected = new HostSecrets { MasterKey = new Key { Name = "master", Value = "1234" }, FunctionKeys = new List <Key> { new Key { Name = "Key1", Value = "Value1", IsEncrypted = false }, new Key { Name = "Key2", Value = "Value2", IsEncrypted = true } }, HostName = hostName }; HostSecrets actual = serializer.DeserializeSecrets <HostSecrets>(JObject.Parse(serializedSecret)); Assert.NotNull(actual); Assert.Equal(expected.MasterKey, actual.MasterKey); Assert.Equal(actual.HostName, hostName); Assert.Equal(expected.Source, ScriptConstants.Runtime); AssertKeyCollectionsEquality(expected.FunctionKeys, actual.FunctionKeys); }
public void SetMasterKey_WithProvidedKey_UsesProvidedKeyAndPersistsFile() { var secretsPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); string testSecret = "abcde0123456789abcde0123456789abcde0123456789"; try { Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false); KeyOperationResult result; using (var secretManager = new SecretManager(secretsPath, mockValueConverterFactory.Object)) { result = secretManager.SetMasterKey(testSecret); } bool functionSecretsExists = File.Exists(Path.Combine(secretsPath, "testfunction.json")); string secretsJson = File.ReadAllText(Path.Combine(secretsPath, ScriptConstants.HostMetadataFileName)); HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson); Assert.NotNull(persistedSecrets); Assert.NotNull(persistedSecrets.MasterKey); Assert.Equal(OperationResult.Updated, result.Result); Assert.Equal(testSecret, result.Secret); } finally { Directory.Delete(secretsPath, true); } }
public async Task AddOrUpdateFunctionSecrets_WithScope_UsesSecretandPersistsHostFile(string scope, Func <HostSecrets, IList <Key> > keySelector, TempDirectory directory) { string secretName = "TestSecret"; string expectedTraceMessage = string.Format(Resources.TraceAddOrUpdateFunctionSecret, "Host", secretName, scope, "Created"); Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false); KeyOperationResult result; ISecretsRepository repository = new FileSystemSecretsRepository(directory.Path); using (var secretManager = new SecretManager(repository, mockValueConverterFactory.Object, NullLogger.Instance)) { result = await secretManager.AddOrUpdateFunctionSecretAsync(secretName, "TestSecretValue", scope, ScriptSecretsType.Host); } string secretsJson = File.ReadAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName)); HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson); Key newSecret = keySelector(persistedSecrets).FirstOrDefault(k => string.Equals(k.Name, secretName, StringComparison.Ordinal)); Assert.Equal(OperationResult.Created, result.Result); Assert.Equal("TestSecretValue", result.Secret, StringComparer.Ordinal); Assert.NotNull(persistedSecrets); Assert.NotNull(newSecret); Assert.Equal(result.Secret, newSecret.Value); Assert.Equal(secretName, newSecret.Name, StringComparer.Ordinal); Assert.NotNull(persistedSecrets.MasterKey); }
public async Task SetMasterKey_WithoutProvidedKey_GeneratesKeyAndPersistsFile() { using (var directory = new TempDirectory()) { Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false); KeyOperationResult result; var traceWriter = new TestTraceWriter(System.Diagnostics.TraceLevel.Verbose); ISecretsRepository repository = new FileSystemSecretsRepository(directory.Path); using (var secretManager = new SecretManager(repository, mockValueConverterFactory.Object, null)) { result = await secretManager.SetMasterKeyAsync(); } bool functionSecretsExists = File.Exists(Path.Combine(directory.Path, "testfunction.json")); string secretsJson = File.ReadAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName)); HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson); Assert.NotNull(persistedSecrets); Assert.NotNull(persistedSecrets.MasterKey); Assert.Equal(OperationResult.Created, result.Result); Assert.Equal(result.Secret, persistedSecrets.MasterKey.Value); } }
public void SerializeHostSecrets_ReturnsExpectedResult() { var serializer = new ScriptSecretSerializerV0(); var secrets = new HostSecrets { MasterKey = new Key { Name = "master", Value = "mastervalue" }, FunctionKeys = new List <Key> { new Key { Name = string.Empty, Value = "functionKeyValue", IsEncrypted = false, } } }; string serializedSecret = serializer.SerializeSecrets(secrets); Assert.NotNull(serializedSecret); var jsonObject = JObject.Parse(serializedSecret); var functionKey = jsonObject.Value <string>("functionKey"); var masterKey = jsonObject.Value <string>("masterKey"); Assert.Equal("mastervalue", masterKey); Assert.Equal("functionKeyValue", functionKey); }
public void GetHostSecrets_WhenNoHostSecretFileExists_GeneratesSecretsAndPersistsFiles() { using (var directory = new TempDirectory()) { string expectedTraceMessage = Resources.TraceHostSecretGeneration; Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false, false); HostSecretsInfo hostSecrets; var traceWriter = new TestTraceWriter(TraceLevel.Verbose); using (var secretManager = new SecretManager(directory.Path, mockValueConverterFactory.Object, traceWriter)) { hostSecrets = secretManager.GetHostSecrets(); } string secretsJson = File.ReadAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName)); HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson); Assert.NotNull(hostSecrets); Assert.NotNull(persistedSecrets); Assert.Equal(1, hostSecrets.FunctionKeys.Count); Assert.NotNull(hostSecrets.MasterKey); Assert.Equal(persistedSecrets.MasterKey.Value, hostSecrets.MasterKey); Assert.Equal(persistedSecrets.FunctionKeys.First().Value, hostSecrets.FunctionKeys.First().Value); Assert.True(traceWriter.Traces.Any(t => t.Level == TraceLevel.Verbose && t.Message.IndexOf(expectedTraceMessage) > -1)); } }
public async Task GetHostSecrets_WhenNoHostSecretFileExists_GeneratesSecretsAndPersistsFiles() { using (var directory = new TempDirectory()) { string expectedTraceMessage = Resources.TraceHostSecretGeneration; Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false, false); HostSecretsInfo hostSecrets; ISecretsRepository repository = new FileSystemSecretsRepository(directory.Path); using (var secretManager = new SecretManager(repository, mockValueConverterFactory.Object, NullLogger.Instance)) { hostSecrets = await secretManager.GetHostSecretsAsync(); } string secretsJson = File.ReadAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName)); HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson); Assert.NotNull(hostSecrets); Assert.NotNull(persistedSecrets); Assert.Equal(1, hostSecrets.FunctionKeys.Count); Assert.NotNull(hostSecrets.MasterKey); Assert.NotNull(hostSecrets.SystemKeys); Assert.Equal(0, hostSecrets.SystemKeys.Count); Assert.Equal(persistedSecrets.MasterKey.Value, hostSecrets.MasterKey); Assert.Equal(persistedSecrets.FunctionKeys.First().Value, hostSecrets.FunctionKeys.First().Value); } }
public void DeserializeHostSecrets_ReturnsExpectedResult() { var serializer = new ScriptSecretSerializerV1(); var serializedSecret = "{'masterKey':{'name':'master','value':'1234','encrypted':false},'functionKeys':[{'name':'Key1','value':'Value1','encrypted':false},{'name':'Key2','value':'Value2','encrypted':true}]}"; var expected = new HostSecrets { MasterKey = new Key { Name = "master", Value = "1234" }, FunctionKeys = new List <Key> { new Key { Name = "Key1", Value = "Value1", IsEncrypted = false }, new Key { Name = "Key2", Value = "Value2", IsEncrypted = true } } }; HostSecrets actual = serializer.DeserializeSecrets <HostSecrets>(JObject.Parse(serializedSecret)); Assert.NotNull(actual); Assert.Equal(expected.MasterKey, actual.MasterKey); AssertKeyCollectionsEquality(expected.FunctionKeys, actual.FunctionKeys); }
public void SetMasterKey_WithoutProvidedKey_GeneratesKeyAndPersistsFile() { var secretsPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); try { using (var variables = new TestScopedEnvironmentVariables("AzureWebJobsFeatureFlags", "MultiKey")) { Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false); KeyOperationResult result; using (var secretManager = new SecretManager(secretsPath, mockValueConverterFactory.Object)) { result = secretManager.SetMasterKey(); } bool functionSecretsExists = File.Exists(Path.Combine(secretsPath, "testfunction.json")); string secretsJson = File.ReadAllText(Path.Combine(secretsPath, ScriptConstants.HostMetadataFileName)); HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson); Assert.NotNull(persistedSecrets); Assert.NotNull(persistedSecrets.MasterKey); Assert.Equal(OperationResult.Created, result.Result); Assert.Equal(result.Secret, persistedSecrets.MasterKey.Value); } } finally { Directory.Delete(secretsPath, true); } }
public AuthorizationLevelAttributeTests() { _actionContext = new HttpActionContext(); HttpControllerContext controllerContext = new HttpControllerContext(); _actionContext.ControllerContext = controllerContext; HttpConfiguration httpConfig = new HttpConfiguration(); controllerContext.Configuration = httpConfig; Mock <IDependencyResolver> mockDependencyResolver = new Mock <IDependencyResolver>(MockBehavior.Strict); httpConfig.DependencyResolver = mockDependencyResolver.Object; _mockSecretManager = new Mock <SecretManager>(MockBehavior.Strict); _hostSecrets = new HostSecrets { MasterKey = TestMasterKeyValue, FunctionKey = TestHostFunctionKeyValue }; _mockSecretManager.Setup(p => p.GetHostSecrets()).Returns(_hostSecrets); _functionSecrets = new FunctionSecrets { Key = TestFunctionKeyValue }; _mockSecretManager.Setup(p => p.GetFunctionSecrets(It.IsAny <string>())).Returns(_functionSecrets); mockDependencyResolver.Setup(p => p.GetService(typeof(SecretManager))).Returns(_mockSecretManager.Object); }
public void GetHostSecrets_WhenNoHostSecretFileExists_GeneratesSecretsAndPersistsFiles() { var secretsPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); try { using (var variables = new TestScopedEnvironmentVariables("AzureWebJobsFeatureFlags", "MultiKey")) { Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false); HostSecretsInfo hostSecrets; using (var secretManager = new SecretManager(secretsPath, mockValueConverterFactory.Object)) { hostSecrets = secretManager.GetHostSecrets(); } string secretsJson = File.ReadAllText(Path.Combine(secretsPath, ScriptConstants.HostMetadataFileName)); HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson); Assert.NotNull(hostSecrets); Assert.NotNull(persistedSecrets); Assert.Equal(1, hostSecrets.FunctionKeys.Count); Assert.NotNull(hostSecrets.MasterKey); Assert.Equal(persistedSecrets.MasterKey.Value, hostSecrets.MasterKey); Assert.Equal(persistedSecrets.FunctionKeys.First().Value, hostSecrets.FunctionKeys.First().Value); } } finally { Directory.Delete(secretsPath, true); } }
public void SetMasterKey_WithProvidedKey_UsesProvidedKeyAndPersistsFile() { string testSecret = "abcde0123456789abcde0123456789abcde0123456789"; using (var directory = new TempDirectory()) { string expectedTraceMessage = "Master key Updated"; Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false); KeyOperationResult result; var traceWriter = new TestTraceWriter(TraceLevel.Verbose); using (var secretManager = new SecretManager(directory.Path, mockValueConverterFactory.Object, traceWriter)) { result = secretManager.SetMasterKey(testSecret); } bool functionSecretsExists = File.Exists(Path.Combine(directory.Path, "testfunction.json")); string secretsJson = File.ReadAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName)); HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson); Assert.NotNull(persistedSecrets); Assert.NotNull(persistedSecrets.MasterKey); Assert.Equal(OperationResult.Updated, result.Result); Assert.Equal(testSecret, result.Secret); Assert.True(traceWriter.Traces.Any(t => t.Level == TraceLevel.Info && t.Message.IndexOf(expectedTraceMessage) > -1)); } }
public void DeserializeHostSecrets_ReturnsExpectedResult() { var serializer = new ScriptSecretSerializerV0(); var serializedSecret = "{'masterKey': 'master', 'functionKey': 'master'}"; var expected = new HostSecrets { MasterKey = new Key { Name = ScriptConstants.DefaultMasterKeyName, Value = "master" }, FunctionKeys = new List <Key> { new Key { Name = ScriptConstants.DefaultFunctionKeyName, Value = "master", IsEncrypted = false } } }; HostSecrets actual = serializer.DeserializeSecrets <HostSecrets>(JObject.Parse(serializedSecret)); Assert.NotNull(actual); Assert.Equal(expected.MasterKey, actual.MasterKey); AssertKeyCollectionsEquality(expected.FunctionKeys, actual.FunctionKeys); }
public async Task SetMasterKey_WithoutProvidedKey_GeneratesKeyAndPersistsFile() { using (var directory = new TempDirectory()) { string expectedTraceMessage = "Master key Created"; Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false); KeyOperationResult result; var traceWriter = new TestTraceWriter(TraceLevel.Verbose); ISecretsRepository repository = new FileSystemSecretsRepository(directory.Path); using (var secretManager = new SecretManager(repository, mockValueConverterFactory.Object, traceWriter)) { result = await secretManager.SetMasterKeyAsync(); } bool functionSecretsExists = File.Exists(Path.Combine(directory.Path, "testfunction.json")); string secretsJson = File.ReadAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName)); HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson); Assert.NotNull(persistedSecrets); Assert.NotNull(persistedSecrets.MasterKey); Assert.Equal(OperationResult.Created, result.Result); Assert.Equal(result.Secret, persistedSecrets.MasterKey.Value); Assert.True(traceWriter.Traces.Any(t => t.Level == TraceLevel.Info && t.Message.IndexOf(expectedTraceMessage) > -1), "Expected Trace message not found"); } }
public async Task AddOrUpdateFunctionSecrets_WithNoFunctionNameAndProvidedSecret_UsesSecretAndPersistsHostFile() { using (var directory = new TempDirectory()) { string secretName = "TestSecret"; string expectedTraceMessage = string.Format(Resources.TraceAddOrUpdateFunctionSecret, "Host", secretName, "host", "Created"); Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false); KeyOperationResult result; var traceWriter = new TestTraceWriter(TraceLevel.Verbose); ISecretsRepository repository = new FileSystemSecretsRepository(directory.Path); using (var secretManager = new SecretManager(repository, mockValueConverterFactory.Object, traceWriter)) { result = await secretManager.AddOrUpdateFunctionSecretAsync(secretName, "TestSecretValue"); } string secretsJson = File.ReadAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName)); HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson); Key newSecret = persistedSecrets.FunctionKeys.FirstOrDefault(k => string.Equals(k.Name, secretName, StringComparison.Ordinal)); Assert.Equal(OperationResult.Created, result.Result); Assert.Equal("TestSecretValue", result.Secret, StringComparer.Ordinal); Assert.NotNull(persistedSecrets); Assert.NotNull(newSecret); Assert.Equal(result.Secret, newSecret.Value); Assert.Equal(secretName, newSecret.Name, StringComparer.Ordinal); Assert.NotNull(persistedSecrets.MasterKey); Assert.True(traceWriter.Traces.Any(t => t.Level == TraceLevel.Info && t.Message.IndexOf(expectedTraceMessage) > -1), "Expected Trace message not found"); } }
public async Task ReadAsync_ReadsExpectedFile(SecretsRepositoryType repositoryType, ScriptSecretsType secretsType) { using (var directory = new TempDirectory()) { await _fixture.TestInitialize(repositoryType, directory.Path); ScriptSecrets testSecrets = null; if (secretsType == ScriptSecretsType.Host) { testSecrets = new HostSecrets() { MasterKey = new Key("master", "test"), FunctionKeys = new List <Key>() { new Key(KeyName, "test") }, SystemKeys = new List <Key>() { new Key(KeyName, "test") } }; } else { testSecrets = new FunctionSecrets() { Keys = new List <Key>() { new Key(KeyName, "test") } }; } string testFunctionName = secretsType == ScriptSecretsType.Host ? "host" : functionName; await _fixture.WriteSecret(testFunctionName, testSecrets); var target = _fixture.GetNewSecretRepository(); ScriptSecrets secretsContent = await target.ReadAsync(secretsType, testFunctionName); if (secretsType == ScriptSecretsType.Host) { Assert.Equal((secretsContent as HostSecrets).MasterKey.Name, "master"); Assert.Equal((secretsContent as HostSecrets).MasterKey.Value, "test"); Assert.Equal((secretsContent as HostSecrets).FunctionKeys[0].Name, KeyName); Assert.Equal((secretsContent as HostSecrets).FunctionKeys[0].Value, "test"); Assert.Equal((secretsContent as HostSecrets).SystemKeys[0].Name, KeyName); Assert.Equal((secretsContent as HostSecrets).SystemKeys[0].Value, "test"); } else { Assert.Equal((secretsContent as FunctionSecrets).Keys[0].Name, KeyName); Assert.Equal((secretsContent as FunctionSecrets).Keys[0].Value, "test"); } } }
private async Task <ScriptSecrets> GetSecretsFromKeyVault(string functionNameOrHost, ScriptSecretsType type) { var secretResults = SecretClient.GetPropertiesOfSecretsAsync().AsPages(); var searchPages = new List <SecretProperties>(); await foreach (Page <SecretProperties> page in secretResults) { { foreach (SecretProperties secret in page.Values) { searchPages.Add(secret); } } } if (type == ScriptSecretsType.Host) { KeyVaultSecret masterBundle = await SecretClient.GetSecretAsync(searchPages.FirstOrDefault(x => x.Name.StartsWith("host--master")).Name); KeyVaultSecret functionKeyBundle = await SecretClient.GetSecretAsync(searchPages.FirstOrDefault(x => x.Name.StartsWith("host--functionKey")).Name); KeyVaultSecret systemKeyBundle = await SecretClient.GetSecretAsync(searchPages.FirstOrDefault(x => x.Name.StartsWith("host--systemKey")).Name); HostSecrets hostSecrets = new HostSecrets() { FunctionKeys = new List <Key>() { new Key(GetSecretName(functionKeyBundle.Name), functionKeyBundle.Value) }, SystemKeys = new List <Key>() { new Key(GetSecretName(systemKeyBundle.Name), systemKeyBundle.Value) } }; hostSecrets.MasterKey = new Key("master", masterBundle.Value); return(hostSecrets); } else { KeyVaultSecret functionKeyBundle = await SecretClient.GetSecretAsync(searchPages.FirstOrDefault(x => x.Name.StartsWith("function--")).Name); FunctionSecrets functionSecrets = new FunctionSecrets() { Keys = new List <Key>() { new Key(GetSecretName(functionKeyBundle.Name), functionKeyBundle.Value) } }; return(functionSecrets); } }
public async Task AddOrUpdateFunctionSecrets_WithExistingHostFileAndSystemSecretScope_PersistsHostFileWithSecret() { using (var directory = new TempDirectory()) { var hostSecret = new HostSecrets(); hostSecret.MasterKey = new Key("_master", "master"); hostSecret.FunctionKeys = new List <Key> { }; var hostJson = JsonConvert.SerializeObject(hostSecret); await FileUtility.WriteAsync(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName), hostJson); await AddOrUpdateFunctionSecrets_WithScope_UsesSecretandPersistsHostFile(HostKeyScopes.SystemKeys, h => h.SystemKeys, directory); } }
internal static AuthorizationLevel GetAuthorizationLevel(HttpRequestMessage request, SecretManager secretManager, string functionName = null) { // TODO: Add support for validating "EasyAuth" headers // first see if a key value is specified via headers or query string (header takes precidence) IEnumerable <string> values; string keyValue = null; if (request.Headers.TryGetValues(FunctionsKeyHeaderName, out values)) { keyValue = values.FirstOrDefault(); } else { var queryParameters = request.GetQueryNameValuePairs().ToDictionary(p => p.Key, p => p.Value, StringComparer.OrdinalIgnoreCase); queryParameters.TryGetValue("code", out keyValue); } if (!string.IsNullOrEmpty(keyValue)) { // see if the key specified is the master key HostSecrets hostSecrets = secretManager.GetHostSecrets(); if (!string.IsNullOrEmpty(hostSecrets.MasterKey) && SecretEqual(keyValue, hostSecrets.MasterKey)) { return(AuthorizationLevel.Admin); } // see if the key specified matches the host function key if (!string.IsNullOrEmpty(hostSecrets.FunctionKey) && SecretEqual(keyValue, hostSecrets.FunctionKey)) { return(AuthorizationLevel.Function); } // if there is a function specific key specified try to match against that if (functionName != null) { FunctionSecrets functionSecrets = secretManager.GetFunctionSecrets(functionName); if (functionSecrets != null && !string.IsNullOrEmpty(functionSecrets.Key) && SecretEqual(keyValue, functionSecrets.Key)) { return(AuthorizationLevel.Function); } } } return(AuthorizationLevel.Anonymous); }
public async Task SetMasterKey_WithoutProvidedKey_GeneratesKeyAndPersistsFile() { using (var directory = new TempDirectory()) { KeyOperationResult result; using (var secretManager = CreateSecretManager(directory.Path, simulateWriteConversion: false)) { result = await secretManager.SetMasterKeyAsync(); } bool functionSecretsExists = File.Exists(Path.Combine(directory.Path, "testfunction.json")); string secretsJson = File.ReadAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName)); HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson); Assert.NotNull(persistedSecrets); Assert.NotNull(persistedSecrets.MasterKey); Assert.Equal(OperationResult.Created, result.Result); Assert.Equal(result.Secret, persistedSecrets.MasterKey.Value); } }
public void HostKeys(string secretName) { HostSecrets hostSecrets = new HostSecrets() { MasterKey = new Key("master", "test"), FunctionKeys = new List <Key>() { new Key(secretName, "test") }, SystemKeys = new List <Key>() { new Key(secretName, "test") }, }; Dictionary <string, string> dictionary = KeyVaultSecretsRepository.GetDictionaryFromScriptSecrets(hostSecrets, null); Assert.True(dictionary["host--masterKey--master"] == "test"); Assert.True(dictionary[$"host--functionKey--{KeyVaultSecretsRepository.Normalize(secretName)}"] == "test"); Assert.True(dictionary[$"host--systemKey--{KeyVaultSecretsRepository.Normalize(secretName)}"] == "test"); }
private async Task <ScriptSecrets> GetSecretsFromKeyVault(string functionNameOrHost, ScriptSecretsType type) { var secretResults = await KeyVaultClient.GetSecretsAsync(GetKeyVaultBaseUrl()); if (type == ScriptSecretsType.Host) { SecretBundle masterBundle = await KeyVaultClient.GetSecretAsync(GetKeyVaultBaseUrl(), secretResults.FirstOrDefault(x => x.Identifier.Name.StartsWith("host--master")).Identifier.Name); SecretBundle functionKeyBundle = await KeyVaultClient.GetSecretAsync(GetKeyVaultBaseUrl(), secretResults.FirstOrDefault(x => x.Identifier.Name.StartsWith("host--functionKey")).Identifier.Name); SecretBundle systemKeyBundle = await KeyVaultClient.GetSecretAsync(GetKeyVaultBaseUrl(), secretResults.FirstOrDefault(x => x.Identifier.Name.StartsWith("host--systemKey")).Identifier.Name); HostSecrets hostSecrets = new HostSecrets() { FunctionKeys = new List <Key>() { new Key(GetSecretName(functionKeyBundle.SecretIdentifier.Name), functionKeyBundle.Value) }, SystemKeys = new List <Key>() { new Key(GetSecretName(systemKeyBundle.SecretIdentifier.Name), systemKeyBundle.Value) } }; hostSecrets.MasterKey = new Key("master", masterBundle.Value); return(hostSecrets); } else { SecretBundle functionKeyBundle = await KeyVaultClient.GetSecretAsync(GetKeyVaultBaseUrl(), secretResults.FirstOrDefault(x => x.Identifier.Name.StartsWith("function--")).Identifier.Name); FunctionSecrets functionSecrets = new FunctionSecrets() { Keys = new List <Key>() { new Key(GetSecretName(functionKeyBundle.SecretIdentifier.Name), functionKeyBundle.Value) } }; return(functionSecrets); } }
public void SerializeHostSecrets_ReturnsExpectedResult() { var serializer = new ScriptSecretSerializerV1(); var secrets = new HostSecrets { MasterKey = new Key { Name = "master", Value = "1234" }, FunctionKeys = new List <Key> { new Key { Name = "Key1", Value = "Value1", IsEncrypted = false }, new Key { Name = "Key2", Value = "Value2", IsEncrypted = true } } }; string serializedSecret = serializer.SerializeSecrets(secrets); var jsonObject = JObject.Parse(serializedSecret); var functionSecrets = jsonObject.Property("functionKeys")?.Value?.ToObject <List <Key> >(); var masterKey = jsonObject.Property("masterKey")?.Value?.ToObject <Key>(); var instanceId = jsonObject.Property("instanceId")?.Value; Assert.NotNull(serializedSecret); Assert.Equal(secrets.MasterKey, masterKey); AssertKeyCollectionsEquality(secrets.FunctionKeys, functionSecrets); Assert.Equal(instanceId, secrets.InstanceId); }
public async Task GetSecretSnapshots_ReturnsExpected(SecretsRepositoryType repositoryType, ScriptSecretsType secretsType) { using (var directory = new TempDirectory()) { await _fixture.TestInitialize(repositoryType, directory.Path); ScriptSecrets secrets = null; if (secretsType == ScriptSecretsType.Host) { secrets = new HostSecrets() { MasterKey = new Key("master", "test") }; } else { secrets = new FunctionSecrets() { Keys = new List <Key>() { new Key(KeyName, "test") } }; } string testFunctionName = secretsType == ScriptSecretsType.Host ? null : functionName; var target = _fixture.GetNewSecretRepository(); await target.WriteAsync(secretsType, testFunctionName, secrets); for (int i = 0; i < 5; i++) { await target.WriteSnapshotAsync(secretsType, testFunctionName, secrets); } string[] files = await target.GetSecretSnapshots(secretsType, testFunctionName); Assert.True(files.Length > 0); } }
public async Task ReadAsync_ReadsExpectedKeyVaultPages(SecretsRepositoryType repositoryType, ScriptSecretsType secretsType) { using (var directory = new TempDirectory()) { await _fixture.TestInitialize(repositoryType, directory.Path); ScriptSecrets testSecrets = null; int keyCount = 35; List <Key> functionKeys = new List <Key>(); for (int i = 0; i < keyCount; ++i) { functionKeys.Add(new Key(KeyName + Guid.NewGuid().ToString(), "test" + i.ToString())); } if (secretsType == ScriptSecretsType.Host) { testSecrets = new HostSecrets() { MasterKey = new Key("master", "test"), FunctionKeys = functionKeys, SystemKeys = new List <Key>() { new Key(KeyName, "test") } }; } else { testSecrets = new FunctionSecrets() { Keys = functionKeys }; } string testFunctionName = secretsType == ScriptSecretsType.Host ? "host" : functionName; await _fixture.WriteSecret(testFunctionName, testSecrets); var target = _fixture.GetNewSecretRepository(); ScriptSecrets secretsContent = await target.ReadAsync(secretsType, testFunctionName); if (secretsType == ScriptSecretsType.Host) { Assert.Equal((secretsContent as HostSecrets).MasterKey.Name, "master"); Assert.Equal((secretsContent as HostSecrets).MasterKey.Value, "test"); Assert.Equal((secretsContent as HostSecrets).FunctionKeys.Count, functionKeys.Count); foreach (Key originalKey in functionKeys) { var matchingKeys = (secretsContent as HostSecrets).FunctionKeys.Where(x => string.Equals(x.Name, originalKey.Name)); Assert.Equal(matchingKeys.Count(), 1); Assert.Equal(matchingKeys.First().Value, originalKey.Value); } Assert.Equal((secretsContent as HostSecrets).SystemKeys[0].Name, KeyName); Assert.Equal((secretsContent as HostSecrets).SystemKeys[0].Value, "test"); } else { Assert.Equal((secretsContent as FunctionSecrets).Keys.Count, functionKeys.Count); foreach (Key originalKey in functionKeys) { var matchingKeys = (secretsContent as FunctionSecrets).Keys.Where(x => string.Equals(x.Name, originalKey.Name)); Assert.Equal(matchingKeys.Count(), 1); Assert.Equal(matchingKeys.First().Value, originalKey.Value); } } } }
public async Task WriteAsync_CreatesExpectedFile(SecretsRepositoryType repositoryType, ScriptSecretsType secretsType) { using (var directory = new TempDirectory()) { await _fixture.TestInitialize(repositoryType, directory.Path); ScriptSecrets secrets = null; if (secretsType == ScriptSecretsType.Host) { secrets = new HostSecrets() { MasterKey = new Key("master", "test"), FunctionKeys = new List <Key>() { new Key(KeyName, "test") }, SystemKeys = new List <Key>() { new Key(KeyName, "test") } }; } else { secrets = new FunctionSecrets() { Keys = new List <Key>() { new Key(KeyName, "test") } }; } string testFunctionName = secretsType == ScriptSecretsType.Host ? null : functionName; var target = _fixture.GetNewSecretRepository(); await target.WriteAsync(secretsType, testFunctionName, secrets); string filePath = Path.Combine(directory.Path, $"{testFunctionName ?? "host"}.json"); if (repositoryType == SecretsRepositoryType.BlobStorage || repositoryType == SecretsRepositoryType.BlobStorageSas) { Assert.True(_fixture.MarkerFileExists(testFunctionName ?? "host")); } ScriptSecrets secrets1 = await _fixture.GetSecretText(testFunctionName ?? "host", secretsType); if (secretsType == ScriptSecretsType.Host) { Assert.Equal((secrets1 as HostSecrets).MasterKey.Name, "master"); Assert.Equal((secrets1 as HostSecrets).MasterKey.Value, "test"); Assert.Equal((secrets1 as HostSecrets).FunctionKeys[0].Name, KeyName); Assert.Equal((secrets1 as HostSecrets).FunctionKeys[0].Value, "test"); Assert.Equal((secrets1 as HostSecrets).SystemKeys[0].Name, KeyName); Assert.Equal((secrets1 as HostSecrets).SystemKeys[0].Value, "test"); } else { Assert.Equal((secrets1 as FunctionSecrets).Keys[0].Name, KeyName); Assert.Equal((secrets1 as FunctionSecrets).Keys[0].Value, "test"); } } }