|
// 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 Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.UserSecrets;
using Microsoft.Extensions.Tools.Internal;
using Newtonsoft.Json.Linq;
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 = new JObject();
if (_secrets != null)
{
foreach (var secret in _secrets.AsEnumerable())
{
contents[secret.Key] = secret.Value;
}
}
// 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.ToString(), 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);
}
}
|