| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- using System.Text.RegularExpressions;
- using Admin.NET.Core;
- using Microsoft.Extensions.Logging;
- namespace Admin.NET.Plugin.AiDOP.DataPlatform;
- public interface IMdpSourcePasswordResolver
- {
- /// <summary>解析数据源口令。返回值不得写入日志、实体或数据库。</summary>
- string Resolve(string sourceCode, string? storedSecret);
- }
- public sealed class MdpSourceSecretException : Exception
- {
- public string Code { get; }
- public MdpSourceSecretException(string code, string message) : base(message)
- {
- Code = code;
- }
- }
- /// <summary>
- /// 口令只在建连时解析:环境变量优先,其次系统密文,最后才是迁移期明文。
- /// </summary>
- public sealed class MdpSourcePasswordResolver : IMdpSourcePasswordResolver, ITransient
- {
- private readonly ILogger<MdpSourcePasswordResolver>? _logger;
- public MdpSourcePasswordResolver(ILogger<MdpSourcePasswordResolver>? logger = null)
- {
- _logger = logger;
- }
- public static string EnvironmentVariableName(string sourceCode)
- {
- if (string.IsNullOrWhiteSpace(sourceCode))
- throw new ArgumentException("sourceCode 不能为空", nameof(sourceCode));
- var token = Regex.Replace(sourceCode.Trim().ToUpperInvariant(), "[^A-Z0-9]", "_");
- return "AIDOP_MDP_SOURCE_" + token + "_PASSWORD";
- }
- public string Resolve(string sourceCode, string? storedSecret)
- => ResolveCore(sourceCode, storedSecret, DecryptStored, _logger);
- internal static string ResolveCore(
- string sourceCode,
- string? storedSecret,
- Func<string, string?> decrypt,
- ILogger? logger)
- {
- var envName = EnvironmentVariableName(sourceCode);
- var fromEnv = Environment.GetEnvironmentVariable(envName);
- if (!string.IsNullOrEmpty(fromEnv))
- return fromEnv;
- if (!string.IsNullOrEmpty(storedSecret))
- {
- if (TryDecrypt(storedSecret, decrypt, out var plain))
- return plain;
- logger?.LogWarning(
- "mdp source {SourceCode} still uses a legacy plaintext secret. Set {EnvName} and clear the stored value.",
- sourceCode, envName);
- return storedSecret;
- }
- throw new MdpSourceSecretException(
- "SECRET_MISSING",
- $"源 {sourceCode} 未配置口令。请设置环境变量 {envName}。");
- }
- private static string? DecryptStored(string stored)
- {
- var decrypted = CryptogramUtil.Decrypt(stored);
- return decrypted;
- }
- private static bool TryDecrypt(string stored, Func<string, string?> decrypt, out string plain)
- {
- plain = "";
- try
- {
- var decrypted = decrypt(stored);
- // 原样返回入参不是解密成功,按迁移期明文处理。
- if (string.IsNullOrEmpty(decrypted) || string.Equals(decrypted, stored, StringComparison.Ordinal))
- return false;
- plain = decrypted;
- return true;
- }
- catch
- {
- return false;
- }
- }
- }
|