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);
 }
Exemple #2
0
        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);
        }
Exemple #8
0
        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();
            }
        }
Exemple #9
0
        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);
        }
Exemple #11
0
        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();
            }
        }
Exemple #12
0
        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);
        }
Exemple #13
0
        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);
                }
            }
        }
Exemple #14
0
        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();
        }
Exemple #16
0
        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());
        }
Exemple #18
0
        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);
        }
Exemple #20
0
        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"]);
        }
Exemple #22
0
        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);
        }
Exemple #24
0
        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\"}]";
        }