public async virtual Task <IDictionary <string, string> > GetFunctionSecretsAsync(string functionName, bool merged = false) { if (string.IsNullOrEmpty(functionName)) { throw new ArgumentNullException(nameof(functionName)); } functionName = functionName.ToLowerInvariant(); Dictionary <string, string> functionSecrets; _secretsMap.TryGetValue(functionName, out functionSecrets); if (functionSecrets == null) { FunctionSecrets secrets = await LoadFunctionSecretsAsync(functionName); if (secrets == null) { _traceWriter.VerboseFormat(Resources.TraceFunctionSecretGeneration, functionName); secrets = new FunctionSecrets { Keys = new List <Key> { GenerateKey(ScriptConstants.DefaultFunctionKeyName) } }; await PersistSecretsAsync(secrets, functionName); } // Read all secrets, which will run the keys through the appropriate readers secrets.Keys = secrets.Keys.Select(k => _keyValueConverterFactory.ReadKey(k)).ToList(); if (secrets.HasStaleKeys) { _traceWriter.VerboseFormat(Resources.TraceStaleFunctionSecretRefresh, functionName); await RefreshSecretsAsync(secrets, functionName); } Dictionary <string, string> result = secrets.Keys.ToDictionary(s => s.Name, s => s.Value); functionSecrets = _secretsMap.AddOrUpdate(functionName, result, (n, r) => result); } if (merged) { // If merged is true, we combine function specific keys with host level function keys, // prioritizing function specific keys HostSecretsInfo hostSecrets = await GetHostSecretsAsync(); Dictionary <string, string> hostFunctionSecrets = hostSecrets.FunctionKeys; functionSecrets = functionSecrets.Union(hostFunctionSecrets.Where(s => !functionSecrets.ContainsKey(s.Key))) .ToDictionary(kv => kv.Key, kv => kv.Value); } return(functionSecrets); }
public virtual IDictionary <string, string> GetFunctionSecrets(string functionName, bool merged = false) { if (string.IsNullOrEmpty(functionName)) { throw new ArgumentNullException(nameof(functionName)); } functionName = functionName.ToLowerInvariant(); var functionSecrets = _secretsMap.GetOrAdd(functionName, n => { FunctionSecrets secrets; string secretsFilePath = GetFunctionSecretsFilePath(functionName); if (!TryLoadFunctionSecrets(functionName, out secrets, secretsFilePath)) { _traceWriter.VerboseFormat(Resources.TraceFunctionSecretGeneration, functionName); secrets = new FunctionSecrets { Keys = new List <Key> { GenerateKey(ScriptConstants.DefaultFunctionKeyName) } }; PersistSecrets(secrets, secretsFilePath); } // Read all secrets, which will run the keys through the appropriate readers secrets.Keys = secrets.Keys.Select(k => _keyValueConverterFactory.ReadKey(k)).ToList(); if (secrets.HasStaleKeys) { _traceWriter.VerboseFormat(Resources.TraceStaleFunctionSecretRefresh, functionName); RefreshSecrets(secrets, secretsFilePath); } return(secrets.Keys.ToDictionary(s => s.Name, s => s.Value)); }); if (merged) { // If merged is true, we combine function specific keys with host level function keys, // prioritizing function specific keys Dictionary <string, string> hostFunctionSecrets = GetHostSecrets().FunctionKeys; functionSecrets = functionSecrets.Union(hostFunctionSecrets.Where(s => !functionSecrets.ContainsKey(s.Key))) .ToDictionary(kv => kv.Key, kv => kv.Value); } return(functionSecrets); }
private IHttpActionResult AddOrUpdateFunctionSecret(string keyName, string value, string functionName = null) { if (functionName != null && !_scriptHostManager.Instance.Functions.Any(f => string.Equals(f.Name, functionName, StringComparison.OrdinalIgnoreCase))) { return(NotFound()); } KeyOperationResult operationResult; if (functionName == null && string.Equals(keyName, MasterKeyName, StringComparison.OrdinalIgnoreCase)) { operationResult = _secretManager.SetMasterKey(value); } else { operationResult = _secretManager.AddOrUpdateFunctionSecret(keyName, value, functionName); } _traceWriter.VerboseFormat(Resources.TraceKeysApiSecretChange, keyName, functionName ?? "host", operationResult.Result); switch (operationResult.Result) { case OperationResult.Created: { var keyResponse = ApiModelUtility.CreateApiModel(new { name = keyName, value = operationResult.Secret }, Request); return(Created(ApiModelUtility.GetBaseUri(Request), keyResponse)); } case OperationResult.Updated: { var keyResponse = ApiModelUtility.CreateApiModel(new { name = keyName, value = operationResult.Secret }, Request); return(Ok(keyResponse)); } case OperationResult.NotFound: return(NotFound()); case OperationResult.Conflict: return(Conflict()); default: return(InternalServerError()); } }
private async Task <IHttpActionResult> AddOrUpdateSecretAsync(string keyName, string value, string keyScope, ScriptSecretsType secretsType) { if (secretsType == ScriptSecretsType.Function && keyScope != null && !_scriptHostManager.Instance.IsFunction(keyScope)) { return(NotFound()); } KeyOperationResult operationResult; if (secretsType == ScriptSecretsType.Host && string.Equals(keyName, MasterKeyName, StringComparison.OrdinalIgnoreCase)) { operationResult = await _secretManager.SetMasterKeyAsync(value); } else { operationResult = await _secretManager.AddOrUpdateFunctionSecretAsync(keyName, value, keyScope, secretsType); } _traceWriter.VerboseFormat(Resources.TraceKeysApiSecretChange, keyName, keyScope ?? "host", operationResult.Result); switch (operationResult.Result) { case OperationResult.Created: { var keyResponse = ApiModelUtility.CreateApiModel(new { name = keyName, value = operationResult.Secret }, Request); return(Created(ApiModelUtility.GetBaseUri(Request), keyResponse)); } case OperationResult.Updated: { var keyResponse = ApiModelUtility.CreateApiModel(new { name = keyName, value = operationResult.Secret }, Request); return(Ok(keyResponse)); } case OperationResult.NotFound: return(NotFound()); case OperationResult.Conflict: return(Conflict()); default: return(InternalServerError()); } }
private async Task <IHttpActionResult> DeleteFunctionSecretAsync(string keyName, string keyScope, ScriptSecretsType secretsType) { if (keyName == null || keyName.StartsWith("_")) { // System keys cannot be deleted. return(BadRequest("Invalid key name.")); } if ((secretsType == ScriptSecretsType.Function && !_scriptHostManager.Instance.IsFunction(keyScope)) || !await _secretManager.DeleteSecretAsync(keyName, keyScope, secretsType)) { // Either the function or the key were not found return(NotFound()); } string message = string.Format(Resources.TraceKeysApiSecretChange, keyName, keyScope ?? "host", "Deleted"); _traceWriter.VerboseFormat(message); _logger?.LogDebug(message); return(StatusCode(HttpStatusCode.NoContent)); }