59 lines
2.3 KiB
C#
59 lines
2.3 KiB
C#
namespace WxAgent.Core;
|
|
|
|
public sealed record RemoteAccountIdentity(string AccountId, bool Verified);
|
|
|
|
public sealed record RemoteAccountContextSnapshot(
|
|
string? ActiveAccountId,
|
|
long Revision,
|
|
bool Confirmed);
|
|
|
|
public sealed class RemoteAccountContext
|
|
{
|
|
private readonly object _gate = new();
|
|
private RemoteAccountContextSnapshot _snapshot = new(null, 0, false);
|
|
|
|
public RemoteAccountContextSnapshot Snapshot
|
|
{
|
|
get { lock (_gate) return _snapshot; }
|
|
}
|
|
|
|
public RemoteAccountContextSnapshot SwitchTo(
|
|
string accountId,
|
|
IReadOnlyCollection<RemoteAccountIdentity> identities,
|
|
bool hasInFlightWrites = false)
|
|
{
|
|
RemoteAgentOptions.ValidateIdentifier(accountId, "accountId", 200);
|
|
ArgumentNullException.ThrowIfNull(identities);
|
|
lock (_gate)
|
|
{
|
|
if (hasInFlightWrites && !string.Equals(_snapshot.ActiveAccountId, accountId, StringComparison.Ordinal))
|
|
throw new WxAgentException(WxAgentErrorCode.InvalidOperationState, "Account switching is blocked while a write operation is in flight.");
|
|
var matches = identities.Where(identity => string.Equals(identity.AccountId, accountId, StringComparison.Ordinal)).ToArray();
|
|
if (matches.Length != 1 || !matches[0].Verified)
|
|
{
|
|
_snapshot = new RemoteAccountContextSnapshot(null, checked(_snapshot.Revision + 1), false);
|
|
throw new WxAgentException(WxAgentErrorCode.AccountContextUnconfirmed, "The requested account identity could not be confirmed.");
|
|
}
|
|
if (_snapshot.Confirmed && string.Equals(_snapshot.ActiveAccountId, accountId, StringComparison.Ordinal))
|
|
return _snapshot;
|
|
_snapshot = new RemoteAccountContextSnapshot(accountId, checked(_snapshot.Revision + 1), true);
|
|
return _snapshot;
|
|
}
|
|
}
|
|
|
|
public void Invalidate()
|
|
{
|
|
lock (_gate)
|
|
{
|
|
if (!_snapshot.Confirmed && _snapshot.ActiveAccountId is null) return;
|
|
_snapshot = new RemoteAccountContextSnapshot(null, checked(_snapshot.Revision + 1), false);
|
|
}
|
|
}
|
|
|
|
public bool IsConfirmedFor(string accountId)
|
|
{
|
|
lock (_gate)
|
|
return _snapshot.Confirmed && string.Equals(_snapshot.ActiveAccountId, accountId, StringComparison.Ordinal);
|
|
}
|
|
}
|