public async Task AddOrUpdateFunctionSecret_ClearsCache_WhenHostSystemSecretAdded()
        {
            using (var directory = new TempDirectory())
            {
                CreateTestSecrets(directory.Path);

                KeyOperationResult result;
                using (var secretManager = CreateSecretManager(directory.Path, simulateWriteConversion: false))
                {
                    var hostKeys = await secretManager.GetHostSecretsAsync();

                    Assert.Equal(2, hostKeys.SystemKeys.Count);

                    // add a new key
                    result = await secretManager.AddOrUpdateFunctionSecretAsync("host-system-3", "123", HostKeyScopes.SystemKeys, ScriptSecretsType.Host);
                }

                string secretsJson      = File.ReadAllText(Path.Combine(directory.Path, "host.json"));
                var    persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson);

                Assert.Equal(OperationResult.Created, result.Result);
                Assert.Equal(result.Secret, "123");

                var logs = _loggerProvider.GetAllLogMessages();
                Assert.Equal(1, logs.Count(p => p.FormattedMessage == "Host keys change detected. Clearing cache."));
                Assert.Equal(1, logs.Count(p => p.FormattedMessage == "Host secret 'host-system-3' for 'systemkeys' Created."));
            }
        }
        public async Task AddOrUpdateFunctionSecret_ClearsCache_WhenFunctionSecretAdded()
        {
            using (var directory = new TempDirectory())
            {
                CreateTestSecrets(directory.Path);

                KeyOperationResult result;
                using (var secretManager = CreateSecretManager(directory.Path, simulateWriteConversion: false))
                {
                    var keys = await secretManager.GetFunctionSecretsAsync("testfunction");

                    Assert.Equal(2, keys.Count);

                    // add a new key
                    result = await secretManager.AddOrUpdateFunctionSecretAsync("function-key-3", "9876", "TestFunction", ScriptSecretsType.Function);
                }

                string secretsJson      = File.ReadAllText(Path.Combine(directory.Path, "testfunction.json"));
                var    persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <FunctionSecrets>(secretsJson);

                Assert.Equal(OperationResult.Created, result.Result);
                Assert.Equal(result.Secret, "9876");

                var logs = _loggerProvider.GetAllLogMessages();
                Assert.Equal(1, logs.Count(p => string.Equals(p.FormattedMessage, "Function keys change detected. Clearing cache for function 'TestFunction'.", StringComparison.OrdinalIgnoreCase)));
                Assert.Equal(1, logs.Count(p => p.FormattedMessage == "Function secret 'function-key-3' for 'TestFunction' Created."));
            }
        }
        public async Task GetHostSecrets_WhenNoHostSecretFileExists_GeneratesSecretsAndPersistsFiles()
        {
            using (var directory = new TempDirectory())
            {
                string          expectedTraceMessage = Resources.TraceHostSecretGeneration;
                HostSecretsInfo hostSecrets;

                using (var secretManager = CreateSecretManager(directory.Path, simulateWriteConversion: false, setStaleValue: false))
                {
                    hostSecrets = await secretManager.GetHostSecretsAsync();
                }

                string      secretsJson      = File.ReadAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName));
                HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson);

                Assert.NotNull(hostSecrets);
                Assert.NotNull(persistedSecrets);
                Assert.Equal(1, hostSecrets.FunctionKeys.Count);
                Assert.NotNull(hostSecrets.MasterKey);
                Assert.NotNull(hostSecrets.SystemKeys);
                Assert.Equal(0, hostSecrets.SystemKeys.Count);
                Assert.Equal(persistedSecrets.MasterKey.Value, hostSecrets.MasterKey);
                Assert.Equal(persistedSecrets.FunctionKeys.First().Value, hostSecrets.FunctionKeys.First().Value);
            }
        }
        public async Task AddOrUpdateFunctionSecret_ClearsCache_WhenHostLevelFunctionSecretAdded()
        {
            using (var directory = new TempDirectory())
            {
                CreateTestSecrets(directory.Path);

                Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false);
                KeyOperationResult result;
                ISecretsRepository repository = new FileSystemSecretsRepository(directory.Path);
                using (var secretManager = new SecretManager(repository, mockValueConverterFactory.Object, _logger, new TestMetricsLogger(), _hostNameProvider))
                {
                    var hostKeys = await secretManager.GetHostSecretsAsync();

                    Assert.Equal(2, hostKeys.FunctionKeys.Count);

                    // add a new key
                    result = await secretManager.AddOrUpdateFunctionSecretAsync("function-host-3", "9876", HostKeyScopes.FunctionKeys, ScriptSecretsType.Host);
                }

                string secretsJson      = File.ReadAllText(Path.Combine(directory.Path, "host.json"));
                var    persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson);

                Assert.Equal(OperationResult.Created, result.Result);
                Assert.Equal(result.Secret, "9876");

                var logs = _loggerProvider.GetAllLogMessages();
                Assert.Equal(1, logs.Count(p => p.FormattedMessage == "Host keys change detected. Clearing cache."));
                Assert.Equal(1, logs.Count(p => p.FormattedMessage == "Host secret 'function-host-3' for 'functionkeys' Created."));
            }
        }
        public async Task AddOrUpdateFunctionSecrets_WithFunctionNameAndNoSecret_EncryptsSecretAndPersistsFile()
        {
            using (var directory = new TempDirectory())
            {
                string secretName           = "TestSecret";
                string functionName         = "TestFunction";
                string expectedTraceMessage = string.Format(Resources.TraceAddOrUpdateFunctionSecret, "Function", secretName, functionName, "Created");

                KeyOperationResult result;
                using (var secretManager = CreateSecretManager(directory.Path))
                {
                    result = await secretManager.AddOrUpdateFunctionSecretAsync(secretName, null, functionName, ScriptSecretsType.Function);
                }

                string          secretsJson      = File.ReadAllText(Path.Combine(directory.Path, "testfunction.json"));
                FunctionSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <FunctionSecrets>(secretsJson);

                Assert.Equal(OperationResult.Created, result.Result);
                Assert.NotNull(result.Secret);
                Assert.NotNull(persistedSecrets);
                Assert.Equal("!" + result.Secret, persistedSecrets.Keys.First().Value);
                Assert.Equal(secretName, persistedSecrets.Keys.First().Name, StringComparer.Ordinal);
                Assert.True(persistedSecrets.Keys.First().IsEncrypted);
            }
        }
        public async Task SetMasterKey_WithoutProvidedKey_GeneratesKeyAndPersistsFile()
        {
            using (var directory = new TempDirectory())
            {
                string expectedTraceMessage = "Master key Created";

                Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false);

                KeyOperationResult result;
                var traceWriter = new TestTraceWriter(TraceLevel.Verbose);
                ISecretsRepository repository = new FileSystemSecretsRepository(directory.Path);
                using (var secretManager = new SecretManager(repository, mockValueConverterFactory.Object, traceWriter))
                {
                    result = await secretManager.SetMasterKeyAsync();
                }

                bool functionSecretsExists = File.Exists(Path.Combine(directory.Path, "testfunction.json"));

                string      secretsJson      = File.ReadAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName));
                HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson);

                Assert.NotNull(persistedSecrets);
                Assert.NotNull(persistedSecrets.MasterKey);
                Assert.Equal(OperationResult.Created, result.Result);
                Assert.Equal(result.Secret, persistedSecrets.MasterKey.Value);
                Assert.True(traceWriter.Traces.Any(t => t.Level == TraceLevel.Info && t.Message.IndexOf(expectedTraceMessage) > -1),
                            "Expected Trace message not found");
            }
        }
        public async Task SetMasterKey_WithProvidedKey_UsesProvidedKeyAndPersistsFile()
        {
            string testSecret = "abcde0123456789abcde0123456789abcde0123456789";

            using (var directory = new TempDirectory())
            {
                Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false);

                KeyOperationResult result;
                ISecretsRepository repository = new FileSystemSecretsRepository(directory.Path);
                using (var secretManager = new SecretManager(repository, mockValueConverterFactory.Object, NullLogger.Instance))
                {
                    result = await secretManager.SetMasterKeyAsync(testSecret);
                }

                bool functionSecretsExists = File.Exists(Path.Combine(directory.Path, "testfunction.json"));

                string      secretsJson      = File.ReadAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName));
                HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson);

                Assert.NotNull(persistedSecrets);
                Assert.NotNull(persistedSecrets.MasterKey);
                Assert.Equal(OperationResult.Updated, result.Result);
                Assert.Equal(testSecret, result.Secret);
            }
        }
Exemplo n.º 8
0
        public void AddOrUpdateFunctionSecrets_WithFunctionNameAndNoSecret_GeneratesFunctionSecretsAndPersistsFile()
        {
            var secretsPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            try
            {
                using (var variables = new TestScopedEnvironmentVariables("AzureWebJobsFeatureFlags", "MultiKey"))
                {
                    Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false);

                    KeyOperationResult result;
                    using (var secretManager = new SecretManager(secretsPath, mockValueConverterFactory.Object))
                    {
                        result = secretManager.AddOrUpdateFunctionSecret("TestSecret", null, "TestFunction");
                    }

                    string          secretsJson      = File.ReadAllText(Path.Combine(secretsPath, "testfunction.json"));
                    FunctionSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <FunctionSecrets>(secretsJson);

                    Assert.Equal(OperationResult.Created, result.Result);
                    Assert.NotNull(result.Secret);
                    Assert.NotNull(persistedSecrets);
                    Assert.Equal(result.Secret, persistedSecrets.Keys.First().Value);
                    Assert.Equal("TestSecret", persistedSecrets.Keys.First().Name, StringComparer.Ordinal);
                }
            }
            finally
            {
                Directory.Delete(secretsPath, true);
            }
        }
        public void GetHostSecrets_WhenNoHostSecretFileExists_GeneratesSecretsAndPersistsFiles()
        {
            using (var directory = new TempDirectory())
            {
                string expectedTraceMessage = Resources.TraceHostSecretGeneration;
                Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false, false);

                HostSecretsInfo hostSecrets;
                var             traceWriter = new TestTraceWriter(TraceLevel.Verbose);
                using (var secretManager = new SecretManager(directory.Path, mockValueConverterFactory.Object, traceWriter))
                {
                    hostSecrets = secretManager.GetHostSecrets();
                }

                string      secretsJson      = File.ReadAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName));
                HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson);

                Assert.NotNull(hostSecrets);
                Assert.NotNull(persistedSecrets);
                Assert.Equal(1, hostSecrets.FunctionKeys.Count);
                Assert.NotNull(hostSecrets.MasterKey);
                Assert.Equal(persistedSecrets.MasterKey.Value, hostSecrets.MasterKey);
                Assert.Equal(persistedSecrets.FunctionKeys.First().Value, hostSecrets.FunctionKeys.First().Value);
                Assert.True(traceWriter.Traces.Any(t => t.Level == TraceLevel.Verbose && t.Message.IndexOf(expectedTraceMessage) > -1));
            }
        }
        public async Task AddOrUpdateFunctionSecrets_WithScope_UsesSecretandPersistsHostFile(string scope, Func <HostSecrets, IList <Key> > keySelector, TempDirectory directory)
        {
            string secretName           = "TestSecret";
            string expectedTraceMessage = string.Format(Resources.TraceAddOrUpdateFunctionSecret, "Host", secretName, scope, "Created");

            Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false);

            KeyOperationResult result;
            ISecretsRepository repository = new FileSystemSecretsRepository(directory.Path);

            using (var secretManager = new SecretManager(repository, mockValueConverterFactory.Object, NullLogger.Instance))
            {
                result = await secretManager.AddOrUpdateFunctionSecretAsync(secretName, "TestSecretValue", scope, ScriptSecretsType.Host);
            }

            string      secretsJson      = File.ReadAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName));
            HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson);
            Key         newSecret        = keySelector(persistedSecrets).FirstOrDefault(k => string.Equals(k.Name, secretName, StringComparison.Ordinal));

            Assert.Equal(OperationResult.Created, result.Result);
            Assert.Equal("TestSecretValue", result.Secret, StringComparer.Ordinal);
            Assert.NotNull(persistedSecrets);
            Assert.NotNull(newSecret);
            Assert.Equal(result.Secret, newSecret.Value);
            Assert.Equal(secretName, newSecret.Name, StringComparer.Ordinal);
            Assert.NotNull(persistedSecrets.MasterKey);
        }
        public async Task GetHostSecrets_WhenNoHostSecretFileExists_GeneratesSecretsAndPersistsFiles()
        {
            using (var directory = new TempDirectory())
            {
                string expectedTraceMessage = Resources.TraceHostSecretGeneration;
                Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false, false);

                HostSecretsInfo    hostSecrets;
                ISecretsRepository repository = new FileSystemSecretsRepository(directory.Path);
                using (var secretManager = new SecretManager(repository, mockValueConverterFactory.Object, NullLogger.Instance))
                {
                    hostSecrets = await secretManager.GetHostSecretsAsync();
                }

                string      secretsJson      = File.ReadAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName));
                HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson);

                Assert.NotNull(hostSecrets);
                Assert.NotNull(persistedSecrets);
                Assert.Equal(1, hostSecrets.FunctionKeys.Count);
                Assert.NotNull(hostSecrets.MasterKey);
                Assert.NotNull(hostSecrets.SystemKeys);
                Assert.Equal(0, hostSecrets.SystemKeys.Count);
                Assert.Equal(persistedSecrets.MasterKey.Value, hostSecrets.MasterKey);
                Assert.Equal(persistedSecrets.FunctionKeys.First().Value, hostSecrets.FunctionKeys.First().Value);
            }
        }
        public async Task AddOrUpdateFunctionSecrets_WithFunctionNameAndProvidedSecret_UsesSecretAndPersistsFile()
        {
            using (var directory = new TempDirectory())
            {
                string secretName           = "TestSecret";
                string functionName         = "TestFunction";
                string expectedTraceMessage = string.Format(Resources.TraceAddOrUpdateFunctionSecret, "Function", secretName, functionName, "Created");

                Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false);

                KeyOperationResult result;
                ISecretsRepository repository = new FileSystemSecretsRepository(directory.Path);
                using (var secretManager = new SecretManager(repository, mockValueConverterFactory.Object, NullLogger.Instance))
                {
                    result = await secretManager.AddOrUpdateFunctionSecretAsync(secretName, "TestSecretValue", functionName, ScriptSecretsType.Function);
                }

                string          secretsJson      = File.ReadAllText(Path.Combine(directory.Path, "testfunction.json"));
                FunctionSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <FunctionSecrets>(secretsJson);

                Assert.Equal(OperationResult.Created, result.Result);
                Assert.Equal("TestSecretValue", result.Secret, StringComparer.Ordinal);
                Assert.NotNull(persistedSecrets);
                Assert.Equal(result.Secret, persistedSecrets.Keys.First().Value);
                Assert.Equal(secretName, persistedSecrets.Keys.First().Name, StringComparer.Ordinal);
            }
        }
Exemplo n.º 13
0
            public async Task <ScriptSecrets> GetSecretText(string functionNameOrHost, ScriptSecretsType type)
            {
                ScriptSecrets secrets = null;

                switch (RepositoryType)
                {
                case SecretsRepositoryType.FileSystem:
                    string secretText = File.ReadAllText(SecretsFileOrSentinelPath(functionNameOrHost));
                    secrets = ScriptSecretSerializer.DeserializeSecrets(type, secretText);
                    break;

                case SecretsRepositoryType.BlobStorage:
                case SecretsRepositoryType.BlobStorageSas:
                    secrets = await GetSecretBlobText(functionNameOrHost, type);

                    break;

                case SecretsRepositoryType.KeyVault:
                    secrets = await GetSecretsFromKeyVault(functionNameOrHost, type);

                    break;

                default:
                    break;
                }
                return(secrets);
            }
Exemplo n.º 14
0
        public void AddOrUpdateFunctionSecrets_WithNoFunctionNameAndProvidedSecret_UsesSecretAndPersistsHostFile()
        {
            var secretsPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            try
            {
                using (var variables = new TestScopedEnvironmentVariables("AzureWebJobsFeatureFlags", "MultiKey"))
                {
                    Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false);

                    KeyOperationResult result;
                    using (var secretManager = new SecretManager(secretsPath, mockValueConverterFactory.Object))
                    {
                        result = secretManager.AddOrUpdateFunctionSecret("TestSecret", "TestSecretValue");
                    }

                    string      secretsJson      = File.ReadAllText(Path.Combine(secretsPath, ScriptConstants.HostMetadataFileName));
                    HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson);
                    Key         newSecret        = persistedSecrets.FunctionKeys.FirstOrDefault(k => string.Equals(k.Name, "TestSecret", StringComparison.Ordinal));

                    Assert.Equal(OperationResult.Created, result.Result);
                    Assert.Equal("TestSecretValue", result.Secret, StringComparer.Ordinal);
                    Assert.NotNull(persistedSecrets);
                    Assert.NotNull(newSecret);
                    Assert.Equal(result.Secret, newSecret.Value);
                    Assert.Equal("TestSecret", newSecret.Name, StringComparer.Ordinal);
                    Assert.NotNull(persistedSecrets.MasterKey);
                }
            }
            finally
            {
                Directory.Delete(secretsPath, true);
            }
        }
Exemplo n.º 15
0
        public void SetMasterKey_WithoutProvidedKey_GeneratesKeyAndPersistsFile()
        {
            var secretsPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            try
            {
                using (var variables = new TestScopedEnvironmentVariables("AzureWebJobsFeatureFlags", "MultiKey"))
                {
                    Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false);

                    KeyOperationResult result;
                    using (var secretManager = new SecretManager(secretsPath, mockValueConverterFactory.Object))
                    {
                        result = secretManager.SetMasterKey();
                    }

                    bool functionSecretsExists = File.Exists(Path.Combine(secretsPath, "testfunction.json"));

                    string      secretsJson      = File.ReadAllText(Path.Combine(secretsPath, ScriptConstants.HostMetadataFileName));
                    HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson);

                    Assert.NotNull(persistedSecrets);
                    Assert.NotNull(persistedSecrets.MasterKey);
                    Assert.Equal(OperationResult.Created, result.Result);
                    Assert.Equal(result.Secret, persistedSecrets.MasterKey.Value);
                }
            }
            finally
            {
                Directory.Delete(secretsPath, true);
            }
        }
Exemplo n.º 16
0
        public void GetHostSecrets_WhenNoHostSecretFileExists_GeneratesSecretsAndPersistsFiles()
        {
            var secretsPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            try
            {
                using (var variables = new TestScopedEnvironmentVariables("AzureWebJobsFeatureFlags", "MultiKey"))
                {
                    Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false);

                    HostSecretsInfo hostSecrets;
                    using (var secretManager = new SecretManager(secretsPath, mockValueConverterFactory.Object))
                    {
                        hostSecrets = secretManager.GetHostSecrets();
                    }

                    string      secretsJson      = File.ReadAllText(Path.Combine(secretsPath, ScriptConstants.HostMetadataFileName));
                    HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson);

                    Assert.NotNull(hostSecrets);
                    Assert.NotNull(persistedSecrets);
                    Assert.Equal(1, hostSecrets.FunctionKeys.Count);
                    Assert.NotNull(hostSecrets.MasterKey);
                    Assert.Equal(persistedSecrets.MasterKey.Value, hostSecrets.MasterKey);
                    Assert.Equal(persistedSecrets.FunctionKeys.First().Value, hostSecrets.FunctionKeys.First().Value);
                }
            }
            finally
            {
                Directory.Delete(secretsPath, true);
            }
        }
        public void SetMasterKey_WithProvidedKey_UsesProvidedKeyAndPersistsFile()
        {
            var    secretsPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            string testSecret  = "abcde0123456789abcde0123456789abcde0123456789";

            try
            {
                Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false);

                KeyOperationResult result;
                using (var secretManager = new SecretManager(secretsPath, mockValueConverterFactory.Object))
                {
                    result = secretManager.SetMasterKey(testSecret);
                }

                bool functionSecretsExists = File.Exists(Path.Combine(secretsPath, "testfunction.json"));

                string      secretsJson      = File.ReadAllText(Path.Combine(secretsPath, ScriptConstants.HostMetadataFileName));
                HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson);

                Assert.NotNull(persistedSecrets);
                Assert.NotNull(persistedSecrets.MasterKey);
                Assert.Equal(OperationResult.Updated, result.Result);
                Assert.Equal(testSecret, result.Secret);
            }
            finally
            {
                Directory.Delete(secretsPath, true);
            }
        }
        public async Task SetMasterKey_WithoutProvidedKey_GeneratesKeyAndPersistsFile()
        {
            using (var directory = new TempDirectory())
            {
                Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false);

                KeyOperationResult result;
                var traceWriter = new TestTraceWriter(System.Diagnostics.TraceLevel.Verbose);
                ISecretsRepository repository = new FileSystemSecretsRepository(directory.Path);
                using (var secretManager = new SecretManager(repository, mockValueConverterFactory.Object, null))
                {
                    result = await secretManager.SetMasterKeyAsync();
                }

                bool functionSecretsExists = File.Exists(Path.Combine(directory.Path, "testfunction.json"));

                string      secretsJson      = File.ReadAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName));
                HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson);

                Assert.NotNull(persistedSecrets);
                Assert.NotNull(persistedSecrets.MasterKey);
                Assert.Equal(OperationResult.Created, result.Result);
                Assert.Equal(result.Secret, persistedSecrets.MasterKey.Value);
            }
        }
        public void SetMasterKey_WithProvidedKey_UsesProvidedKeyAndPersistsFile()
        {
            string testSecret = "abcde0123456789abcde0123456789abcde0123456789";

            using (var directory = new TempDirectory())
            {
                string expectedTraceMessage = "Master key Updated";

                Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false);

                KeyOperationResult result;
                var traceWriter = new TestTraceWriter(TraceLevel.Verbose);
                using (var secretManager = new SecretManager(directory.Path, mockValueConverterFactory.Object, traceWriter))
                {
                    result = secretManager.SetMasterKey(testSecret);
                }

                bool functionSecretsExists = File.Exists(Path.Combine(directory.Path, "testfunction.json"));

                string      secretsJson      = File.ReadAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName));
                HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson);

                Assert.NotNull(persistedSecrets);
                Assert.NotNull(persistedSecrets.MasterKey);
                Assert.Equal(OperationResult.Updated, result.Result);
                Assert.Equal(testSecret, result.Secret);
                Assert.True(traceWriter.Traces.Any(t => t.Level == TraceLevel.Info && t.Message.IndexOf(expectedTraceMessage) > -1));
            }
        }
        public async Task AddOrUpdateFunctionSecrets_WithNoFunctionNameAndProvidedSecret_UsesSecretAndPersistsHostFile()
        {
            using (var directory = new TempDirectory())
            {
                string secretName           = "TestSecret";
                string expectedTraceMessage = string.Format(Resources.TraceAddOrUpdateFunctionSecret, "Host", secretName, "host", "Created");

                Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false);

                KeyOperationResult result;
                var traceWriter = new TestTraceWriter(TraceLevel.Verbose);
                ISecretsRepository repository = new FileSystemSecretsRepository(directory.Path);
                using (var secretManager = new SecretManager(repository, mockValueConverterFactory.Object, traceWriter))
                {
                    result = await secretManager.AddOrUpdateFunctionSecretAsync(secretName, "TestSecretValue");
                }

                string      secretsJson      = File.ReadAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName));
                HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson);
                Key         newSecret        = persistedSecrets.FunctionKeys.FirstOrDefault(k => string.Equals(k.Name, secretName, StringComparison.Ordinal));

                Assert.Equal(OperationResult.Created, result.Result);
                Assert.Equal("TestSecretValue", result.Secret, StringComparer.Ordinal);
                Assert.NotNull(persistedSecrets);
                Assert.NotNull(newSecret);
                Assert.Equal(result.Secret, newSecret.Value);
                Assert.Equal(secretName, newSecret.Name, StringComparer.Ordinal);
                Assert.NotNull(persistedSecrets.MasterKey);
                Assert.True(traceWriter.Traces.Any(t => t.Level == TraceLevel.Info && t.Message.IndexOf(expectedTraceMessage) > -1),
                            "Expected Trace message not found");
            }
        }
        public async Task AddOrUpdateFunctionSecrets_WithFunctionNameAndNoSecret_GeneratesFunctionSecretsAndPersistsFile()
        {
            using (var directory = new TempDirectory())
            {
                string secretName           = "TestSecret";
                string functionName         = "TestFunction";
                string expectedTraceMessage = string.Format(Resources.TraceAddOrUpdateFunctionSecret, "Function", secretName, functionName, "Created");

                Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false);

                KeyOperationResult result;
                var traceWriter = new TestTraceWriter(TraceLevel.Verbose);
                ISecretsRepository repository = new FileSystemSecretsRepository(directory.Path);
                using (var secretManager = new SecretManager(repository, mockValueConverterFactory.Object, traceWriter))
                {
                    result = await secretManager.AddOrUpdateFunctionSecretAsync(secretName, null, functionName);
                }

                string          secretsJson      = File.ReadAllText(Path.Combine(directory.Path, "testfunction.json"));
                FunctionSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <FunctionSecrets>(secretsJson);

                Assert.Equal(OperationResult.Created, result.Result);
                Assert.NotNull(result.Secret);
                Assert.NotNull(persistedSecrets);
                Assert.Equal(result.Secret, persistedSecrets.Keys.First().Value);
                Assert.Equal(secretName, persistedSecrets.Keys.First().Name, StringComparer.Ordinal);
                Assert.True(traceWriter.Traces.Any(t => t.Level == TraceLevel.Info && t.Message.IndexOf(expectedTraceMessage) > -1),
                            "Expected Trace message not found");
            }
        }
Exemplo n.º 22
0
            private async Task <ScriptSecrets> GetSecretBlobText(string functionNameOrHost, ScriptSecretsType type)
            {
                string blobText = null;
                string blobPath = RelativeBlobPath(functionNameOrHost);

                if (await BlobContainer.GetBlockBlobReference(blobPath).ExistsAsync())
                {
                    blobText = await BlobContainer.GetBlockBlobReference(blobPath).DownloadTextAsync();
                }
                return(ScriptSecretSerializer.DeserializeSecrets(type, blobText));
            }
        public async Task SetMasterKey_WithoutProvidedKey_GeneratesKeyAndPersistsFile()
        {
            using (var directory = new TempDirectory())
            {
                KeyOperationResult result;
                using (var secretManager = CreateSecretManager(directory.Path, simulateWriteConversion: false))
                {
                    result = await secretManager.SetMasterKeyAsync();
                }

                bool functionSecretsExists = File.Exists(Path.Combine(directory.Path, "testfunction.json"));

                string      secretsJson      = File.ReadAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName));
                HostSecrets persistedSecrets = ScriptSecretSerializer.DeserializeSecrets <HostSecrets>(secretsJson);

                Assert.NotNull(persistedSecrets);
                Assert.NotNull(persistedSecrets.MasterKey);
                Assert.Equal(OperationResult.Created, result.Result);
                Assert.Equal(result.Secret, persistedSecrets.MasterKey.Value);
            }
        }
Exemplo n.º 24
0
            public async Task WriteSecret(string functionNameOrHost, ScriptSecrets scriptSecret)
            {
                switch (RepositoryType)
                {
                case SecretsRepositoryType.FileSystem:
                    WriteSecretsToFile(functionNameOrHost, ScriptSecretSerializer.SerializeSecrets(scriptSecret));
                    break;

                case SecretsRepositoryType.BlobStorage:
                    await WriteSecretsBlobAndUpdateSentinelFile(functionNameOrHost, ScriptSecretSerializer.SerializeSecrets(scriptSecret));

                    break;

                case SecretsRepositoryType.KeyVault:
                    await WriteSecretsKeyVaultAndUpdateSectinelFile(functionNameOrHost, scriptSecret);

                    break;

                default:
                    break;
                }
            }