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);
            }
        }
Exemple #2
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);
            }
        }
        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);
            }
        }
Exemple #4
0
        public void DeserializeHostSecrets_ReturnsExpectedResult(string serializedSecret, string hostName)
        {
            var serializer = new ScriptSecretSerializerV1();
            var expected   = new HostSecrets
            {
                MasterKey = new Key {
                    Name = "master", Value = "1234"
                },
                FunctionKeys = new List <Key>
                {
                    new Key
                    {
                        Name        = "Key1",
                        Value       = "Value1",
                        IsEncrypted = false
                    },
                    new Key
                    {
                        Name        = "Key2",
                        Value       = "Value2",
                        IsEncrypted = true
                    }
                },
                HostName = hostName
            };

            HostSecrets actual = serializer.DeserializeSecrets <HostSecrets>(JObject.Parse(serializedSecret));

            Assert.NotNull(actual);
            Assert.Equal(expected.MasterKey, actual.MasterKey);
            Assert.Equal(actual.HostName, hostName);
            Assert.Equal(expected.Source, ScriptConstants.Runtime);
            AssertKeyCollectionsEquality(expected.FunctionKeys, actual.FunctionKeys);
        }
        public void SetMasterKey_WithProvidedKey_UsesProvidedKeyAndPersistsFile()
        {
            var    secretsPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            string testSecret  = "abcde0123456789abcde0123456789abcde0123456789";

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

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

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

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

                Assert.NotNull(persistedSecrets);
                Assert.NotNull(persistedSecrets.MasterKey);
                Assert.Equal(OperationResult.Updated, result.Result);
                Assert.Equal(testSecret, result.Secret);
            }
            finally
            {
                Directory.Delete(secretsPath, true);
            }
        }
        public async Task AddOrUpdateFunctionSecrets_WithScope_UsesSecretandPersistsHostFile(string scope, Func <HostSecrets, IList <Key> > keySelector, TempDirectory directory)
        {
            string secretName           = "TestSecret";
            string expectedTraceMessage = string.Format(Resources.TraceAddOrUpdateFunctionSecret, "Host", secretName, scope, "Created");

            Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false);

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

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

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

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

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

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

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

                Assert.NotNull(persistedSecrets);
                Assert.NotNull(persistedSecrets.MasterKey);
                Assert.Equal(OperationResult.Created, result.Result);
                Assert.Equal(result.Secret, persistedSecrets.MasterKey.Value);
            }
        }
        public void SerializeHostSecrets_ReturnsExpectedResult()
        {
            var serializer = new ScriptSecretSerializerV0();

            var secrets = new HostSecrets
            {
                MasterKey = new Key {
                    Name = "master", Value = "mastervalue"
                },
                FunctionKeys = new List <Key>
                {
                    new Key
                    {
                        Name        = string.Empty,
                        Value       = "functionKeyValue",
                        IsEncrypted = false,
                    }
                }
            };

            string serializedSecret = serializer.SerializeSecrets(secrets);

            Assert.NotNull(serializedSecret);

            var jsonObject  = JObject.Parse(serializedSecret);
            var functionKey = jsonObject.Value <string>("functionKey");
            var masterKey   = jsonObject.Value <string>("masterKey");

            Assert.Equal("mastervalue", masterKey);
            Assert.Equal("functionKeyValue", functionKey);
        }
        public void GetHostSecrets_WhenNoHostSecretFileExists_GeneratesSecretsAndPersistsFiles()
        {
            using (var directory = new TempDirectory())
            {
                string expectedTraceMessage = Resources.TraceHostSecretGeneration;
                Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false, false);

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

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

                Assert.NotNull(hostSecrets);
                Assert.NotNull(persistedSecrets);
                Assert.Equal(1, hostSecrets.FunctionKeys.Count);
                Assert.NotNull(hostSecrets.MasterKey);
                Assert.Equal(persistedSecrets.MasterKey.Value, hostSecrets.MasterKey);
                Assert.Equal(persistedSecrets.FunctionKeys.First().Value, hostSecrets.FunctionKeys.First().Value);
                Assert.True(traceWriter.Traces.Any(t => t.Level == TraceLevel.Verbose && t.Message.IndexOf(expectedTraceMessage) > -1));
            }
        }
        public async Task GetHostSecrets_WhenNoHostSecretFileExists_GeneratesSecretsAndPersistsFiles()
        {
            using (var directory = new TempDirectory())
            {
                string expectedTraceMessage = Resources.TraceHostSecretGeneration;
                Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false, false);

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

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

                Assert.NotNull(hostSecrets);
                Assert.NotNull(persistedSecrets);
                Assert.Equal(1, hostSecrets.FunctionKeys.Count);
                Assert.NotNull(hostSecrets.MasterKey);
                Assert.NotNull(hostSecrets.SystemKeys);
                Assert.Equal(0, hostSecrets.SystemKeys.Count);
                Assert.Equal(persistedSecrets.MasterKey.Value, hostSecrets.MasterKey);
                Assert.Equal(persistedSecrets.FunctionKeys.First().Value, hostSecrets.FunctionKeys.First().Value);
            }
        }
        public void DeserializeHostSecrets_ReturnsExpectedResult()
        {
            var serializer       = new ScriptSecretSerializerV1();
            var serializedSecret = "{'masterKey':{'name':'master','value':'1234','encrypted':false},'functionKeys':[{'name':'Key1','value':'Value1','encrypted':false},{'name':'Key2','value':'Value2','encrypted':true}]}";
            var expected         = new HostSecrets
            {
                MasterKey = new Key {
                    Name = "master", Value = "1234"
                },
                FunctionKeys = new List <Key>
                {
                    new Key
                    {
                        Name        = "Key1",
                        Value       = "Value1",
                        IsEncrypted = false
                    },
                    new Key
                    {
                        Name        = "Key2",
                        Value       = "Value2",
                        IsEncrypted = true
                    }
                }
            };

            HostSecrets actual = serializer.DeserializeSecrets <HostSecrets>(JObject.Parse(serializedSecret));

            Assert.NotNull(actual);
            Assert.Equal(expected.MasterKey, actual.MasterKey);
            AssertKeyCollectionsEquality(expected.FunctionKeys, actual.FunctionKeys);
        }
Exemple #12
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);
            }
        }
Exemple #13
0
        public AuthorizationLevelAttributeTests()
        {
            _actionContext = new HttpActionContext();
            HttpControllerContext controllerContext = new HttpControllerContext();

            _actionContext.ControllerContext = controllerContext;
            HttpConfiguration httpConfig = new HttpConfiguration();

            controllerContext.Configuration = httpConfig;
            Mock <IDependencyResolver> mockDependencyResolver = new Mock <IDependencyResolver>(MockBehavior.Strict);

            httpConfig.DependencyResolver = mockDependencyResolver.Object;
            _mockSecretManager            = new Mock <SecretManager>(MockBehavior.Strict);
            _hostSecrets = new HostSecrets
            {
                MasterKey   = TestMasterKeyValue,
                FunctionKey = TestHostFunctionKeyValue
            };
            _mockSecretManager.Setup(p => p.GetHostSecrets()).Returns(_hostSecrets);
            _functionSecrets = new FunctionSecrets
            {
                Key = TestFunctionKeyValue
            };
            _mockSecretManager.Setup(p => p.GetFunctionSecrets(It.IsAny <string>())).Returns(_functionSecrets);
            mockDependencyResolver.Setup(p => p.GetService(typeof(SecretManager))).Returns(_mockSecretManager.Object);
        }
Exemple #14
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()
        {
            string testSecret = "abcde0123456789abcde0123456789abcde0123456789";

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

                Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false);

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

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

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

                Assert.NotNull(persistedSecrets);
                Assert.NotNull(persistedSecrets.MasterKey);
                Assert.Equal(OperationResult.Updated, result.Result);
                Assert.Equal(testSecret, result.Secret);
                Assert.True(traceWriter.Traces.Any(t => t.Level == TraceLevel.Info && t.Message.IndexOf(expectedTraceMessage) > -1));
            }
        }
        public void DeserializeHostSecrets_ReturnsExpectedResult()
        {
            var serializer       = new ScriptSecretSerializerV0();
            var serializedSecret = "{'masterKey': 'master', 'functionKey': 'master'}";
            var expected         = new HostSecrets
            {
                MasterKey = new Key {
                    Name = ScriptConstants.DefaultMasterKeyName, Value = "master"
                },
                FunctionKeys = new List <Key>
                {
                    new Key
                    {
                        Name        = ScriptConstants.DefaultFunctionKeyName,
                        Value       = "master",
                        IsEncrypted = false
                    }
                }
            };

            HostSecrets actual = serializer.DeserializeSecrets <HostSecrets>(JObject.Parse(serializedSecret));

            Assert.NotNull(actual);
            Assert.Equal(expected.MasterKey, actual.MasterKey);
            AssertKeyCollectionsEquality(expected.FunctionKeys, actual.FunctionKeys);
        }
        public async Task SetMasterKey_WithoutProvidedKey_GeneratesKeyAndPersistsFile()
        {
            using (var directory = new TempDirectory())
            {
                string expectedTraceMessage = "Master key Created";

                Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false);

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

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

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

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

                Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false);

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

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

                Assert.Equal(OperationResult.Created, result.Result);
                Assert.Equal("TestSecretValue", result.Secret, StringComparer.Ordinal);
                Assert.NotNull(persistedSecrets);
                Assert.NotNull(newSecret);
                Assert.Equal(result.Secret, newSecret.Value);
                Assert.Equal(secretName, newSecret.Name, StringComparer.Ordinal);
                Assert.NotNull(persistedSecrets.MasterKey);
                Assert.True(traceWriter.Traces.Any(t => t.Level == TraceLevel.Info && t.Message.IndexOf(expectedTraceMessage) > -1),
                            "Expected Trace message not found");
            }
        }
Exemple #19
0
        public async Task ReadAsync_ReadsExpectedFile(SecretsRepositoryType repositoryType, ScriptSecretsType secretsType)
        {
            using (var directory = new TempDirectory())
            {
                await _fixture.TestInitialize(repositoryType, directory.Path);

                ScriptSecrets testSecrets = null;
                if (secretsType == ScriptSecretsType.Host)
                {
                    testSecrets = new HostSecrets()
                    {
                        MasterKey    = new Key("master", "test"),
                        FunctionKeys = new List <Key>()
                        {
                            new Key(KeyName, "test")
                        },
                        SystemKeys = new List <Key>()
                        {
                            new Key(KeyName, "test")
                        }
                    };
                }
                else
                {
                    testSecrets = new FunctionSecrets()
                    {
                        Keys = new List <Key>()
                        {
                            new Key(KeyName, "test")
                        }
                    };
                }
                string testFunctionName = secretsType == ScriptSecretsType.Host ? "host" : functionName;

                await _fixture.WriteSecret(testFunctionName, testSecrets);

                var target = _fixture.GetNewSecretRepository();

                ScriptSecrets secretsContent = await target.ReadAsync(secretsType, testFunctionName);

                if (secretsType == ScriptSecretsType.Host)
                {
                    Assert.Equal((secretsContent as HostSecrets).MasterKey.Name, "master");
                    Assert.Equal((secretsContent as HostSecrets).MasterKey.Value, "test");
                    Assert.Equal((secretsContent as HostSecrets).FunctionKeys[0].Name, KeyName);
                    Assert.Equal((secretsContent as HostSecrets).FunctionKeys[0].Value, "test");
                    Assert.Equal((secretsContent as HostSecrets).SystemKeys[0].Name, KeyName);
                    Assert.Equal((secretsContent as HostSecrets).SystemKeys[0].Value, "test");
                }
                else
                {
                    Assert.Equal((secretsContent as FunctionSecrets).Keys[0].Name, KeyName);
                    Assert.Equal((secretsContent as FunctionSecrets).Keys[0].Value, "test");
                }
            }
        }
Exemple #20
0
            private async Task <ScriptSecrets> GetSecretsFromKeyVault(string functionNameOrHost, ScriptSecretsType type)
            {
                var secretResults = SecretClient.GetPropertiesOfSecretsAsync().AsPages();
                var searchPages   = new List <SecretProperties>();

                await foreach (Page <SecretProperties> page in secretResults)
                {
                    {
                        foreach (SecretProperties secret in page.Values)
                        {
                            searchPages.Add(secret);
                        }
                    }
                }

                if (type == ScriptSecretsType.Host)
                {
                    KeyVaultSecret masterBundle = await SecretClient.GetSecretAsync(searchPages.FirstOrDefault(x => x.Name.StartsWith("host--master")).Name);

                    KeyVaultSecret functionKeyBundle = await SecretClient.GetSecretAsync(searchPages.FirstOrDefault(x => x.Name.StartsWith("host--functionKey")).Name);

                    KeyVaultSecret systemKeyBundle = await SecretClient.GetSecretAsync(searchPages.FirstOrDefault(x => x.Name.StartsWith("host--systemKey")).Name);

                    HostSecrets hostSecrets = new HostSecrets()
                    {
                        FunctionKeys = new List <Key>()
                        {
                            new Key(GetSecretName(functionKeyBundle.Name), functionKeyBundle.Value)
                        },
                        SystemKeys = new List <Key>()
                        {
                            new Key(GetSecretName(systemKeyBundle.Name), systemKeyBundle.Value)
                        }
                    };
                    hostSecrets.MasterKey = new Key("master", masterBundle.Value);
                    return(hostSecrets);
                }
                else
                {
                    KeyVaultSecret functionKeyBundle = await SecretClient.GetSecretAsync(searchPages.FirstOrDefault(x => x.Name.StartsWith("function--")).Name);

                    FunctionSecrets functionSecrets = new FunctionSecrets()
                    {
                        Keys = new List <Key>()
                        {
                            new Key(GetSecretName(functionKeyBundle.Name), functionKeyBundle.Value)
                        }
                    };
                    return(functionSecrets);
                }
            }
        public async Task AddOrUpdateFunctionSecrets_WithExistingHostFileAndSystemSecretScope_PersistsHostFileWithSecret()
        {
            using (var directory = new TempDirectory())
            {
                var hostSecret = new HostSecrets();
                hostSecret.MasterKey    = new Key("_master", "master");
                hostSecret.FunctionKeys = new List <Key> {
                };

                var hostJson = JsonConvert.SerializeObject(hostSecret);
                await FileUtility.WriteAsync(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName), hostJson);
                await AddOrUpdateFunctionSecrets_WithScope_UsesSecretandPersistsHostFile(HostKeyScopes.SystemKeys, h => h.SystemKeys, directory);
            }
        }
Exemple #22
0
        internal static AuthorizationLevel GetAuthorizationLevel(HttpRequestMessage request, SecretManager secretManager, string functionName = null)
        {
            // TODO: Add support for validating "EasyAuth" headers

            // first see if a key value is specified via headers or query string (header takes precidence)
            IEnumerable <string> values;
            string keyValue = null;

            if (request.Headers.TryGetValues(FunctionsKeyHeaderName, out values))
            {
                keyValue = values.FirstOrDefault();
            }
            else
            {
                var queryParameters = request.GetQueryNameValuePairs().ToDictionary(p => p.Key, p => p.Value, StringComparer.OrdinalIgnoreCase);
                queryParameters.TryGetValue("code", out keyValue);
            }

            if (!string.IsNullOrEmpty(keyValue))
            {
                // see if the key specified is the master key
                HostSecrets hostSecrets = secretManager.GetHostSecrets();
                if (!string.IsNullOrEmpty(hostSecrets.MasterKey) &&
                    SecretEqual(keyValue, hostSecrets.MasterKey))
                {
                    return(AuthorizationLevel.Admin);
                }

                // see if the key specified matches the host function key
                if (!string.IsNullOrEmpty(hostSecrets.FunctionKey) &&
                    SecretEqual(keyValue, hostSecrets.FunctionKey))
                {
                    return(AuthorizationLevel.Function);
                }

                // if there is a function specific key specified try to match against that
                if (functionName != null)
                {
                    FunctionSecrets functionSecrets = secretManager.GetFunctionSecrets(functionName);
                    if (functionSecrets != null &&
                        !string.IsNullOrEmpty(functionSecrets.Key) &&
                        SecretEqual(keyValue, functionSecrets.Key))
                    {
                        return(AuthorizationLevel.Function);
                    }
                }
            }

            return(AuthorizationLevel.Anonymous);
        }
        public async Task SetMasterKey_WithoutProvidedKey_GeneratesKeyAndPersistsFile()
        {
            using (var directory = new TempDirectory())
            {
                KeyOperationResult result;
                using (var secretManager = CreateSecretManager(directory.Path, simulateWriteConversion: false))
                {
                    result = await secretManager.SetMasterKeyAsync();
                }

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

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

                Assert.NotNull(persistedSecrets);
                Assert.NotNull(persistedSecrets.MasterKey);
                Assert.Equal(OperationResult.Created, result.Result);
                Assert.Equal(result.Secret, persistedSecrets.MasterKey.Value);
            }
        }
        public void HostKeys(string secretName)
        {
            HostSecrets hostSecrets = new HostSecrets()
            {
                MasterKey    = new Key("master", "test"),
                FunctionKeys = new List <Key>()
                {
                    new Key(secretName, "test")
                },
                SystemKeys = new List <Key>()
                {
                    new Key(secretName, "test")
                },
            };

            Dictionary <string, string> dictionary = KeyVaultSecretsRepository.GetDictionaryFromScriptSecrets(hostSecrets, null);

            Assert.True(dictionary["host--masterKey--master"] == "test");
            Assert.True(dictionary[$"host--functionKey--{KeyVaultSecretsRepository.Normalize(secretName)}"] == "test");
            Assert.True(dictionary[$"host--systemKey--{KeyVaultSecretsRepository.Normalize(secretName)}"] == "test");
        }
Exemple #25
0
            private async Task <ScriptSecrets> GetSecretsFromKeyVault(string functionNameOrHost, ScriptSecretsType type)
            {
                var secretResults = await KeyVaultClient.GetSecretsAsync(GetKeyVaultBaseUrl());

                if (type == ScriptSecretsType.Host)
                {
                    SecretBundle masterBundle = await KeyVaultClient.GetSecretAsync(GetKeyVaultBaseUrl(), secretResults.FirstOrDefault(x => x.Identifier.Name.StartsWith("host--master")).Identifier.Name);

                    SecretBundle functionKeyBundle = await KeyVaultClient.GetSecretAsync(GetKeyVaultBaseUrl(), secretResults.FirstOrDefault(x => x.Identifier.Name.StartsWith("host--functionKey")).Identifier.Name);

                    SecretBundle systemKeyBundle = await KeyVaultClient.GetSecretAsync(GetKeyVaultBaseUrl(), secretResults.FirstOrDefault(x => x.Identifier.Name.StartsWith("host--systemKey")).Identifier.Name);

                    HostSecrets hostSecrets = new HostSecrets()
                    {
                        FunctionKeys = new List <Key>()
                        {
                            new Key(GetSecretName(functionKeyBundle.SecretIdentifier.Name), functionKeyBundle.Value)
                        },
                        SystemKeys = new List <Key>()
                        {
                            new Key(GetSecretName(systemKeyBundle.SecretIdentifier.Name), systemKeyBundle.Value)
                        }
                    };
                    hostSecrets.MasterKey = new Key("master", masterBundle.Value);
                    return(hostSecrets);
                }
                else
                {
                    SecretBundle functionKeyBundle = await KeyVaultClient.GetSecretAsync(GetKeyVaultBaseUrl(), secretResults.FirstOrDefault(x => x.Identifier.Name.StartsWith("function--")).Identifier.Name);

                    FunctionSecrets functionSecrets = new FunctionSecrets()
                    {
                        Keys = new List <Key>()
                        {
                            new Key(GetSecretName(functionKeyBundle.SecretIdentifier.Name), functionKeyBundle.Value)
                        }
                    };
                    return(functionSecrets);
                }
            }
Exemple #26
0
        public void SerializeHostSecrets_ReturnsExpectedResult()
        {
            var serializer = new ScriptSecretSerializerV1();

            var secrets = new HostSecrets
            {
                MasterKey = new Key {
                    Name = "master", Value = "1234"
                },
                FunctionKeys = new List <Key>
                {
                    new Key
                    {
                        Name        = "Key1",
                        Value       = "Value1",
                        IsEncrypted = false
                    },
                    new Key
                    {
                        Name        = "Key2",
                        Value       = "Value2",
                        IsEncrypted = true
                    }
                }
            };

            string serializedSecret = serializer.SerializeSecrets(secrets);

            var jsonObject      = JObject.Parse(serializedSecret);
            var functionSecrets = jsonObject.Property("functionKeys")?.Value?.ToObject <List <Key> >();
            var masterKey       = jsonObject.Property("masterKey")?.Value?.ToObject <Key>();
            var instanceId      = jsonObject.Property("instanceId")?.Value;

            Assert.NotNull(serializedSecret);
            Assert.Equal(secrets.MasterKey, masterKey);
            AssertKeyCollectionsEquality(secrets.FunctionKeys, functionSecrets);
            Assert.Equal(instanceId, secrets.InstanceId);
        }
Exemple #27
0
        public async Task GetSecretSnapshots_ReturnsExpected(SecretsRepositoryType repositoryType, ScriptSecretsType secretsType)
        {
            using (var directory = new TempDirectory())
            {
                await _fixture.TestInitialize(repositoryType, directory.Path);

                ScriptSecrets secrets = null;
                if (secretsType == ScriptSecretsType.Host)
                {
                    secrets = new HostSecrets()
                    {
                        MasterKey = new Key("master", "test")
                    };
                }
                else
                {
                    secrets = new FunctionSecrets()
                    {
                        Keys = new List <Key>()
                        {
                            new Key(KeyName, "test")
                        }
                    };
                }
                string testFunctionName = secretsType == ScriptSecretsType.Host ? null : functionName;

                var target = _fixture.GetNewSecretRepository();
                await target.WriteAsync(secretsType, testFunctionName, secrets);

                for (int i = 0; i < 5; i++)
                {
                    await target.WriteSnapshotAsync(secretsType, testFunctionName, secrets);
                }
                string[] files = await target.GetSecretSnapshots(secretsType, testFunctionName);

                Assert.True(files.Length > 0);
            }
        }
Exemple #28
0
        public async Task ReadAsync_ReadsExpectedKeyVaultPages(SecretsRepositoryType repositoryType, ScriptSecretsType secretsType)
        {
            using (var directory = new TempDirectory())
            {
                await _fixture.TestInitialize(repositoryType, directory.Path);

                ScriptSecrets testSecrets = null;
                int           keyCount    = 35;

                List <Key> functionKeys = new List <Key>();
                for (int i = 0; i < keyCount; ++i)
                {
                    functionKeys.Add(new Key(KeyName + Guid.NewGuid().ToString(), "test" + i.ToString()));
                }

                if (secretsType == ScriptSecretsType.Host)
                {
                    testSecrets = new HostSecrets()
                    {
                        MasterKey    = new Key("master", "test"),
                        FunctionKeys = functionKeys,
                        SystemKeys   = new List <Key>()
                        {
                            new Key(KeyName, "test")
                        }
                    };
                }
                else
                {
                    testSecrets = new FunctionSecrets()
                    {
                        Keys = functionKeys
                    };
                }
                string testFunctionName = secretsType == ScriptSecretsType.Host ? "host" : functionName;

                await _fixture.WriteSecret(testFunctionName, testSecrets);

                var target = _fixture.GetNewSecretRepository();

                ScriptSecrets secretsContent = await target.ReadAsync(secretsType, testFunctionName);

                if (secretsType == ScriptSecretsType.Host)
                {
                    Assert.Equal((secretsContent as HostSecrets).MasterKey.Name, "master");
                    Assert.Equal((secretsContent as HostSecrets).MasterKey.Value, "test");

                    Assert.Equal((secretsContent as HostSecrets).FunctionKeys.Count, functionKeys.Count);
                    foreach (Key originalKey in functionKeys)
                    {
                        var matchingKeys = (secretsContent as HostSecrets).FunctionKeys.Where(x => string.Equals(x.Name, originalKey.Name));
                        Assert.Equal(matchingKeys.Count(), 1);
                        Assert.Equal(matchingKeys.First().Value, originalKey.Value);
                    }

                    Assert.Equal((secretsContent as HostSecrets).SystemKeys[0].Name, KeyName);
                    Assert.Equal((secretsContent as HostSecrets).SystemKeys[0].Value, "test");
                }
                else
                {
                    Assert.Equal((secretsContent as FunctionSecrets).Keys.Count, functionKeys.Count);
                    foreach (Key originalKey in functionKeys)
                    {
                        var matchingKeys = (secretsContent as FunctionSecrets).Keys.Where(x => string.Equals(x.Name, originalKey.Name));
                        Assert.Equal(matchingKeys.Count(), 1);
                        Assert.Equal(matchingKeys.First().Value, originalKey.Value);
                    }
                }
            }
        }
Exemple #29
0
        public async Task WriteAsync_CreatesExpectedFile(SecretsRepositoryType repositoryType, ScriptSecretsType secretsType)
        {
            using (var directory = new TempDirectory())
            {
                await _fixture.TestInitialize(repositoryType, directory.Path);

                ScriptSecrets secrets = null;
                if (secretsType == ScriptSecretsType.Host)
                {
                    secrets = new HostSecrets()
                    {
                        MasterKey    = new Key("master", "test"),
                        FunctionKeys = new List <Key>()
                        {
                            new Key(KeyName, "test")
                        },
                        SystemKeys = new List <Key>()
                        {
                            new Key(KeyName, "test")
                        }
                    };
                }
                else
                {
                    secrets = new FunctionSecrets()
                    {
                        Keys = new List <Key>()
                        {
                            new Key(KeyName, "test")
                        }
                    };
                }
                string testFunctionName = secretsType == ScriptSecretsType.Host ? null : functionName;

                var target = _fixture.GetNewSecretRepository();
                await target.WriteAsync(secretsType, testFunctionName, secrets);

                string filePath = Path.Combine(directory.Path, $"{testFunctionName ?? "host"}.json");

                if (repositoryType == SecretsRepositoryType.BlobStorage || repositoryType == SecretsRepositoryType.BlobStorageSas)
                {
                    Assert.True(_fixture.MarkerFileExists(testFunctionName ?? "host"));
                }

                ScriptSecrets secrets1 = await _fixture.GetSecretText(testFunctionName ?? "host", secretsType);

                if (secretsType == ScriptSecretsType.Host)
                {
                    Assert.Equal((secrets1 as HostSecrets).MasterKey.Name, "master");
                    Assert.Equal((secrets1 as HostSecrets).MasterKey.Value, "test");
                    Assert.Equal((secrets1 as HostSecrets).FunctionKeys[0].Name, KeyName);
                    Assert.Equal((secrets1 as HostSecrets).FunctionKeys[0].Value, "test");
                    Assert.Equal((secrets1 as HostSecrets).SystemKeys[0].Name, KeyName);
                    Assert.Equal((secrets1 as HostSecrets).SystemKeys[0].Value, "test");
                }
                else
                {
                    Assert.Equal((secrets1 as FunctionSecrets).Keys[0].Name, KeyName);
                    Assert.Equal((secrets1 as FunctionSecrets).Keys[0].Value, "test");
                }
            }
        }