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<ISecretManager>(MockBehavior.Strict); _hostSecrets = new HostSecretsInfo { MasterKey = testMasterKeyValue, FunctionKeys = new Dictionary<string, string> { { "1", TestHostFunctionKeyValue1 }, { "2", TestHostFunctionKeyValue2 } } }; _mockSecretManager.Setup(p => p.GetHostSecrets()).Returns(_hostSecrets); _functionSecrets = new Dictionary<string, string> { { "1", TestFunctionKeyValue1 }, { "2", TestFunctionKeyValue2 } }; _mockSecretManager.Setup(p => p.GetFunctionSecrets(It.IsAny<string>(), false)).Returns(_functionSecrets); mockDependencyResolver.Setup(p => p.GetService(typeof(ISecretManager))).Returns(_mockSecretManager.Object); }
public AuthorizationLevelAttributeTests() { HttpConfig = new HttpConfiguration(); _actionContext = CreateActionContext(typeof(TestController).GetMethod("Get"), HttpConfig); Mock <IDependencyResolver> mockDependencyResolver = new Mock <IDependencyResolver>(MockBehavior.Strict); HttpConfig.DependencyResolver = mockDependencyResolver.Object; MockSecretManager = new Mock <ISecretManager>(MockBehavior.Strict); _hostSecrets = new HostSecretsInfo { MasterKey = TestMasterKeyValue, FunctionKeys = new Dictionary <string, string> { { TestHostFunctionKeyName1, TestHostFunctionKeyValue1 }, { TestHostFunctionKeyName2, TestHostFunctionKeyValue2 } }, SystemKeys = new Dictionary <string, string> { { TestSystemKeyName1, TestSystemKeyValue1 }, { TestSystemKeyName2, TestSystemKeyValue2 } } }; MockSecretManager.Setup(p => p.GetHostSecretsAsync()).ReturnsAsync(_hostSecrets); _functionSecrets = new Dictionary <string, string> { { TestFunctionKeyName1, TestFunctionKeyValue1 }, { TestFunctionKeyName2, TestFunctionKeyValue2 } }; MockSecretManager.Setup(p => p.GetFunctionSecretsAsync(It.IsAny <string>(), false)).ReturnsAsync(_functionSecrets); mockDependencyResolver.Setup(p => p.GetService(typeof(ISecretManager))).Returns(MockSecretManager.Object); _webHostSettings = new WebHostSettings(); mockDependencyResolver.Setup(p => p.GetService(typeof(WebHostSettings))).Returns(_webHostSettings); }
public async Task GetHostSecretsAsync_WaitsForNewSecrets() { using (var directory = new TempDirectory()) { string hostSecretsJson = @"{ 'masterKey': { 'name': 'master', 'value': '1234', 'encrypted': false }, 'functionKeys': [], 'systemKeys': [] }"; string filePath = Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName); File.WriteAllText(filePath, hostSecretsJson); HostSecretsInfo hostSecrets = null; using (var secretManager = CreateSecretManager(directory.Path)) { await Task.WhenAll( Task.Run(async() => { // Lock the file using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Write, FileShare.None)) { await Task.Delay(500); } }), Task.Run(async() => { await Task.Delay(100); hostSecrets = await secretManager.GetHostSecretsAsync(); })); Assert.Equal(hostSecrets.MasterKey, "1234"); } using (var secretManager = CreateSecretManager(directory.Path)) { await Assert.ThrowsAsync <IOException>(async() => { await Task.WhenAll( Task.Run(async() => { // Lock the file using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Write, FileShare.None)) { await Task.Delay(3000); } }), Task.Run(async() => { await Task.Delay(100); hostSecrets = await secretManager.GetHostSecretsAsync(); })); }); } } }
public WebFunctionsManagerTests() { _testRootScriptPath = Path.GetTempPath(); _testHostConfigFilePath = Path.Combine(_testRootScriptPath, ScriptConstants.HostMetadataFileName); FileUtility.DeleteFileSafe(_testHostConfigFilePath); _hostOptions = new ScriptApplicationHostOptions { ScriptPath = @"x:\root", IsSelfHost = false, LogPath = @"x:\tmp\log", SecretsPath = @"x:\secrets", TestDataPath = @"x:\test" }; string functionsPath = Path.Combine(Environment.CurrentDirectory, @"..\..\..\..\..\sample"); var fileSystem = CreateFileSystem(_hostOptions); var loggerFactory = MockNullLoggerFactory.CreateLoggerFactory(); var contentBuilder = new StringBuilder(); var httpClient = CreateHttpClient(contentBuilder); var factory = new TestOptionsFactory <ScriptApplicationHostOptions>(_hostOptions); var tokenSource = new TestChangeTokenSource <ScriptApplicationHostOptions>(); var changeTokens = new[] { tokenSource }; var optionsMonitor = new OptionsMonitor <ScriptApplicationHostOptions>(factory, changeTokens, factory); var secretManagerProviderMock = new Mock <ISecretManagerProvider>(MockBehavior.Strict); var secretManagerMock = new Mock <ISecretManager>(MockBehavior.Strict); secretManagerProviderMock.SetupGet(p => p.Current).Returns(secretManagerMock.Object); var hostSecretsInfo = new HostSecretsInfo(); secretManagerMock.Setup(p => p.GetHostSecretsAsync()).ReturnsAsync(hostSecretsInfo); Dictionary <string, string> functionSecrets = new Dictionary <string, string>(); secretManagerMock.Setup(p => p.GetFunctionSecretsAsync("httptrigger", false)).ReturnsAsync(functionSecrets); var configurationMock = new Mock <IConfiguration>(MockBehavior.Strict); var hostIdProviderMock = new Mock <IHostIdProvider>(MockBehavior.Strict); var mockWebHostEnvironment = new Mock <IScriptWebHostEnvironment>(MockBehavior.Strict); mockWebHostEnvironment.SetupGet(p => p.InStandbyMode).Returns(false); _mockEnvironment = new Mock <IEnvironment>(MockBehavior.Strict); _mockEnvironment.Setup(p => p.GetEnvironmentVariable(EnvironmentSettingNames.AzureWebsiteContainerReady)).Returns("1"); _mockEnvironment.Setup(p => p.GetEnvironmentVariable(EnvironmentSettingNames.CoreToolsEnvironment)).Returns((string)null); _mockEnvironment.Setup(p => p.GetEnvironmentVariable(EnvironmentSettingNames.AzureWebsiteHostName)).Returns(TestHostName); var hostNameProvider = new HostNameProvider(_mockEnvironment.Object, loggerFactory.CreateLogger <HostNameProvider>()); var workerOptions = new LanguageWorkerOptions(); FileUtility.Instance = fileSystem; _fileSystem = fileSystem; var languageWorkerOptions = new OptionsWrapper <LanguageWorkerOptions>(CreateLanguageWorkerConfigSettings()); var metadataProvider = new FunctionMetadataProvider(optionsMonitor, languageWorkerOptions, NullLogger <FunctionMetadataProvider> .Instance, new TestMetricsLogger()); var functionsSyncManager = new FunctionsSyncManager(configurationMock.Object, hostIdProviderMock.Object, optionsMonitor, loggerFactory.CreateLogger <FunctionsSyncManager>(), httpClient, secretManagerProviderMock.Object, mockWebHostEnvironment.Object, _mockEnvironment.Object, hostNameProvider, metadataProvider); _webFunctionsManager = new WebFunctionsManager(optionsMonitor, new OptionsWrapper <LanguageWorkerOptions>(CreateLanguageWorkerConfigSettings()), loggerFactory, httpClient, secretManagerProviderMock.Object, functionsSyncManager, hostNameProvider, metadataProvider); }
internal static async Task <KeyAuthorizationResult> GetAuthorizationResultAsync(HttpRequestMessage request, ISecretManager secretManager, Func <IDictionary <string, string>, string, string, string> matchEvaluator, string keyName = null, string functionName = null) { // first see if a key value is specified via headers or query string (header takes precedence) IEnumerable <string> values; string keyValue = null; if (request.Headers.TryGetValues(FunctionsKeyHeaderName, out values)) { keyValue = values.FirstOrDefault(); } else { var queryParameters = request.GetQueryParameterDictionary(); queryParameters.TryGetValue("code", out keyValue); } if (!string.IsNullOrEmpty(keyValue)) { // see if the key specified is the master key HostSecretsInfo hostSecrets = await secretManager.GetHostSecretsAsync().ConfigureAwait(false); if (!string.IsNullOrEmpty(hostSecrets.MasterKey) && Key.SecretValueEquals(keyValue, hostSecrets.MasterKey)) { return(new KeyAuthorizationResult(ScriptConstants.DefaultMasterKeyName, AuthorizationLevel.Admin)); } string matchedKeyName = matchEvaluator(hostSecrets.SystemKeys, keyName, keyValue); if (matchedKeyName != null) { return(new KeyAuthorizationResult(matchedKeyName, AuthorizationLevel.System)); } // see if the key specified matches the host function key matchedKeyName = matchEvaluator(hostSecrets.FunctionKeys, keyName, keyValue); if (matchedKeyName != null) { return(new KeyAuthorizationResult(matchedKeyName, AuthorizationLevel.Function)); } // if there is a function specific key specified try to match against that if (functionName != null) { var functionSecrets = await secretManager.GetFunctionSecretsAsync(functionName); matchedKeyName = matchEvaluator(functionSecrets, keyName, keyValue); if (matchedKeyName != null) { return(new KeyAuthorizationResult(matchedKeyName, AuthorizationLevel.Function)); } } } return(new KeyAuthorizationResult(null, AuthorizationLevel.Anonymous)); }
public async Task <HostStatus> GetHostStatusAsync() { HostSecretsInfo secrets = await SecretManager.GetHostSecretsAsync(); string uri = $"admin/host/status?code={secrets.MasterKey}"; HttpResponseMessage response = await HttpClient.GetAsync(uri); response.EnsureSuccessStatusCode(); return(await response.Content.ReadAsAsync <HostStatus>()); }
public DefaultScriptWebHookProviderTests() { _mockSecretManager = new Mock <ISecretManager>(MockBehavior.Strict); _hostSecrets = new HostSecretsInfo(); _mockSecretManager.Setup(p => p.GetHostSecretsAsync()).ReturnsAsync(_hostSecrets); var mockSecretManagerProvider = new Mock <ISecretManagerProvider>(MockBehavior.Strict); mockSecretManagerProvider.Setup(p => p.Current).Returns(_mockSecretManager.Object); _webHookProvider = new DefaultScriptWebHookProvider(mockSecretManagerProvider.Object); }
public async Task SyncRead_Succeeds_WithFlag() { using (var host = GetHost(d => d.Add(EnvironmentSettingNames.AzureWebJobsFeatureFlags, ScriptConstants.FeatureFlagAllowSynchronousIO))) { HostSecretsInfo secrets = await host.SecretManager.GetHostSecretsAsync(); var response = await MakeRequest(host.HttpClient, secrets.MasterKey); response.EnsureSuccessStatusCode(); } }
public async Task SyncDownload_Succeeds() { using (var host = GetHost()) { HostSecretsInfo secrets = await host.SecretManager.GetHostSecretsAsync(); var response = await MakeDownloadRequest(host.HttpClient, secrets.MasterKey); response.EnsureSuccessStatusCode(); Assert.True(response.Content.Headers.ContentLength > 0); } }
internal static async Task <(string, AuthorizationLevel)> GetAuthorizationKeyInfoAsync(HttpRequest request, ISecretManagerProvider secretManagerProvider) { // first see if a key value is specified via headers or query string (header takes precedence) string keyValue = null; if (request.Headers.TryGetValue(FunctionsKeyHeaderName, out StringValues values)) { keyValue = values.First(); } else if (request.Query.TryGetValue("code", out values)) { keyValue = values.First(); } if (!string.IsNullOrEmpty(keyValue)) { ISecretManager secretManager = secretManagerProvider.Current; // see if the key specified is the master key HostSecretsInfo hostSecrets = await secretManager.GetHostSecretsAsync().ConfigureAwait(false); if (!string.IsNullOrEmpty(hostSecrets.MasterKey) && Key.SecretValueEquals(keyValue, hostSecrets.MasterKey)) { return(ScriptConstants.DefaultMasterKeyName, AuthorizationLevel.Admin); } if (HasMatchingKey(hostSecrets.SystemKeys, keyValue, out string keyName)) { return(keyName, AuthorizationLevel.System); } // see if the key specified matches the host function key if (HasMatchingKey(hostSecrets.FunctionKeys, keyValue, out keyName)) { return(keyName, AuthorizationLevel.Function); } // If there is a function specific key specified try to match against that IFunctionExecutionFeature executionFeature = request.HttpContext.Features.Get <IFunctionExecutionFeature>(); if (executionFeature != null) { IDictionary <string, string> functionSecrets = await secretManager.GetFunctionSecretsAsync(executionFeature.Descriptor.Name); if (HasMatchingKey(functionSecrets, keyValue, out keyName)) { return(keyName, AuthorizationLevel.Function); } } } return(null, AuthorizationLevel.Anonymous); }
public async Task SyncRead_Succeeds_InV2CompatMode() { using (var host = GetHost(d => d.Add(EnvironmentSettingNames.FunctionsV2CompatibilityModeKey, "true"))) { HostSecretsInfo secrets = await host.SecretManager.GetHostSecretsAsync(); var response = await MakeRequest(host.HttpClient, secrets.MasterKey); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); } }
internal static async Task <AuthorizationLevel> GetAuthorizationLevelAsync(HttpRequestMessage request, ISecretManager 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 precedence) IEnumerable <string> values; string keyValue = null; if (request.Headers.TryGetValues(FunctionsKeyHeaderName, out values)) { keyValue = values.FirstOrDefault(); } else { var queryParameters = request.GetQueryParameterDictionary(); queryParameters.TryGetValue("code", out keyValue); } if (!string.IsNullOrEmpty(keyValue)) { // see if the key specified is the master key HostSecretsInfo hostSecrets = await secretManager.GetHostSecretsAsync().ConfigureAwait(false); if (!string.IsNullOrEmpty(hostSecrets.MasterKey) && Key.SecretValueEquals(keyValue, hostSecrets.MasterKey)) { return(AuthorizationLevel.Admin); } // see if the key specified matches the host function key if (hostSecrets.FunctionKeys != null && hostSecrets.FunctionKeys.Any(k => Key.SecretValueEquals(keyValue, k.Value))) { return(AuthorizationLevel.Function); } // if there is a function specific key specified try to match against that if (functionName != null) { IDictionary <string, string> functionSecrets = await secretManager.GetFunctionSecretsAsync(functionName); if (functionSecrets != null && functionSecrets.Values.Any(s => Key.SecretValueEquals(keyValue, s))) { return(AuthorizationLevel.Function); } } } return(AuthorizationLevel.Anonymous); }
private async Task <bool> IsHostRunning(HttpClient client) { HostSecretsInfo secrets = await SecretManager.GetHostSecretsAsync(); // Workaround for https://github.com/Azure/azure-functions-host/issues/2397 as the base URL // doesn't currently start the host. // Note: the master key "1234" is from the TestSecretManager. using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, $"/admin/functions/dummyName/status?code={secrets.MasterKey}")) { using (HttpResponseMessage response = await client.SendAsync(request)) { return(response.StatusCode == HttpStatusCode.NoContent || response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.NotFound); } } }
public async Task SyncRead_Fails_ByDefault() { using (var host = GetHost()) { HostSecretsInfo secrets = await host.SecretManager.GetHostSecretsAsync(); var response = await MakeRequest(host.HttpClient, secrets.MasterKey); Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode); var a = host.GetScriptHostLogMessages().Select(p => p.Exception?.ToString()); Assert.Contains(host.GetScriptHostLogMessages(), p => p.Exception != null && p.Exception.ToString().Contains("Synchronous operations are disallowed.")); } }
public async Task BeginFunctionAsync(string functionName, JToken payload) { JObject wrappedPayload = new JObject { { "input", payload.ToString() } }; HostSecretsInfo secrets = await SecretManager.GetHostSecretsAsync(); string uri = $"admin/functions/{functionName}?code={secrets.MasterKey}"; HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, uri); request.Content = new StringContent(wrappedPayload.ToString(), Encoding.UTF8, "application/json"); HttpResponseMessage response = await HttpClient.SendAsync(request); response.EnsureSuccessStatusCode(); }
public DefaultScriptWebHookProviderTests() { _mockSecretManager = new Mock <ISecretManager>(MockBehavior.Strict); _hostSecrets = new HostSecretsInfo(); _mockSecretManager.Setup(p => p.GetHostSecretsAsync()).ReturnsAsync(_hostSecrets); var mockSecretManagerProvider = new Mock <ISecretManagerProvider>(MockBehavior.Strict); mockSecretManagerProvider.Setup(p => p.Current).Returns(_mockSecretManager.Object); var loggerProvider = new TestLoggerProvider(); var loggerFactory = new LoggerFactory(); loggerFactory.AddProvider(loggerProvider); var testEnvironment = new TestEnvironment(); testEnvironment.SetEnvironmentVariable(EnvironmentSettingNames.AzureWebsiteHostName, TestHostName); var hostNameProvider = new HostNameProvider(testEnvironment); _webHookProvider = new DefaultScriptWebHookProvider(mockSecretManagerProvider.Object, hostNameProvider); }
public void ReadFunctionsMetadataSucceeds() { string functionsPath = Path.Combine(Environment.CurrentDirectory, @"..\..\..\..\..\sample"); // Setup var fileSystem = CreateFileSystem(_hostOptions.ScriptPath); var loggerFactory = MockNullLoggerFactory.CreateLoggerFactory(); var contentBuilder = new StringBuilder(); var httpClient = CreateHttpClient(contentBuilder); var factory = new TestOptionsFactory <ScriptApplicationHostOptions>(_hostOptions); var tokenSource = new TestChangeTokenSource(); var changeTokens = new[] { tokenSource }; var optionsMonitor = new OptionsMonitor <ScriptApplicationHostOptions>(factory, changeTokens, factory); var secretManagerProviderMock = new Mock <ISecretManagerProvider>(MockBehavior.Strict); var secretManagerMock = new Mock <ISecretManager>(MockBehavior.Strict); secretManagerProviderMock.SetupGet(p => p.Current).Returns(secretManagerMock.Object); var hostSecretsInfo = new HostSecretsInfo(); secretManagerMock.Setup(p => p.GetHostSecretsAsync()).ReturnsAsync(hostSecretsInfo); Dictionary <string, string> functionSecrets = new Dictionary <string, string>(); secretManagerMock.Setup(p => p.GetFunctionSecretsAsync("httptrigger", false)).ReturnsAsync(functionSecrets); var configurationMock = new Mock <IConfiguration>(MockBehavior.Strict); var hostIdProviderMock = new Mock <IHostIdProvider>(MockBehavior.Strict); var mockWebHostEnvironment = new Mock <IScriptWebHostEnvironment>(MockBehavior.Strict); mockWebHostEnvironment.SetupGet(p => p.InStandbyMode).Returns(false); var mockEnvironment = new Mock <IEnvironment>(MockBehavior.Strict); mockEnvironment.Setup(p => p.GetEnvironmentVariable(EnvironmentSettingNames.AzureWebsiteContainerReady)).Returns("1"); mockEnvironment.Setup(p => p.GetEnvironmentVariable(EnvironmentSettingNames.CoreToolsEnvironment)).Returns((string)null); var functionsSyncManager = new FunctionsSyncManager(configurationMock.Object, hostIdProviderMock.Object, optionsMonitor, new OptionsWrapper <LanguageWorkerOptions>(CreateLanguageWorkerConfigSettings()), loggerFactory, httpClient, secretManagerProviderMock.Object, mockWebHostEnvironment.Object, mockEnvironment.Object); var webManager = new WebFunctionsManager(optionsMonitor, new OptionsWrapper <LanguageWorkerOptions>(CreateLanguageWorkerConfigSettings()), loggerFactory, httpClient, secretManagerProviderMock.Object, functionsSyncManager); FileUtility.Instance = fileSystem; IEnumerable <FunctionMetadata> metadata = webManager.GetFunctionsMetadata(); var jsFunctions = metadata.Where(funcMetadata => funcMetadata.Language == LanguageWorkerConstants.NodeLanguageWorkerName).ToList(); var unknownFunctions = metadata.Where(funcMetadata => string.IsNullOrEmpty(funcMetadata.Language)).ToList(); Assert.Equal(2, jsFunctions.Count()); Assert.Equal(1, unknownFunctions.Count()); }
private static DefaultScriptWebHookProvider CreateDefaultScriptWebHookProvider(out Mock <ISecretManager> mockSecretManager, out HostSecretsInfo hostSecrets) { mockSecretManager = new Mock <ISecretManager>(MockBehavior.Strict); hostSecrets = new HostSecretsInfo(); hostSecrets.SystemKeys = new Dictionary <string, string>(); hostSecrets.FunctionKeys = new Dictionary <string, string>(); var mockSecretManagerProvider = new Mock <ISecretManagerProvider>(MockBehavior.Strict); mockSecretManagerProvider.Setup(p => p.Current).Returns(mockSecretManager.Object); var loggerProvider = new TestLoggerProvider(); var loggerFactory = new LoggerFactory(); loggerFactory.AddProvider(loggerProvider); var testEnvironment = new TestEnvironment(); testEnvironment.SetEnvironmentVariable(EnvironmentSettingNames.AzureWebsiteHostName, TestHostName); var hostNameProvider = new HostNameProvider(testEnvironment); return(new DefaultScriptWebHookProvider(mockSecretManagerProvider.Object, hostNameProvider)); }
private async Task <bool> IsHostStarted(HttpClient client) { //HostStatus status = await GetHostStatusAsync(); //return status.State == $"{ScriptHostState.Running}" || status.State == $"{ScriptHostState.Error}"; HostSecretsInfo secrets = await SecretManager.GetHostSecretsAsync(); // Workaround for https://github.com/Azure/azure-functions-host/issues/2397 as the base URL // doesn't currently start the host. // Note: the master key "1234" is from the TestSecretManager. using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, $"/admin/functions/dummyName/status?code={secrets.MasterKey}")) { using (HttpResponseMessage response = await client.SendAsync(request)) { //return response.StatusCode == HttpStatusCode.NoContent || response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.NotFound; // Throw away this response. } } return(_hostService.State == ScriptHostState.Running || _hostService.State == ScriptHostState.Error); }
public async Task InstallBindingExtension(string packageName, string packageVersion) { HostSecretsInfo secrets = await SecretManager.GetHostSecretsAsync(); string uri = $"admin/host/extensions?code={secrets.MasterKey}"; HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, uri); string payload = new JObject { { "id", packageName }, { "version", packageVersion } }.ToString(Newtonsoft.Json.Formatting.None); request.Content = new StringContent(payload, Encoding.UTF8, "application/json"); var response = await HttpClient.SendAsync(request); var jobStatusUri = response.Headers.Location; string status = null; do { await Task.Delay(500); response = await CheckExtensionInstallStatus(jobStatusUri); var jobStatus = await response.Content.ReadAsAsync <JObject>(); status = jobStatus["status"].ToString(); } while (status == "Started"); if (status != "Succeeded") { throw new InvalidOperationException("Failed to install extension."); } // TODO: Find a better way to ensure the site has restarted. await Task.Delay(3000); }
public async Task GenericWebHook_Post_NamedKey_Headers_Succeeds() { // Authenticate using values specified via headers, // rather than URI query params string uri = "api/webhook-generic"; HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, uri); HostSecretsInfo secrets = await _fixture.Host.SecretManager.GetHostSecretsAsync(); request.Headers.Add(AuthenticationLevelHandler.FunctionsKeyHeaderName, secrets.MasterKey); request.Headers.Add("x-functions-clientid", "testclient"); request.Content = new StringContent("{ 'value': 'Foobar' }"); request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); HttpResponseMessage response = await _fixture.Host.HttpClient.SendAsync(request); Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal("application/json", response.Content.Headers.ContentType.MediaType); string body = await response.Content.ReadAsStringAsync(); JObject jsonObject = JObject.Parse(body); Assert.Equal("Value: Foobar", jsonObject["result"]); }
public FunctionsSyncManagerTests() { _testRootScriptPath = Path.GetTempPath(); _testHostConfigFilePath = Path.Combine(_testRootScriptPath, ScriptConstants.HostMetadataFileName); FileUtility.DeleteFileSafe(_testHostConfigFilePath); _hostOptions = new ScriptApplicationHostOptions { ScriptPath = @"x:\root", IsSelfHost = false, LogPath = @"x:\tmp\log", SecretsPath = @"x:\secrets", TestDataPath = @"x:\sampledata" }; var jobHostOptions = new ScriptJobHostOptions { RootScriptPath = _hostOptions.ScriptPath, RootLogPath = _hostOptions.LogPath }; string testHostName = "appName.azurewebsites.net"; _vars = new Dictionary <string, string> { { EnvironmentSettingNames.WebSiteAuthEncryptionKey, TestHelpers.GenerateKeyHexString() }, { EnvironmentSettingNames.AzureWebsiteHostName, testHostName } }; ResetMockFileSystem(); _loggerProvider = new TestLoggerProvider(); var loggerFactory = new LoggerFactory(); loggerFactory.AddProvider(_loggerProvider); _contentBuilder = new StringBuilder(); _mockHttpHandler = new MockHttpHandler(_contentBuilder); var httpClient = CreateHttpClient(_mockHttpHandler); var factory = new TestOptionsFactory <ScriptApplicationHostOptions>(_hostOptions); var tokenSource = new TestChangeTokenSource <ScriptApplicationHostOptions>(); var changeTokens = new[] { tokenSource }; var optionsMonitor = new OptionsMonitor <ScriptApplicationHostOptions>(factory, changeTokens, factory); var secretManagerProviderMock = new Mock <ISecretManagerProvider>(MockBehavior.Strict); var secretManagerMock = new Mock <ISecretManager>(MockBehavior.Strict); secretManagerProviderMock.SetupGet(p => p.Current).Returns(secretManagerMock.Object); var hostSecretsInfo = new HostSecretsInfo(); hostSecretsInfo.MasterKey = "aaa"; hostSecretsInfo.FunctionKeys = new Dictionary <string, string> { { "TestHostFunctionKey1", "aaa" }, { "TestHostFunctionKey2", "bbb" } }; hostSecretsInfo.SystemKeys = new Dictionary <string, string> { { "TestSystemKey1", "aaa" }, { "TestSystemKey2", "bbb" } }; secretManagerMock.Setup(p => p.GetHostSecretsAsync()).ReturnsAsync(hostSecretsInfo); Dictionary <string, string> functionSecretsResponse = new Dictionary <string, string>() { { "TestFunctionKey1", "aaa" }, { "TestFunctionKey2", "bbb" } }; secretManagerMock.Setup(p => p.GetFunctionSecretsAsync("function1", false)).ReturnsAsync(functionSecretsResponse); var configuration = ScriptSettingsManager.BuildDefaultConfiguration(); var hostIdProviderMock = new Mock <IHostIdProvider>(MockBehavior.Strict); hostIdProviderMock.Setup(p => p.GetHostIdAsync(CancellationToken.None)).ReturnsAsync("testhostid123"); _mockWebHostEnvironment = new Mock <IScriptWebHostEnvironment>(MockBehavior.Strict); _mockWebHostEnvironment.SetupGet(p => p.InStandbyMode).Returns(false); _mockEnvironment = new Mock <IEnvironment>(MockBehavior.Strict); _mockEnvironment.Setup(p => p.GetEnvironmentVariable(EnvironmentSettingNames.AzureWebsiteArmCacheEnabled)).Returns("1"); _mockEnvironment.Setup(p => p.GetEnvironmentVariable(EnvironmentSettingNames.AzureWebsiteContainerReady)).Returns("1"); _mockEnvironment.Setup(p => p.GetEnvironmentVariable(EnvironmentSettingNames.CoreToolsEnvironment)).Returns((string)null); _mockEnvironment.Setup(p => p.GetEnvironmentVariable(EnvironmentSettingNames.WebSiteAuthEncryptionKey)).Returns("1"); _mockEnvironment.Setup(p => p.GetEnvironmentVariable(EnvironmentSettingNames.AzureWebsiteInstanceId)).Returns("1"); _mockEnvironment.Setup(p => p.GetEnvironmentVariable(EnvironmentSettingNames.AzureWebsiteHostName)).Returns(testHostName); _mockEnvironment.Setup(p => p.GetEnvironmentVariable(EnvironmentSettingNames.SkipSslValidation)).Returns((string)null); _mockEnvironment.Setup(p => p.GetEnvironmentVariable(EnvironmentSettingNames.AzureWebJobsSecretStorageType)).Returns("blob"); _mockEnvironment.Setup(p => p.GetEnvironmentVariable(EnvironmentSettingNames.KubernetesServiceHost)).Returns(""); _mockEnvironment.Setup(p => p.GetEnvironmentVariable(EnvironmentSettingNames.PodNamespace)).Returns(""); _hostNameProvider = new HostNameProvider(_mockEnvironment.Object); var functionMetadataProvider = new FunctionMetadataProvider(optionsMonitor, NullLogger <FunctionMetadataProvider> .Instance, new TestMetricsLogger()); var functionMetadataManager = TestFunctionMetadataManager.GetFunctionMetadataManager(new OptionsWrapper <ScriptJobHostOptions>(jobHostOptions), functionMetadataProvider, null, new OptionsWrapper <HttpWorkerOptions>(new HttpWorkerOptions()), loggerFactory, new OptionsWrapper <LanguageWorkerOptions>(CreateLanguageWorkerConfigSettings())); _functionsSyncManager = new FunctionsSyncManager(configuration, hostIdProviderMock.Object, optionsMonitor, loggerFactory.CreateLogger <FunctionsSyncManager>(), httpClient, secretManagerProviderMock.Object, _mockWebHostEnvironment.Object, _mockEnvironment.Object, _hostNameProvider, functionMetadataManager); }
public async Task <string> GetMasterKeyAsync() { HostSecretsInfo secrets = await SecretManager.GetHostSecretsAsync(); return(secrets.MasterKey); }
public FunctionsSyncManagerTests() { _testRootScriptPath = Path.GetTempPath(); _testHostConfigFilePath = Path.Combine(_testRootScriptPath, ScriptConstants.HostMetadataFileName); FileUtility.DeleteFileSafe(_testHostConfigFilePath); _hostOptions = new ScriptApplicationHostOptions { ScriptPath = @"x:\root", IsSelfHost = false, LogPath = @"x:\tmp\log", SecretsPath = @"x:\secrets", TestDataPath = @"x:\sampledata" }; string testHostName = "appName.azurewebsites.net"; _vars = new Dictionary <string, string> { { EnvironmentSettingNames.WebSiteAuthEncryptionKey, TestHelpers.GenerateKeyHexString() }, { EnvironmentSettingNames.AzureWebsiteHostName, testHostName } }; ResetMockFileSystem(); _loggerProvider = new TestLoggerProvider(); var loggerFactory = new LoggerFactory(); loggerFactory.AddProvider(_loggerProvider); _contentBuilder = new StringBuilder(); _mockHttpHandler = new MockHttpHandler(_contentBuilder); var httpClient = CreateHttpClient(_mockHttpHandler); var factory = new TestOptionsFactory <ScriptApplicationHostOptions>(_hostOptions); var tokenSource = new TestChangeTokenSource(); var changeTokens = new[] { tokenSource }; var optionsMonitor = new OptionsMonitor <ScriptApplicationHostOptions>(factory, changeTokens, factory); var secretManagerProviderMock = new Mock <ISecretManagerProvider>(MockBehavior.Strict); var secretManagerMock = new Mock <ISecretManager>(MockBehavior.Strict); secretManagerProviderMock.SetupGet(p => p.Current).Returns(secretManagerMock.Object); var hostSecretsInfo = new HostSecretsInfo(); hostSecretsInfo.MasterKey = "aaa"; hostSecretsInfo.FunctionKeys = new Dictionary <string, string> { { "TestHostFunctionKey1", "aaa" }, { "TestHostFunctionKey2", "bbb" } }; hostSecretsInfo.SystemKeys = new Dictionary <string, string> { { "TestSystemKey1", "aaa" }, { "TestSystemKey2", "bbb" } }; secretManagerMock.Setup(p => p.GetHostSecretsAsync()).ReturnsAsync(hostSecretsInfo); Dictionary <string, string> functionSecretsResponse = new Dictionary <string, string>() { { "TestFunctionKey1", "aaa" }, { "TestFunctionKey2", "bbb" } }; secretManagerMock.Setup(p => p.GetFunctionSecretsAsync("function1", false)).ReturnsAsync(functionSecretsResponse); var configuration = ScriptSettingsManager.BuildDefaultConfiguration(); var hostIdProviderMock = new Mock <IHostIdProvider>(MockBehavior.Strict); hostIdProviderMock.Setup(p => p.GetHostIdAsync(CancellationToken.None)).ReturnsAsync("testhostid123"); _mockWebHostEnvironment = new Mock <IScriptWebHostEnvironment>(MockBehavior.Strict); _mockWebHostEnvironment.SetupGet(p => p.InStandbyMode).Returns(false); _mockEnvironment = new Mock <IEnvironment>(MockBehavior.Strict); _mockEnvironment.Setup(p => p.GetEnvironmentVariable(EnvironmentSettingNames.AzureWebsiteArmCacheEnabled)).Returns("1"); _mockEnvironment.Setup(p => p.GetEnvironmentVariable(EnvironmentSettingNames.AzureWebsiteContainerReady)).Returns("1"); _mockEnvironment.Setup(p => p.GetEnvironmentVariable(EnvironmentSettingNames.CoreToolsEnvironment)).Returns((string)null); _mockEnvironment.Setup(p => p.GetEnvironmentVariable(EnvironmentSettingNames.WebSiteAuthEncryptionKey)).Returns("1"); _mockEnvironment.Setup(p => p.GetEnvironmentVariable(EnvironmentSettingNames.AzureWebsiteInstanceId)).Returns("1"); _mockEnvironment.Setup(p => p.GetEnvironmentVariable(EnvironmentSettingNames.AzureWebsiteHostName)).Returns(testHostName); _mockEnvironment.Setup(p => p.GetEnvironmentVariable(EnvironmentSettingNames.SkipSslValidation)).Returns((string)null); _mockEnvironment.Setup(p => p.GetEnvironmentVariable(EnvironmentSettingNames.AzureWebJobsSecretStorageType)).Returns("blob"); _hostNameProvider = new HostNameProvider(_mockEnvironment.Object, loggerFactory.CreateLogger <HostNameProvider>()); _functionsSyncManager = new FunctionsSyncManager(configuration, hostIdProviderMock.Object, optionsMonitor, new OptionsWrapper <LanguageWorkerOptions>(CreateLanguageWorkerConfigSettings()), loggerFactory.CreateLogger <FunctionsSyncManager>(), httpClient, secretManagerProviderMock.Object, _mockWebHostEnvironment.Object, _mockEnvironment.Object, _hostNameProvider); _expectedSyncTriggersPayload = "[{\"authLevel\":\"anonymous\",\"type\":\"httpTrigger\",\"direction\":\"in\",\"name\":\"req\",\"functionName\":\"function1\"}," + "{\"name\":\"myQueueItem\",\"type\":\"orchestrationTrigger\",\"direction\":\"in\",\"queueName\":\"myqueue-items\",\"connection\":\"DurableStorage\",\"functionName\":\"function2\",\"taskHubName\":\"TestHubValue\"}," + "{\"name\":\"myQueueItem\",\"type\":\"activityTrigger\",\"direction\":\"in\",\"queueName\":\"myqueue-items\",\"connection\":\"DurableStorage\",\"functionName\":\"function3\",\"taskHubName\":\"TestHubValue\"}]"; }