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");
            }
        }
        public async Task GetHostSecrets_WhenNonDecryptedHostSecrets_SavesAndRefreshes()
        {
            using (var directory = new TempDirectory())
            {
                string expectedTraceMessage = Resources.TraceNonDecryptedHostSecretRefresh;
                string hostSecretsJson      =
                    @"{
    'masterKey': {
        'name': 'master',
        'value': 'cryptoError',
        'encrypted': true
    },
    'functionKeys': [],
    'systemKeys': []
}";
                File.WriteAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName), hostSecretsJson);
                Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(true, false);
                HostSecretsInfo    hostSecrets;
                ISecretsRepository repository = new FileSystemSecretsRepository(directory.Path);

                using (var secretManager = new SecretManager(repository, mockValueConverterFactory.Object, null))
                {
                    hostSecrets = await secretManager.GetHostSecretsAsync();
                }

                Assert.NotNull(hostSecrets);
                Assert.Equal(hostSecrets.MasterKey, "cryptoError");
                var result = JsonConvert.DeserializeObject <HostSecrets>(File.ReadAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName)));
                Assert.Equal(result.MasterKey.Value, "!cryptoError");
                Assert.Equal(1, Directory.GetFiles(directory.Path, $"host.{ScriptConstants.Snapshot}*").Length);
            }
        }
Ejemplo n.º 3
0
 /// <exception cref="System.IO.IOException"/>
 public virtual RPC.Server GetServer <_T0>(Type protocol, object instance, string bindAddress
                                           , int port, int numHandlers, int numReaders, int queueSizePerHandler, bool verbose
                                           , Configuration conf, SecretManager <_T0> secretManager, string portRangeConfig)
     where _T0 : TokenIdentifier
 {
     return(null);
 }
Ejemplo n.º 4
0
 /// <summary>Default: null</summary>
 public virtual RPC.Builder SetSecretManager <_T0>(SecretManager <_T0> secretManager
                                                   )
     where _T0 : TokenIdentifier
 {
     this.secretManager = secretManager;
     return(this);
 }
        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");
            }
        }
Ejemplo n.º 6
0
 public GameController()
 {
     Map                = new Map();
     InputHandler       = new MapInputHandler(this);
     SecretMan          = new SecretManager(this);
     Map.OnPlayerMoved += Map_PlayerMoved;
 }
        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())
            {
                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_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 void GetFunctionSecrets_WhenNoSecretFileExists_CreatesDefaultSecretAndPersistsFile()
        {
            var secretsPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

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

                IDictionary <string, string> functionSecrets;
                using (var secretManager = new SecretManager(secretsPath, mockValueConverterFactory.Object))
                {
                    functionSecrets = secretManager.GetFunctionSecrets("TestFunction");
                }

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

                Assert.NotNull(functionSecrets);
                Assert.True(functionSecretsExists);
                Assert.Equal(1, functionSecrets.Count);
                Assert.Equal(ScriptConstants.DefaultFunctionKeyName, functionSecrets.Keys.First());
            }
            finally
            {
                Directory.Delete(secretsPath, true);
            }
        }
Ejemplo n.º 11
0
        public static byte[] CreateSelfSignedCertificate(string[] alternativeNames, string password)
        {
            string pemKey  = SecretManager.GetSecret <string>("skynet_key");
            string pemCert = SecretManager.GetSecret <string>("skynet_cert");

            Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair rootKey  = ReadAsymmetricKeyParameter(pemKey);
            Org.BouncyCastle.X509.X509Certificate           rootCert = PemStringToX509(pemCert);

            Org.BouncyCastle.Security.SecureRandom          random      = new Org.BouncyCastle.Security.SecureRandom(NonBackdooredPrng.Create());
            Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair certKeyPair = KeyGenerator.GenerateRsaKeyPair(2048, random);

            Org.BouncyCastle.X509.X509Certificate sslCertificate = SelfSignSslCertificate(
                random
                , rootCert
                , certKeyPair.Public
                , rootKey.Private
                , alternativeNames
                );

            bool val = CerGenerator.ValidateSelfSignedCert(sslCertificate, rootCert.GetPublicKey());

            if (val == false)
            {
                throw new System.InvalidOperationException("SSL certificate does NOT validate successfully.");
            }

            byte[] pfx = CreatePfxBytes(sslCertificate, certKeyPair.Private, password);
            return(pfx);
        } // End Function CreateSelfSignedCertificate
        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);
            }
        }
Ejemplo n.º 14
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            Secret secret = SecretManager.GetSecret();

            _logger = new LoggerConfiguration()
                      .WriteTo.Console()
                      .WriteTo.File("2falog.txt", rollingInterval: RollingInterval.Day)
                      .CreateLogger();

            IDocumentSession ravendb =
                RavenDbInitializer.Init(secret.RavenDbFilePath, secret.RavenDbServerUrl);

            services.AddTransient <IAuthFactor>(sp => {
                return(new SMSAuthFactorService(secret.TwilioAccountId, secret.TwilioAuthToken));
            });

            services.AddSingleton(typeof(Logger), _logger);

            services.AddSingleton(typeof(IDocumentSession), sp => { return(ravendb); });

            services.AddSingleton <IOTPCodeRepository>(sp => {
                return(new OTPCodeRepository(ravendb));
            });

            services.AddControllers();
        }
Ejemplo n.º 15
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 async Task GetFunctionSecrets_WhenNoSecretFileExists_CreatesDefaultSecretAndPersistsFile()
        {
            using (var directory = new TempDirectory())
            {
                string functionName         = "TestFunction";
                string expectedTraceMessage = string.Format(Resources.TraceFunctionSecretGeneration, functionName);

                Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false, false);

                IDictionary <string, string> functionSecrets;
                var traceWriter = new TestTraceWriter(System.Diagnostics.TraceLevel.Verbose);
                ISecretsRepository repository = new FileSystemSecretsRepository(directory.Path);
                using (var secretManager = new SecretManager(repository, mockValueConverterFactory.Object, null))
                {
                    functionSecrets = await secretManager.GetFunctionSecretsAsync(functionName);
                }

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

                Assert.NotNull(functionSecrets);
                Assert.True(functionSecretsExists);
                Assert.Equal(1, functionSecrets.Count);
                Assert.Equal(ScriptConstants.DefaultFunctionKeyName, functionSecrets.Keys.First());
            }
        }
        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 Constructor_WithCreateHostSecretsIfMissingSet_CreatesHostSecret()
        {
            var secretsPath    = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            var hostSecretPath = Path.Combine(secretsPath, ScriptConstants.HostMetadataFileName);

            try
            {
                string expectedTraceMessage = Resources.TraceHostSecretGeneration;
                bool   preExistingFile      = File.Exists(hostSecretPath);

                Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false, false);

                var traceWriter = new TestTraceWriter(System.Diagnostics.TraceLevel.Verbose);
                ISecretsRepository repository = new FileSystemSecretsRepository(secretsPath);
                var  secretManager            = new SecretManager(repository, mockValueConverterFactory.Object, null, true);
                bool fileCreated = File.Exists(hostSecretPath);

                Assert.False(preExistingFile);
                Assert.True(fileCreated);
            }
            finally
            {
                Directory.Delete(secretsPath, true);
            }
        }
Ejemplo n.º 19
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);
            }
        }
Ejemplo n.º 20
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);
            }
        }
Ejemplo n.º 21
0
        } // End Function GetDefaultInstance

        public static string GetConnectionString()
        {
            var csb = new System.Data.SqlClient.SqlConnectionStringBuilder();

            csb.DataSource     = GetDefaultInstance();
            csb.InitialCatalog = "COR_Basic_Demo_V4";
            csb.InitialCatalog = "COR_Basic_SwissLife_UAT";
            csb.InitialCatalog = "COR_Basic_SwissLife_PAV";

            if ("RZ".Equals(System.Environment.UserDomainName, System.StringComparison.InvariantCultureIgnoreCase))
            {
                csb.DataSource = @"SQL05\SWL,2138";
            }


            csb.IntegratedSecurity = true;
            // csb.IntegratedSecurity = false;

            if (!csb.IntegratedSecurity)
            {
                csb.UserID   = SecretManager.GetSecret <string>("DefaultDbUser");
                csb.Password = SecretManager.GetSecret <string>("DefaultDbPassword");
            }

            return(csb.ConnectionString);
        } // End Function GetConnectionString
        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);
            }
        }
Ejemplo n.º 23
0
        public WebScriptHostManagerTests(WebScriptHostManagerTests.Fixture fixture)
        {
            _fixture         = fixture;
            _settingsManager = ScriptSettingsManager.Instance;

            string functionTestDir = Path.Combine(_fixture.TestFunctionRoot, Guid.NewGuid().ToString());

            Directory.CreateDirectory(functionTestDir);
            string logDir     = Path.Combine(_fixture.TestLogsRoot, Guid.NewGuid().ToString());
            string secretsDir = Path.Combine(_fixture.TestSecretsRoot, Guid.NewGuid().ToString());

            _config = new ScriptHostConfiguration
            {
                RootLogPath     = logDir,
                RootScriptPath  = functionTestDir,
                FileLoggingMode = FileLoggingMode.Always,
            };

            var             secretsRepository = new FileSystemSecretsRepository(_secretsDirectory.Path);
            SecretManager   secretManager     = new SecretManager(_settingsManager, secretsRepository, NullLogger.Instance);
            WebHostSettings webHostSettings   = new WebHostSettings
            {
                SecretsPath = _secretsDirectory.Path
            };

            var mockEventManager = new Mock <IScriptEventManager>();

            _mockScriptHostFactory = new Mock <IScriptHostFactory>();
            IWebJobsRouter router = fixture.CreateRouter();

            _hostManager = new WebScriptHostManager(_config, new TestSecretManagerFactory(secretManager), mockEventManager.Object,
                                                    _settingsManager, webHostSettings, router, NullLoggerFactory.Instance, secretsRepositoryFactory: new DefaultSecretsRepositoryFactory(),
                                                    hostTimeoutSeconds: 2, hostPollingIntervalMilliseconds: 500, scriptHostFactory: _mockScriptHostFactory.Object);
        }
Ejemplo n.º 24
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);
            }
        }
Ejemplo n.º 25
0
        public static string GetSearchUrl(string vorname, string nachname, string strasse, string plz, string ort, string tel)
        {
            string ApiKey = SecretManager.GetSecret <string>("tel.search.ch API Key");

            // Example:
            // http://tel.search.ch/api/?was=DerVorname+DerName+079&wo=dieStrasse+8586+Erlen&maxnum=20&key=API_KEY_HERE

            return(ConcatQuery("http://tel.search.ch/api/",
                               new System.Collections.Specialized.NameValueCollection()
            {
                { "was", Concat(vorname, nachname, tel) }
                , { "wo", Concat(strasse, plz, ort) }
                , { "key", ApiKey }
            }
                               ));

#if false
            return(ConcatQuery("http://tel.search.ch/api/",
                               new System.Collections.Generic.Dictionary <string, string>()
            {
                { "was", Concat(vorname, nachname, tel) }
                , { "wo", Concat(strasse, plz, ort) }
                , { "key", ApiKey }
            }
                               ));

            return(ConcatQuery("http://tel.search.ch/api/",
                               new { was = Concat(vorname, nachname, tel) }
                               , new { wo = Concat(strasse, plz, ort) }
                               , new { key = ApiKey }
                               ));
#endif
        }
Ejemplo n.º 26
0
        public void GetFunctionSecrets_WhenNoSecretFileExists_ReturnsEmptySecretsAndDoesNotPersistsFile()
        {
            var secretsPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

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

                    IDictionary <string, string> functionSecrets;
                    using (var secretManager = new SecretManager(secretsPath, mockValueConverterFactory.Object))
                    {
                        functionSecrets = secretManager.GetFunctionSecrets("TestFunction");
                    }

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

                    Assert.NotNull(functionSecrets);
                    Assert.False(functionSecretsExists);
                    Assert.Equal(0, functionSecrets.Count);
                }
            }
            finally
            {
                Directory.Delete(secretsPath, true);
            }
        }
Ejemplo n.º 27
0
 public virtual Server GetServer <_T0>(Type protocol, object instance, IPEndPoint addr
                                       , Configuration conf, SecretManager <_T0> secretManager, int numHandlers)
     where _T0 : TokenIdentifier
 {
     return(GetServer(protocol, instance, addr, conf, secretManager, numHandlers, null
                      ));
 }
        public WebScriptHostManagerTests(WebScriptHostManagerTests.Fixture fixture)
        {
            _fixture         = fixture;
            _settingsManager = ScriptSettingsManager.Instance;

            string functionTestDir = Path.Combine(_fixture.TestFunctionRoot, Guid.NewGuid().ToString());

            Directory.CreateDirectory(functionTestDir);
            string logDir     = Path.Combine(_fixture.TestLogsRoot, Guid.NewGuid().ToString());
            string secretsDir = Path.Combine(_fixture.TestSecretsRoot, Guid.NewGuid().ToString());

            _config = new ScriptHostConfiguration
            {
                RootLogPath     = logDir,
                RootScriptPath  = functionTestDir,
                FileLoggingMode = FileLoggingMode.Always,
            };

            var             secretsRepository = new FileSystemSecretsRepository(_secretsDirectory.Path);
            SecretManager   secretManager     = new SecretManager(_settingsManager, secretsRepository, NullTraceWriter.Instance, null);
            WebHostSettings webHostSettings   = new WebHostSettings
            {
                SecretsPath = _secretsDirectory.Path
            };

            var mockEventManager = new Mock <IScriptEventManager>();

            _mockScriptHostFactory = new Mock <IScriptHostFactory>();

            _hostManager = new WebScriptHostManager(_config, new TestSecretManagerFactory(secretManager), mockEventManager.Object,
                                                    _settingsManager, webHostSettings, _mockScriptHostFactory.Object, new DefaultSecretsRepositoryFactory(), 2, 500);
        }
        public async Task GetHostSecrets_AddMetrics()
        {
            using (var directory = new TempDirectory())
            {
                string expectedTraceMessage = Resources.TraceNonDecryptedHostSecretRefresh;
                string hostSecretsJson      =
                    @"{
    'masterKey': {
        'name': 'master',
        'value': 'cryptoError',
        'encrypted': true
    },
    'functionKeys': [],
    'systemKeys': []
}";
                File.WriteAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName), hostSecretsJson);
                Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(true, false);
                HostSecretsInfo    hostSecrets;
                ISecretsRepository repository    = new FileSystemSecretsRepository(directory.Path);
                TestMetricsLogger  metricsLogger = new TestMetricsLogger();

                using (var secretManager = new SecretManager(repository, mockValueConverterFactory.Object, null, metricsLogger, _hostNameProvider))
                {
                    hostSecrets = await secretManager.GetHostSecretsAsync();
                }

                string eventName = string.Format(MetricEventNames.SecretManagerGetHostSecrets, repository.GetType().Name.ToLower());
                metricsLogger.EventsBegan.Single(e => string.Equals(e, eventName));
                metricsLogger.EventsEnded.Single(e => string.Equals(e.ToString(), eventName));
            }
        }
        public async Task GetHostSecrets_UpdatesStaleSecrets()
        {
            using (var directory = new TempDirectory())
            {
                string expectedTraceMessage = Resources.TraceStaleHostSecretRefresh;
                string hostSecretsJson      =
                    @"{
    'masterKey': {
        'name': 'master',
        'value': '1234',
        'encrypted': false
    },
    'functionKeys': [
        {
            'name': 'Key1',
            'value': 'HostValue1',
            'encrypted': false
        },
        {
            'name': 'Key3',
            'value': 'HostValue3',
            'encrypted': false
        }
    ],
    'systemKeys': [
        {
            'name': 'SystemKey1',
            'value': 'SystemHostValue1',
            'encrypted': false
        },
        {
            'name': 'SystemKey2',
            'value': 'SystemHostValue2',
            'encrypted': false
        }
    ]
}";
                File.WriteAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName), hostSecretsJson);

                Mock <IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock();

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

                // Read the persisted content
                var  result = JsonConvert.DeserializeObject <HostSecrets>(File.ReadAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName)));
                bool functionSecretsConverted = hostSecrets.FunctionKeys.Values.Zip(result.FunctionKeys, (r1, r2) => string.Equals("!" + r1, r2.Value)).All(r => r);
                bool systemSecretsConverted   = hostSecrets.SystemKeys.Values.Zip(result.SystemKeys, (r1, r2) => string.Equals("!" + r1, r2.Value)).All(r => r);

                Assert.Equal(2, result.FunctionKeys.Count);
                Assert.Equal(2, result.SystemKeys.Count);
                Assert.Equal("!" + hostSecrets.MasterKey, result.MasterKey.Value);
                Assert.True(functionSecretsConverted, "Function secrets were not persisted");
                Assert.True(systemSecretsConverted, "System secrets were not persisted");
            }
        }
        public void MergedSecrets_PrioritizesFunctionSecrets()
        {
            using (var directory = new TempDirectory())
            {
                string hostSecrets =
                    @"{
    'masterKey': {
        'name': 'master',
        'value': '1234',
        'encrypted': false
    },
    'functionKeys': [
        {
            'name': 'Key1',
            'value': 'HostValue1',
            'encrypted': false
        },
        {
            'name': 'Key3',
            'value': 'HostValue3',
            'encrypted': false
        }
    ]
}";
                string functionSecrets =
                    @"{
    'keys': [
        {
            'name': 'Key1',
            'value': 'FunctionValue1',
            'encrypted': false
        },
        {
            'name': 'Key2',
            'value': 'FunctionValue2',
            'encrypted': false
        }
    ]
}";
                File.WriteAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName), hostSecrets);
                File.WriteAllText(Path.Combine(directory.Path, "testfunction.json"), functionSecrets);

                IDictionary<string, string> result;
                using (var secretManager = new SecretManager(_settingsManager, directory.Path, NullTraceWriter.Instance))
                {
                    result = secretManager.GetFunctionSecrets("testfunction", true);
                }

                Assert.Contains("Key1", result.Keys);
                Assert.Contains("Key2", result.Keys);
                Assert.Contains("Key3", result.Keys);
                Assert.Equal("FunctionValue1", result["Key1"]);
                Assert.Equal("FunctionValue2", result["Key2"]);
                Assert.Equal("HostValue3", result["Key3"]);
            }
        }
        public static bool IsAuthorized(HttpRequestMessage request, AuthorizationLevel level, SecretManager secretManager, string functionName = null)
        {
            if (level == AuthorizationLevel.Anonymous)
            {
                return true;
            }

            AuthorizationLevel requestLevel = GetAuthorizationLevel(request, secretManager, functionName);
            return requestLevel >= level;
        }
        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 WebHookReceiverManager(SecretManager secretManager)
        {
            _httpConfiguration = new HttpConfiguration();

            var builder = new ContainerBuilder();
            builder.RegisterInstance<IWebHookHandler>(new DelegatingWebHookHandler());
            builder.RegisterInstance<IWebHookReceiverConfig>(new DynamicWebHookReceiverConfig(secretManager));
            var container = builder.Build();

            WebHooksConfig.Initialize(_httpConfiguration);

            _httpConfiguration.DependencyResolver = new AutofacWebApiDependencyResolver(container);

            IEnumerable<IWebHookReceiver> receivers = _httpConfiguration.DependencyResolver.GetReceivers();
            _receiverLookup = receivers.ToDictionary(p => p.Name, p => p, StringComparer.OrdinalIgnoreCase);
        }
        internal static void Initialize(ContainerBuilder builder, WebHostSettings settings)
        {
            ScriptHostConfiguration scriptHostConfig = new ScriptHostConfiguration()
            {
                RootScriptPath = settings.ScriptPath,
                RootLogPath = settings.LogPath,
                FileLoggingEnabled = true
            };

            // If running on Azure Web App, derive the host ID from the site name
            string hostId = Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME");
            if (!String.IsNullOrEmpty(hostId))
            {
                // Truncate to the max host name length if needed
                const int MaximumHostIdLength = 32;
                if (hostId.Length > MaximumHostIdLength)
                {
                    hostId = hostId.Substring(0, MaximumHostIdLength);
                }

                // Trim any trailing - as they can cause problems with queue names
                hostId = hostId.TrimEnd('-');

                scriptHostConfig.HostConfig.HostId = hostId.ToLowerInvariant();
            }

            WebScriptHostManager scriptHostManager = new WebScriptHostManager(scriptHostConfig);
            builder.RegisterInstance<WebScriptHostManager>(scriptHostManager);

            SecretManager secretManager = new SecretManager(settings.SecretsPath);
            // Make sure that host secrets get created on startup if they don't exist
            secretManager.GetHostSecrets();
            builder.RegisterInstance<SecretManager>(secretManager);

            WebHookReceiverManager webHookReceiverManager = new WebHookReceiverManager(secretManager);
            builder.RegisterInstance<WebHookReceiverManager>(webHookReceiverManager);

            if (!settings.IsSelfHost)
            {
                HostingEnvironment.QueueBackgroundWorkItem((ct) => scriptHostManager.RunAndBlock(ct));
            }
            else
            {
                Task.Run(() => scriptHostManager.RunAndBlock());
            }
        }
        internal static void Initialize(ContainerBuilder builder)
        {
            string logFilePath;
            string scriptRootPath;
            string secretsPath;
            string home = Environment.GetEnvironmentVariable("HOME");
            bool isLocal = string.IsNullOrEmpty(home);
            if (isLocal)
            {
                // we're running locally
                scriptRootPath = Path.Combine(HostingEnvironment.ApplicationPhysicalPath, @"..\..\sample");
                logFilePath = Path.Combine(Path.GetTempPath(), @"Functions");
                secretsPath = HttpContext.Current.Server.MapPath("~/App_Data/Secrets");
            }
            else
            {
                // we're running in Azure
                scriptRootPath = Path.Combine(home, @"site\wwwroot");
                logFilePath = Path.Combine(home, @"LogFiles\Application\Functions");
                secretsPath = Path.Combine(home, @"data\Functions\secrets");
            }

            ScriptHostConfiguration scriptHostConfig = new ScriptHostConfiguration()
            {
                RootScriptPath = scriptRootPath,
                RootLogPath = logFilePath,
                FileLoggingEnabled = true
            };
            WebScriptHostManager scriptHostManager = new WebScriptHostManager(scriptHostConfig);
            builder.RegisterInstance<WebScriptHostManager>(scriptHostManager);

            SecretManager secretManager = new SecretManager(secretsPath);
            builder.RegisterInstance<SecretManager>(secretManager);

            WebHookReceiverManager webHookRecieverManager = new WebHookReceiverManager(secretManager);
            builder.RegisterInstance<WebHookReceiverManager>(webHookRecieverManager);

            Task.Run(() => scriptHostManager.RunAndBlock(CancellationToken.None));
        }
        public void GetHostSecrets_UpdatesStaleSecrets()
        {
            using (var directory = new TempDirectory())
            {
                string expectedTraceMessage = Resources.TraceStaleHostSecretRefresh;
                string hostSecretsJson =
                    @"{
    'masterKey': {
        'name': 'master',
        'value': '1234',
        'encrypted': false
    },
    'functionKeys': [
        {
            'name': 'Key1',
            'value': 'HostValue1',
            'encrypted': false
        },
        {
            'name': 'Key3',
            'value': 'HostValue3',
            'encrypted': false
        }
    ]
}";
                File.WriteAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName), hostSecretsJson);

                Mock<IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock();

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

                // Read the persisted content
                var result = JsonConvert.DeserializeObject<HostSecrets>(File.ReadAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName)));
                bool functionSecretsConverted = hostSecrets.FunctionKeys.Values.Zip(result.FunctionKeys, (r1, r2) => string.Equals("!" + r1, r2.Value)).All(r => r);

                Assert.Equal(2, result.FunctionKeys.Count);
                Assert.Equal("!" + hostSecrets.MasterKey, result.MasterKey.Value);
                Assert.True(functionSecretsConverted, "Function secrets were not persisted");
                Assert.True(traceWriter.Traces.Any(t => t.Level == TraceLevel.Verbose && t.Message.IndexOf(expectedTraceMessage) > -1));
            }
        }
        public void GetFunctionSecrets_WhenNoSecretFileExists_CreatesDefaultSecretAndPersistsFile()
        {
            using (var directory = new TempDirectory())
            {
                string functionName = "TestFunction";
                string expectedTraceMessage = string.Format(Resources.TraceFunctionSecretGeneration, functionName);

                Mock<IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false, false);

                IDictionary<string, string> functionSecrets;
                var traceWriter = new TestTraceWriter(TraceLevel.Verbose);
                using (var secretManager = new SecretManager(directory.Path, mockValueConverterFactory.Object, traceWriter))
                {
                    functionSecrets = secretManager.GetFunctionSecrets(functionName);
                }

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

                Assert.NotNull(functionSecrets);
                Assert.True(functionSecretsExists);
                Assert.Equal(1, functionSecrets.Count);
                Assert.Equal(ScriptConstants.DefaultFunctionKeyName, functionSecrets.Keys.First());
                Assert.True(traceWriter.Traces.Any(
                    t => t.Level == TraceLevel.Verbose && t.Message.IndexOf(expectedTraceMessage, StringComparison.OrdinalIgnoreCase) > -1),
                    "Expected Trace message not found");
            }
        }
        public void 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);
                using (var secretManager = new SecretManager(directory.Path, mockValueConverterFactory.Object, traceWriter))
                {
                    result = secretManager.AddOrUpdateFunctionSecret(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");
            }
        }
        public void 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);
                using (var secretManager = new SecretManager(directory.Path, mockValueConverterFactory.Object, traceWriter))
                {
                    result = secretManager.AddOrUpdateFunctionSecret(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 void 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);
                using (var secretManager = new SecretManager(directory.Path, mockValueConverterFactory.Object, traceWriter))
                {
                    result = secretManager.SetMasterKey();
                }

                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 void Constructor_WithCreateHostSecretsIfMissingSet_CreatesHostSecret()
        {
            var secretsPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            var hostSecretPath = Path.Combine(secretsPath, ScriptConstants.HostMetadataFileName);
            try
            {
                string expectedTraceMessage = Resources.TraceHostSecretGeneration;
                bool preExistingFile = File.Exists(hostSecretPath);

                Mock<IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock(false, false);

                var traceWriter = new TestTraceWriter(TraceLevel.Verbose);
                var secretManager = new SecretManager(secretsPath, mockValueConverterFactory.Object, traceWriter, true);
                bool fileCreated = File.Exists(hostSecretPath);

                Assert.False(preExistingFile);
                Assert.True(fileCreated);
                Assert.True(traceWriter.Traces.Any(t => t.Level == TraceLevel.Verbose && t.Message.IndexOf(expectedTraceMessage) > -1));
            }
            finally
            {
                Directory.Delete(secretsPath, true);
            }
        }
        public void GetFunctionSecrets_UpdatesStaleSecrets()
        {
            using (var directory = new TempDirectory())
            {
                string functionName = "testfunction";
                string expectedTraceMessage = string.Format(Resources.TraceStaleFunctionSecretRefresh, functionName);
                string functionSecretsJson =
                 @"{
    'keys': [
        {
            'name': 'Key1',
            'value': 'FunctionValue1',
            'encrypted': false
        },
        {
            'name': 'Key2',
            'value': 'FunctionValue2',
            'encrypted': false
        }
    ]
}";
                File.WriteAllText(Path.Combine(directory.Path, functionName + ".json"), functionSecretsJson);

                Mock<IKeyValueConverterFactory> mockValueConverterFactory = GetConverterFactoryMock();

                IDictionary<string, string> functionSecrets;
                var traceWriter = new TestTraceWriter(TraceLevel.Verbose);
                using (var secretManager = new SecretManager(directory.Path, mockValueConverterFactory.Object, traceWriter))
                {
                    functionSecrets = secretManager.GetFunctionSecrets(functionName);
                }
                // Read the persisted content
                var result = JsonConvert.DeserializeObject<FunctionSecrets>(File.ReadAllText(Path.Combine(directory.Path, functionName + ".json")));
                bool functionSecretsConverted = functionSecrets.Values.Zip(result.Keys, (r1, r2) => string.Equals("!" + r1, r2.Value)).All(r => r);

                Assert.Equal(2, result.Keys.Count);
                Assert.True(functionSecretsConverted, "Function secrets were not persisted");
                Assert.True(traceWriter.Traces.Any(t => t.Level == TraceLevel.Verbose && t.Message.IndexOf(expectedTraceMessage) > -1));
            }
        }
        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));
            }
        }
        internal async Task GeneratedMethods_WithOutParams_DoNotCauseDeadlocks(string fixture)
        {
            var traceWriter = new TestTraceWriter(TraceLevel.Verbose);

            ScriptHostConfiguration config = new ScriptHostConfiguration()
            {
                RootScriptPath = @"TestScripts\FunctionGeneration",
                TraceWriter = traceWriter
            };

            string secretsPath = Path.Combine(Path.GetTempPath(), @"FunctionTests\Secrets");
            WebHostSettings webHostSettings = new WebHostSettings();
            var secretManager = new SecretManager(SettingsManager, secretsPath, NullTraceWriter.Instance);

            using (var manager = new WebScriptHostManager(config, new TestSecretManagerFactory(secretManager), SettingsManager, webHostSettings))
            {
                Thread runLoopThread = new Thread(_ =>
                {
                    manager.RunAndBlock(CancellationToken.None);
                });
                runLoopThread.IsBackground = true;
                runLoopThread.Start();

                await TestHelpers.Await(() =>
                {
                    return manager.State == ScriptHostState.Running;
                });

                var request = new HttpRequestMessage(HttpMethod.Get, String.Format("http://localhost/api/httptrigger-{0}", fixture));
                FunctionDescriptor function = manager.GetHttpFunctionOrNull(request);

                SynchronizationContext currentContext = SynchronizationContext.Current;
                var resetEvent = new ManualResetEventSlim();

                try
                {
                    var requestThread = new Thread(() =>
                    {
                        var context = new SingleThreadSynchronizationContext();
                        SynchronizationContext.SetSynchronizationContext(context);

                        manager.HandleRequestAsync(function, request, CancellationToken.None)
                        .ContinueWith(task => resetEvent.Set());

                        Thread.Sleep(500);
                        context.Run();
                    });

                    requestThread.IsBackground = true;
                    requestThread.Start();

                    bool threadSignaled = resetEvent.Wait(TimeSpan.FromSeconds(10));

                    requestThread.Abort();

                    Assert.True(threadSignaled, "Thread execution did not complete");
                }
                finally
                {
                    SynchronizationContext.SetSynchronizationContext(currentContext);
                    manager.Stop();
                }
            }
        }
 public DynamicWebHookReceiverConfig(SecretManager secretManager)
 {
     _secretManager = secretManager;
 }