| File: Internal\SecretsStore.cs | Web Access |
| Project: src\aspnetcore\src\Tools\dotnet-user-secrets\src\dotnet-user-secrets.csproj (dotnet-user-secrets) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration.UserSecrets; using Microsoft.Extensions.Tools.Internal; namespace Microsoft.Extensions.SecretManager.Tools.Internal; /// <summary> /// This API supports infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public class SecretsStore { private readonly string _secretsFilePath; private readonly IDictionary<string, string> _secrets; public SecretsStore(string userSecretsId, IReporter reporter) { Ensure.NotNull(userSecretsId, nameof(userSecretsId)); _secretsFilePath = PathHelper.GetSecretsPathFromSecretsId(userSecretsId); // workaround bug in configuration var secretDir = Path.GetDirectoryName(_secretsFilePath); Directory.CreateDirectory(secretDir); reporter.Verbose(Resources.FormatMessage_Secret_File_Path(_secretsFilePath)); _secrets = Load(userSecretsId); } public string this[string key] { get { return _secrets[key]; } } public int Count => _secrets.Count; // For testing. internal string SecretsFilePath => _secretsFilePath; public bool ContainsKey(string key) => _secrets.ContainsKey(key); public IEnumerable<KeyValuePair<string, string>> AsEnumerable() => _secrets; public void Clear() => _secrets.Clear(); public void Set(string key, string value) => _secrets[key] = value; public void Remove(string key) { if (_secrets.ContainsKey(key)) { _secrets.Remove(key); } } public virtual void Save() { Directory.CreateDirectory(Path.GetDirectoryName(_secretsFilePath)); var contents = Serialize(_secrets); // Create a temp file with the correct Unix file mode before moving it to the expected _filePath. if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { var tempFilename = Path.GetTempFileName(); File.Move(tempFilename, _secretsFilePath, overwrite: true); } File.WriteAllText(_secretsFilePath, contents, Encoding.UTF8); } protected virtual IDictionary<string, string> Load(string userSecretsId) { return new ConfigurationBuilder() .AddJsonFile(_secretsFilePath, optional: true) .Build() .AsEnumerable() .Where(i => i.Value != null) .ToDictionary(i => i.Key, i => i.Value, StringComparer.OrdinalIgnoreCase); } internal static string Serialize(IDictionary<string, string> secrets) { return JsonSerializer.Serialize(secrets, SecretManagerJsonSerializerContext.Default.IDictionaryStringString); } } [JsonSourceGenerationOptions(WriteIndented = true)] [JsonSerializable(typeof(IDictionary<string, string>))] internal sealed partial class SecretManagerJsonSerializerContext : JsonSerializerContext { }