WorkCamera/client/WorkCameraExport/Services/ConfigService.cs
2026-01-06 00:42:25 +08:00

205 lines
6.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using WorkCameraExport.Models;
using WorkCameraExport.Services.Interfaces;
namespace WorkCameraExport.Services
{
/// <summary>
/// 配置服务实现 - 负责配置文件和登录凭证的管理
/// </summary>
public class ConfigService : IConfigService
{
// 用于加密凭证的密钥AES-256 需要 32 字节密钥16 字节 IV
private static readonly byte[] EncryptionKey = Encoding.UTF8.GetBytes("WorkCameraExport2025SecretKey!!!"); // 32 bytes
private static readonly byte[] EncryptionIV = Encoding.UTF8.GetBytes("WCE2025InitVect!"); // 16 bytes
private static readonly JsonSerializerOptions JsonOptions = new()
{
WriteIndented = true,
PropertyNameCaseInsensitive = true
};
public ConfigService()
{
}
/// <summary>
/// 用于测试的构造函数
/// </summary>
public ConfigService(string _)
{
}
#region IConfigService
public string AppDataPath => PathService.BaseDirectory;
public string TempPath => PathService.TempDirectory;
public string LogPath => PathService.LogDirectory;
public bool HasSavedCredentials => File.Exists(PathService.CredentialsFile);
public AppConfig LoadConfig()
{
try
{
var path = PathService.ConfigFile;
if (File.Exists(path))
{
var json = File.ReadAllText(path);
var config = JsonSerializer.Deserialize<AppConfig>(json, JsonOptions);
if (config != null)
{
config.Validate();
return config;
}
}
}
catch
{
// 加载失败时返回默认配置
}
return AppConfig.CreateDefault();
}
public void SaveConfig(AppConfig config)
{
config.Validate();
var json = JsonSerializer.Serialize(config, JsonOptions);
File.WriteAllText(PathService.ConfigFile, json);
}
public void SaveCredentials(string serverUrl, string token, string username)
{
var credentials = new CredentialsData
{
ServerUrl = serverUrl,
Token = token,
Username = username,
SavedAt = DateTime.Now
};
var json = JsonSerializer.Serialize(credentials, JsonOptions);
var encrypted = Encrypt(json);
File.WriteAllBytes(PathService.CredentialsFile, encrypted);
}
public (string ServerUrl, string Token, string Username)? LoadCredentials()
{
try
{
var path = PathService.CredentialsFile;
if (!File.Exists(path))
return null;
var encrypted = File.ReadAllBytes(path);
var json = Decrypt(encrypted);
var credentials = JsonSerializer.Deserialize<CredentialsData>(json, JsonOptions);
if (credentials != null &&
!string.IsNullOrEmpty(credentials.ServerUrl) &&
!string.IsNullOrEmpty(credentials.Token))
{
return (credentials.ServerUrl, credentials.Token, credentials.Username);
}
}
catch
{
// 解密失败时清除凭证
ClearCredentials();
}
return null;
}
public void ClearCredentials()
{
try
{
var path = PathService.CredentialsFile;
if (File.Exists(path))
{
File.Delete(path);
}
}
catch
{
// 忽略删除错误
}
}
public void CleanTempFiles()
{
try
{
var tempPath = PathService.TempDirectory;
if (Directory.Exists(tempPath))
{
var directory = new DirectoryInfo(tempPath);
foreach (var file in directory.GetFiles())
{
try { file.Delete(); } catch { }
}
foreach (var dir in directory.GetDirectories())
{
try { dir.Delete(true); } catch { }
}
}
}
catch
{
// 忽略清理错误
}
}
#endregion
#region
private static byte[] Encrypt(string plainText)
{
using var aes = Aes.Create();
aes.Key = EncryptionKey;
aes.IV = EncryptionIV;
using var encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
using var ms = new MemoryStream();
using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
using (var sw = new StreamWriter(cs))
{
sw.Write(plainText);
}
return ms.ToArray();
}
private static string Decrypt(byte[] cipherText)
{
using var aes = Aes.Create();
aes.Key = EncryptionKey;
aes.IV = EncryptionIV;
using var decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
using var ms = new MemoryStream(cipherText);
using var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);
using var sr = new StreamReader(cs);
return sr.ReadToEnd();
}
#endregion
#region
private class CredentialsData
{
public string ServerUrl { get; set; } = "";
public string Token { get; set; } = "";
public string Username { get; set; } = "";
public DateTime SavedAt { get; set; }
}
#endregion
}
}