PalacePal/Pal.Client/Configuration/AccountConfigurationV7.cs

81 lines
2.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text.Json.Serialization;
using Dalamud.Logging;
namespace Pal.Client.Configuration
{
public class AccountConfigurationV7 : IAccountConfiguration
{
[JsonConstructor]
public AccountConfigurationV7()
{
}
public AccountConfigurationV7(string server, Guid accountId)
{
Server = server;
EncryptedId = EncryptAccountId(accountId);
}
[Obsolete("for V1 import")]
public AccountConfigurationV7(string server, string accountId)
{
Server = server;
if (accountId.StartsWith("s:"))
EncryptedId = accountId;
else if (Guid.TryParse(accountId, out Guid guid))
EncryptedId = EncryptAccountId(guid);
else
throw new InvalidOperationException("invalid account id format");
}
public string EncryptedId { get; init; } = null!;
public string Server { get; set; } = null!;
[JsonIgnore] public bool IsUsable => DecryptAccountId(EncryptedId) != null;
[JsonIgnore] public Guid AccountId => DecryptAccountId(EncryptedId) ?? throw new InvalidOperationException();
public List<string> CachedRoles { get; set; } = new();
private Guid? DecryptAccountId(string id)
{
if (Guid.TryParse(id, out Guid guid) && guid != Guid.Empty)
return guid;
if (!id.StartsWith("s:"))
throw new InvalidOperationException("invalid prefix");
try
{
byte[] guidBytes = ProtectedData.Unprotect(Convert.FromBase64String(id.Substring(2)),
ConfigurationData.Entropy, DataProtectionScope.CurrentUser);
return new Guid(guidBytes);
}
catch (CryptographicException e)
{
PluginLog.Verbose(e, $"Could not load account id {id}");
return null;
}
}
private string EncryptAccountId(Guid g)
{
try
{
byte[] guidBytes = ProtectedData.Protect(g.ToByteArray(), ConfigurationData.Entropy,
DataProtectionScope.CurrentUser);
return $"s:{Convert.ToBase64String(guidBytes)}";
}
catch (CryptographicException)
{
return g.ToString();
}
}
}
}