Пример #1
0
 public async Task FileSystemRepo_WriteAsync_CreatesExpectedFile(ScriptSecretsType secretsType)
 {
     await WriteAsync_CreatesExpectedFile(SecretsRepositoryType.FileSystem, secretsType);
 }
Пример #2
0
        private 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");
                }
            }
        }
Пример #3
0
 public async Task BlobStorageRepo_WriteAsync_CreatesExpectedFile(ScriptSecretsType secretsType)
 {
     await WriteAsync_CreatesExpectedFile(SecretsRepositoryType.BlobStorage, secretsType);
 }
Пример #4
0
        public virtual Task <KeyOperationResult> AddOrUpdateFunctionSecretAsync(string secretName, string secret, string keyScope, ScriptSecretsType secretsType)
        {
            string resultSecret = secret ?? "generated";

            return(Task.FromResult(new KeyOperationResult(resultSecret, OperationResult.Created)));
        }
Пример #5
0
 public async Task KeyVaultRepo_ReadAsync_ReadsExpectedFile(ScriptSecretsType secretsType)
 {
     await ReadAsync_ReadsExpectedFile(SecretsRepositoryType.KeyVault, secretsType);
 }
Пример #6
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);
            }
        }
            private async Task <ScriptSecrets> GetSecretBlobText(string functionNameOrHost, ScriptSecretsType type)
            {
                string blobText = null;
                string blobPath = RelativeBlobPath(functionNameOrHost);

                if (await BlobContainer.GetBlockBlobReference(blobPath).ExistsAsync())
                {
                    blobText = await BlobContainer.GetBlockBlobReference(blobPath).DownloadTextAsync();
                }
                return(ScriptSecretSerializer.DeserializeSecrets(type, blobText));
            }
Пример #8
0
        public async Task <KeyOperationResult> AddOrUpdateFunctionSecretAsync(string secretName, string secret, string keyScope, ScriptSecretsType secretsType)
        {
            Func <ScriptSecrets> secretsFactory = null;

            if (secretsType == ScriptSecretsType.Function)
            {
                secretsFactory = () => new FunctionSecrets(new List <Key>());
            }
            else if (secretsType == ScriptSecretsType.Host)
            {
                secretsType    = ScriptSecretsType.Host;
                secretsFactory = GenerateHostSecrets;
            }
            else
            {
                throw new NotSupportedException($"Secrets type {secretsType.ToString("G")} not supported.");
            }

            KeyOperationResult result = await AddOrUpdateSecretAsync(secretsType, keyScope, secretName, secret, secretsFactory);

            _logger.LogInformation(string.Format(Resources.TraceAddOrUpdateFunctionSecret, secretsType, secretName, keyScope ?? "host", result.Result));

            return(result);
        }
Пример #9
0
        public async Task <bool> DeleteSecretAsync(string secretName, string keyScope, ScriptSecretsType secretsType)
        {
            bool deleted = await ModifyFunctionSecretAsync(secretsType, keyScope, secretName, (secrets, key) =>
            {
                secrets?.RemoveKey(key, keyScope);
                return(secrets);
            });

            if (deleted)
            {
                string target = secretsType == ScriptSecretsType.Function
                    ? $"Function ('{keyScope}')"
                    : $"Host (scope: '{keyScope}')";

                _logger.LogInformation(string.Format(Resources.TraceSecretDeleted, target, secretName));
            }

            return(deleted);
        }
Пример #10
0
        private async Task <IActionResult> DeleteFunctionSecretAsync(string keyName, string keyScope, ScriptSecretsType secretsType)
        {
            if (keyName == null)
            {
                return(BadRequest("Invalid key name."));
            }

            if (IsBuiltInSystemKeyName(keyName))
            {
                // System keys cannot be deleted.
                return(BadRequest("Cannot delete System Key."));
            }

            if ((secretsType == ScriptSecretsType.Function && keyScope != null && !IsFunction(keyScope)) ||
                !await _secretManagerProvider.Current.DeleteSecretAsync(keyName, keyScope, secretsType))
            {
                // Either the function or the key were not found
                return(NotFound());
            }

            await _functionsSyncManager.TrySyncTriggersAsync();

            _logger.LogDebug(string.Format(Resources.TraceKeysApiSecretChange, keyName, keyScope ?? "host", "Deleted"));

            return(StatusCode(StatusCodes.Status204NoContent));
        }
Пример #11
0
 private string GetSecretsBlobPath(ScriptSecretsType secretsType, string functionName = null)
 {
     return(secretsType == ScriptSecretsType.Host
         ? _hostSecretsBlobPath
         : string.Format("{0}/{1}", _secretsBlobPath, GetSecretFileName(functionName)));
 }
Пример #12
0
        private async Task <IActionResult> AddOrUpdateSecretAsync(string keyName, string value, string keyScope, ScriptSecretsType secretsType)
        {
            if (secretsType == ScriptSecretsType.Function && keyScope != null && !IsFunction(keyScope))
            {
                return(NotFound());
            }

            KeyOperationResult operationResult;

            if (secretsType == ScriptSecretsType.Host && string.Equals(keyName, MasterKeyName, StringComparison.OrdinalIgnoreCase))
            {
                operationResult = await _secretManagerProvider.Current.SetMasterKeyAsync(value);
            }
            else
            {
                operationResult = await _secretManagerProvider.Current.AddOrUpdateFunctionSecretAsync(keyName, value, keyScope, secretsType);
            }

            _logger.LogDebug(string.Format(Resources.TraceKeysApiSecretChange, keyName, keyScope ?? "host", operationResult.Result));

            switch (operationResult.Result)
            {
            case OperationResult.Created:
            {
                var keyResponse = ApiModelUtility.CreateApiModel(new { name = keyName, value = operationResult.Secret }, Request);
                await _functionsSyncManager.TrySyncTriggersAsync();

                return(Created(ApiModelUtility.GetBaseUri(Request), keyResponse));
            }

            case OperationResult.Updated:
            {
                var keyResponse = ApiModelUtility.CreateApiModel(new { name = keyName, value = operationResult.Secret }, Request);
                await _functionsSyncManager.TrySyncTriggersAsync();

                return(Ok(keyResponse));
            }

            case OperationResult.NotFound:
                return(NotFound());

            case OperationResult.Conflict:
                return(StatusCode(StatusCodes.Status409Conflict));

            case OperationResult.Forbidden:
                return(StatusCode(StatusCodes.Status403Forbidden));

            default:
                return(StatusCode(StatusCodes.Status500InternalServerError));
            }
        }
Пример #13
0
        private async Task <IActionResult> PutKeyAsync(string keyName, Key key, string keyScope, ScriptSecretsType secretsType)
        {
            if (key?.Value == null)
            {
                return(BadRequest("Invalid key value"));
            }

            return(await AddOrUpdateSecretAsync(keyName, key.Value, keyScope, secretsType));
        }
            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);
                }
            }
Пример #15
0
 public async Task KeyVaultRepo_WriteAsync_CreatesExpectedFile(ScriptSecretsType secretsType)
 {
     await WriteAsync_CreatesExpectedFile(SecretsRepositoryType.KeyVault, secretsType);
 }
Пример #16
0
 private Task <ScriptSecrets> LoadSecretsAsync(ScriptSecretsType secretsType, string keyScope)
 => LoadSecretsAsync(secretsType, keyScope, s => ScriptSecretSerializer.DeserializeSecrets(secretsType, s));
Пример #17
0
        private 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)
                {
                    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");
                }
            }
        }
Пример #18
0
 public virtual Task <bool> DeleteSecretAsync(string secretName, string keyScope, ScriptSecretsType secretsType)
 {
     return(Task.FromResult(true));
 }
Пример #19
0
            public async Task <ScriptSecrets> GetSecretText(string functionNameOrHost, ScriptSecretsType type)
            {
                ScriptSecrets secrets = null;

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

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

                    break;

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

                    break;

                default:
                    break;
                }
                return(secrets);
            }
 private static bool TryLoadSecrets(ScriptSecretsType secretsType, string filePath, out ScriptSecrets secrets)
 => TryLoadSecrets(filePath, s => ScriptSecretSerializer.DeserializeSecrets(secretsType, s), out secrets);