Пример #1
0
        public async Task Assignment_Succeeds_With_Encryption_Key()
        {
            var environment = new TestEnvironment();

            environment.SetEnvironmentVariable(EnvironmentSettingNames.AzureWebsitePlaceholderMode, "1");

            var scriptWebEnvironment = new ScriptWebHostEnvironment(environment);

            var loggerFactory  = new LoggerFactory();
            var loggerProvider = new TestLoggerProvider();

            loggerFactory.AddProvider(loggerProvider);

            var handlerMock = new Mock <HttpMessageHandler>(MockBehavior.Strict);

            handlerMock.Protected().Setup <Task <HttpResponseMessage> >("SendAsync",
                                                                        ItExpr.IsAny <HttpRequestMessage>(),
                                                                        ItExpr.IsAny <CancellationToken>()).ReturnsAsync(new HttpResponseMessage
            {
                StatusCode = HttpStatusCode.OK
            });

            var instanceManager = new InstanceManager(_optionsFactory, TestHelpers.CreateHttpClientFactory(handlerMock.Object),
                                                      scriptWebEnvironment, environment, loggerFactory.CreateLogger <InstanceManager>(),
                                                      new TestMetricsLogger(), null, new Mock <IRunFromPackageHandler>().Object,
                                                      new Mock <IPackageDownloadHandler>(MockBehavior.Strict).Object);
            var startupContextProvider = new StartupContextProvider(environment, loggerFactory.CreateLogger <StartupContextProvider>());

            InstanceManager.Reset();

            var podController = new KubernetesPodController(environment, instanceManager, loggerFactory, startupContextProvider);

            const string podEncryptionKey      = "/a/vXvWJ3Hzgx4PFxlDUJJhQm5QVyGiu0NNLFm/ZMMg=";
            var          hostAssignmentContext = new HostAssignmentContext
            {
                Environment = new Dictionary <string, string>()
                {
                    [EnvironmentSettingNames.AzureWebsiteRunFromPackage] = "http://localhost:1234"
                }
            };

            hostAssignmentContext.Secrets         = new FunctionAppSecrets();
            hostAssignmentContext.IsWarmupRequest = false;

            var encryptedHostAssignmentValue = SimpleWebTokenHelper.Encrypt(JsonConvert.SerializeObject(hostAssignmentContext), podEncryptionKey.ToKeyBytes());

            var encryptedHostAssignmentContext = new EncryptedHostAssignmentContext()
            {
                EncryptedContext = encryptedHostAssignmentValue
            };

            environment.SetEnvironmentVariable(EnvironmentSettingNames.PodEncryptionKey, podEncryptionKey);
            environment.SetEnvironmentVariable(EnvironmentSettingNames.KubernetesServiceHost, "http://localhost:80");
            environment.SetEnvironmentVariable(EnvironmentSettingNames.PodNamespace, "k8se-apps");

            var result = await podController.Assign(encryptedHostAssignmentContext);

            Assert.NotNull(startupContextProvider.Context);
            Assert.IsType <AcceptedResult>(result);
        }
        public void SetContext_AppliesHostAssignmentContext()
        {
            var context = new HostAssignmentContext
            {
                Environment = new Dictionary <string, string>(),
                SiteName    = "TestSite",
                Secrets     = _secrets
            };
            string json             = JsonConvert.SerializeObject(context);
            string encrypted        = SimpleWebTokenHelper.Encrypt(json, environment: _environment);
            var    encryptedContext = new EncryptedHostAssignmentContext {
                EncryptedContext = encrypted
            };

            var result = _startupContextProvider.SetContext(encryptedContext);

            Assert.Equal(context.SiteName, result.SiteName);
            Assert.Equal(_secrets.Host.Master, result.Secrets.Host.Master);

            var secrets = _startupContextProvider.GetHostSecretsOrNull();

            Assert.Equal(_secrets.Host.Master, secrets.MasterKey);
            Assert.Equal(_secrets.Host.Function, secrets.FunctionKeys);
            Assert.Equal(_secrets.Host.System, secrets.SystemKeys);
        }
Пример #3
0
 private static string GetEncryptedHostAssignmentContext(HostAssignmentContext hostAssignmentContext, string containerEncryptionKey)
 {
     using (var env = new TestScopedEnvironmentVariable(WebSiteAuthEncryptionKey, containerEncryptionKey))
     {
         var serializeObject = JsonConvert.SerializeObject(hostAssignmentContext);
         return(SimpleWebTokenHelper.Encrypt(serializeObject));
     }
 }
Пример #4
0
        public async Task Assign_MSISpecializationFailure_ReturnsError()
        {
            var environment = new TestEnvironment();

            environment.SetEnvironmentVariable(EnvironmentSettingNames.AzureWebsitePlaceholderMode, "1");

            var scriptWebEnvironment = new ScriptWebHostEnvironment(environment);

            var loggerFactory  = new LoggerFactory();
            var loggerProvider = new TestLoggerProvider();

            loggerFactory.AddProvider(loggerProvider);

            var handlerMock = new Mock <HttpMessageHandler>(MockBehavior.Strict);

            handlerMock.Protected().Setup <Task <HttpResponseMessage> >("SendAsync",
                                                                        ItExpr.IsAny <HttpRequestMessage>(),
                                                                        ItExpr.IsAny <CancellationToken>()).ReturnsAsync(new HttpResponseMessage
            {
                StatusCode = HttpStatusCode.BadRequest
            });

            var instanceManager = new InstanceManager(_optionsFactory, new HttpClient(handlerMock.Object),
                                                      scriptWebEnvironment, environment, loggerFactory.CreateLogger <InstanceManager>(),
                                                      new TestMetricsLogger(), null, _runFromPackageHandler.Object);
            var startupContextProvider = new StartupContextProvider(environment, loggerFactory.CreateLogger <StartupContextProvider>());

            InstanceManager.Reset();

            var instanceController = new InstanceController(environment, instanceManager, loggerFactory, startupContextProvider);

            const string containerEncryptionKey = "/a/vXvWJ3Hzgx4PFxlDUJJhQm5QVyGiu0NNLFm/ZMMg=";
            var          hostAssignmentContext  = new HostAssignmentContext
            {
                Environment = new Dictionary <string, string>(),
                MSIContext  = new MSIContext()
            };

            hostAssignmentContext.Environment[EnvironmentSettingNames.MsiEndpoint] = "http://localhost:8081";
            hostAssignmentContext.Environment[EnvironmentSettingNames.MsiSecret]   = "secret";

            var encryptedHostAssignmentValue = SimpleWebTokenHelper.Encrypt(JsonConvert.SerializeObject(hostAssignmentContext), containerEncryptionKey.ToKeyBytes());

            var encryptedHostAssignmentContext = new EncryptedHostAssignmentContext()
            {
                EncryptedContext = encryptedHostAssignmentValue
            };

            environment.SetEnvironmentVariable(EnvironmentSettingNames.ContainerEncryptionKey, containerEncryptionKey);

            IActionResult result = await instanceController.Assign(encryptedHostAssignmentContext);

            var objectResult = result as ObjectResult;

            Assert.Equal(objectResult.StatusCode, 500);
            Assert.Equal(objectResult.Value, "Specialize MSI sidecar call failed. StatusCode=BadRequest");
        }
Пример #5
0
        public async Task Assignment_Does_Not_Set_Secrets_Context_For_Warmup_Request()
        {
            var environment = new TestEnvironment();

            environment.SetEnvironmentVariable(EnvironmentSettingNames.AzureWebsitePlaceholderMode, "1");

            var scriptWebEnvironment = new ScriptWebHostEnvironment(environment);

            var loggerFactory  = new LoggerFactory();
            var loggerProvider = new TestLoggerProvider();

            loggerFactory.AddProvider(loggerProvider);

            var handlerMock = new Mock <HttpMessageHandler>(MockBehavior.Strict);

            handlerMock.Protected().Setup <Task <HttpResponseMessage> >("SendAsync",
                                                                        ItExpr.IsAny <HttpRequestMessage>(),
                                                                        ItExpr.IsAny <CancellationToken>()).ReturnsAsync(new HttpResponseMessage
            {
                StatusCode = HttpStatusCode.OK
            });

            var instanceManager = new InstanceManager(_optionsFactory, new HttpClient(handlerMock.Object),
                                                      scriptWebEnvironment, environment, loggerFactory.CreateLogger <InstanceManager>(),
                                                      new TestMetricsLogger(), null, _runFromPackageHandler.Object);
            var startupContextProvider = new StartupContextProvider(environment, loggerFactory.CreateLogger <StartupContextProvider>());

            InstanceManager.Reset();

            var instanceController = new InstanceController(environment, instanceManager, loggerFactory, startupContextProvider);

            const string containerEncryptionKey = "/a/vXvWJ3Hzgx4PFxlDUJJhQm5QVyGiu0NNLFm/ZMMg=";
            var          hostAssignmentContext  = new HostAssignmentContext
            {
                Environment = new Dictionary <string, string>()
                {
                    [EnvironmentSettingNames.AzureWebsiteRunFromPackage] = "http://localhost:1234"
                }
            };

            hostAssignmentContext.Secrets         = new FunctionAppSecrets();
            hostAssignmentContext.IsWarmupRequest = true; // Warmup Request

            var encryptedHostAssignmentValue = SimpleWebTokenHelper.Encrypt(JsonConvert.SerializeObject(hostAssignmentContext), containerEncryptionKey.ToKeyBytes());

            var encryptedHostAssignmentContext = new EncryptedHostAssignmentContext()
            {
                EncryptedContext = encryptedHostAssignmentValue
            };

            environment.SetEnvironmentVariable(EnvironmentSettingNames.ContainerEncryptionKey, containerEncryptionKey);

            await instanceController.Assign(encryptedHostAssignmentContext);

            Assert.Null(startupContextProvider.Context);
        }
Пример #6
0
        public static EncryptedHostAssignmentContext Create(HostAssignmentContext context, string key)
        {
            string json          = JsonConvert.SerializeObject(context);
            var    encryptionKey = Convert.FromBase64String(key);
            string encrypted     = SimpleWebTokenHelper.Encrypt(json, encryptionKey);

            return(new EncryptedHostAssignmentContext {
                EncryptedContext = encrypted
            });
        }
        private FunctionAppSecrets WriteStartContextCache(string path)
        {
            var secrets = new FunctionAppSecrets();

            secrets.Host = new FunctionAppSecrets.HostSecrets
            {
                Master = "test-master-key"
            };
            secrets.Host.Function = new Dictionary <string, string>
            {
                { "test-host-function-1", "hostfunction1value" },
                { "test-host-function-2", "hostfunction2value" }
            };
            secrets.Host.System = new Dictionary <string, string>
            {
                { "test-system-1", "system1value" },
                { "test-system-2", "system2value" }
            };
            secrets.Function = new FunctionAppSecrets.FunctionSecrets[]
            {
                new FunctionAppSecrets.FunctionSecrets
                {
                    Name    = "function1",
                    Secrets = new Dictionary <string, string>
                    {
                        { "test-function-1", "function1value" },
                        { "test-function-2", "function2value" }
                    }
                },
                new FunctionAppSecrets.FunctionSecrets
                {
                    Name    = "function2",
                    Secrets = new Dictionary <string, string>
                    {
                        { "test-function-1", "function1value" },
                        { "test-function-2", "function2value" }
                    }
                }
            };

            var context = new JObject
            {
                { "secrets", JObject.FromObject(secrets) }
            };

            string json          = JsonConvert.SerializeObject(context);
            var    encryptionKey = Convert.FromBase64String(TestEncryptionKey);
            string encryptedJson = SimpleWebTokenHelper.Encrypt(json, encryptionKey);

            File.WriteAllText(path, encryptedJson);

            return(secrets);
        }
Пример #8
0
        public void EncryptShouldGenerateDecryptableValues(string valueToEncrypt)
        {
            var key       = TestHelpers.GenerateKeyBytes();
            var stringKey = TestHelpers.GenerateKeyHexString(key);

            using (new TestScopedEnvironmentVariable(SettingsKeys.AuthEncryptionKey, stringKey))
            {
                var encrypted = SimpleWebTokenHelper.Encrypt(valueToEncrypt);
                var decrypted = SimpleWebTokenHelper.Decrypt(key, encrypted);
                Assert.Matches("(.*)[.](.*)[.](.*)", encrypted);
                Assert.Equal(valueToEncrypt, decrypted);
            }
        }
Пример #9
0
        public void EncryptShouldGenerateDecryptableValues(string valueToEncrypt)
        {
            var key       = TestHelpers.GenerateKeyBytes();
            var stringKey = TestHelpers.GenerateKeyHexString(key);

            Environment.SetEnvironmentVariable("WEBSITE_AUTH_ENCRYPTION_KEY", stringKey);

            var encrypted = SimpleWebTokenHelper.Encrypt(valueToEncrypt);
            var decrypted = SimpleWebTokenHelper.Decrypt(key, encrypted);

            Assert.Matches("(.*)[.](.*)[.](.*)", encrypted);
            Assert.Equal(valueToEncrypt, decrypted);
        }
Пример #10
0
        public void EncryptShouldThrowIdNoEncryptionKeyDefined()
        {
            // Make sure WEBSITE_AUTH_ENCRYPTION_KEY is empty
            Environment.SetEnvironmentVariable("WEBSITE_AUTH_ENCRYPTION_KEY", string.Empty);

            try
            {
                SimpleWebTokenHelper.Encrypt("value");
            }
            catch (Exception ex)
            {
                Assert.IsType <InvalidOperationException>(ex);
                Assert.Contains("WEBSITE_AUTH_ENCRYPTION_KEY", ex.Message);
            }
        }
Пример #11
0
 public void EncryptShouldThrowIdNoEncryptionKeyDefined()
 {
     // Make sure WEBSITE_AUTH_ENCRYPTION_KEY is empty
     using (new TestScopedEnvironmentVariable(SettingsKeys.AuthEncryptionKey, string.Empty))
     {
         try
         {
             SimpleWebTokenHelper.Encrypt("value");
         }
         catch (Exception ex)
         {
             Assert.IsType <InvalidOperationException>(ex);
             Assert.Contains(SettingsKeys.AuthEncryptionKey, ex.Message);
         }
     }
 }
Пример #12
0
        public async Task Assignment_Invokes_InstanceManager_Methods_For_Warmup_Requests_Also(bool isWarmupRequest, bool shouldInvokeMethod)
        {
            var environment = new TestEnvironment();

            environment.SetEnvironmentVariable(EnvironmentSettingNames.AzureWebsitePlaceholderMode, "1");

            var loggerFactory  = new LoggerFactory();
            var loggerProvider = new TestLoggerProvider();

            loggerFactory.AddProvider(loggerProvider);

            var instanceManager        = new Mock <IInstanceManager>();
            var startupContextProvider = new StartupContextProvider(environment, loggerFactory.CreateLogger <StartupContextProvider>());

            InstanceManager.Reset();

            var instanceController = new InstanceController(environment, instanceManager.Object, loggerFactory,
                                                            startupContextProvider);

            const string containerEncryptionKey = "/a/vXvWJ3Hzgx4PFxlDUJJhQm5QVyGiu0NNLFm/ZMMg=";
            var          hostAssignmentContext  = new HostAssignmentContext
            {
                Environment = new Dictionary <string, string>()
            };

            hostAssignmentContext.IsWarmupRequest = isWarmupRequest;

            var encryptedHostAssignmentValue =
                SimpleWebTokenHelper.Encrypt(JsonConvert.SerializeObject(hostAssignmentContext),
                                             containerEncryptionKey.ToKeyBytes());

            var encryptedHostAssignmentContext = new EncryptedHostAssignmentContext()
            {
                EncryptedContext = encryptedHostAssignmentValue
            };

            environment.SetEnvironmentVariable(EnvironmentSettingNames.ContainerEncryptionKey, containerEncryptionKey);

            await instanceController.Assign(encryptedHostAssignmentContext);

            instanceManager.Verify(i => i.ValidateContext(It.IsAny <HostAssignmentContext>()),
                                   shouldInvokeMethod ? Times.Once() : Times.Never());
            instanceManager.Verify(i => i.SpecializeMSISidecar(It.IsAny <HostAssignmentContext>()),
                                   shouldInvokeMethod ? Times.Once() : Times.Never());
            instanceManager.Verify(i => i.StartAssignment(It.IsAny <HostAssignmentContext>()),
                                   shouldInvokeMethod ? Times.Once() : Times.Never());
        }
        private string WriteStartupContext(string context = null, string path = null)
        {
            path = path ?? Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.txt");
            path = Environment.ExpandEnvironmentVariables(path);
            _environment.SetEnvironmentVariable(EnvironmentSettingNames.AzureWebsiteStartupContextCache, path);

            if (context == null)
            {
                var content = new JObject
                {
                    { "secrets", JObject.FromObject(_secrets) }
                };
                context = JsonConvert.SerializeObject(content);
            }

            var encrypted = SimpleWebTokenHelper.Encrypt(context, environment: _environment);

            File.WriteAllText(path, encrypted);

            return(path);
        }
        public void Does_Not_SetContext_AppliesHostAssignmentContext_For_Warmup_Request()
        {
            var context = new HostAssignmentContext
            {
                Environment     = new Dictionary <string, string>(),
                SiteName        = "TestSite",
                Secrets         = _secrets,
                IsWarmupRequest = true
            };
            string json             = JsonConvert.SerializeObject(context);
            string encrypted        = SimpleWebTokenHelper.Encrypt(json, environment: _environment);
            var    encryptedContext = new EncryptedHostAssignmentContext {
                EncryptedContext = encrypted
            };

            var result = _startupContextProvider.SetContext(encryptedContext);

            Assert.Equal(context.SiteName, result.SiteName);
            Assert.Equal(_secrets.Host.Master, result.Secrets.Host.Master);

            var secrets = _startupContextProvider.GetHostSecretsOrNull();

            Assert.Null(secrets);
        }