feat(sessions): record OwnerKeyId on session creation
Add a nullable string? OwnerKeyId property to GatewaySession that captures the API key identifier (KeyId) of the authenticated caller that opened the session. Wire it through ISessionManager.OpenSessionAsync → SessionManager → GatewaySession constructor. The gRPC service passes identityAccessor .Current?.KeyId; internal callers (GatewayAlarmMonitor, DashboardLiveDataService) pass null. Covers the positive and null cases with two new TDD-first tests.
This commit is contained in:
@@ -203,6 +203,7 @@ public sealed class GatewayAlarmMonitor : BackgroundService, IGatewayAlarmServic
|
||||
GatewaySession session = await _sessionManager.OpenSessionAsync(
|
||||
new SessionOpenRequest(BackendName, MonitorClientName, Guid.NewGuid().ToString("N"), CommandTimeout: null),
|
||||
MonitorClientName,
|
||||
ownerKeyId: null,
|
||||
stoppingToken)
|
||||
.ConfigureAwait(false);
|
||||
lock (_sync) { _session = session; }
|
||||
|
||||
@@ -138,6 +138,7 @@ public sealed class DashboardLiveDataService : IDashboardLiveDataService, IAsync
|
||||
GatewaySession session = await _sessionManager.OpenSessionAsync(
|
||||
new SessionOpenRequest(BackendName, ClientName, Guid.NewGuid().ToString("N"), CommandTimeout: null),
|
||||
ClientName,
|
||||
ownerKeyId: null,
|
||||
cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ public sealed class MxAccessGatewayService(
|
||||
.OpenSessionAsync(
|
||||
SessionOpenRequest.FromContract(request),
|
||||
ResolveClientIdentity(),
|
||||
identityAccessor.Current?.KeyId,
|
||||
context.CancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ public sealed class GatewaySession
|
||||
pipeName,
|
||||
nonce,
|
||||
clientIdentity,
|
||||
ownerKeyId: null,
|
||||
clientSessionName,
|
||||
clientCorrelationId,
|
||||
commandTimeout,
|
||||
@@ -66,6 +67,7 @@ public sealed class GatewaySession
|
||||
/// <param name="pipeName">Name of the named pipe for gateway-worker IPC.</param>
|
||||
/// <param name="nonce">Security nonce for worker validation.</param>
|
||||
/// <param name="clientIdentity">Client identity from the authentication context.</param>
|
||||
/// <param name="ownerKeyId">API key identifier of the caller that created this session.</param>
|
||||
/// <param name="clientSessionName">Client-supplied session name.</param>
|
||||
/// <param name="clientCorrelationId">Client-supplied correlation identifier.</param>
|
||||
/// <param name="commandTimeout">Timeout for command invocation.</param>
|
||||
@@ -79,6 +81,7 @@ public sealed class GatewaySession
|
||||
string pipeName,
|
||||
string nonce,
|
||||
string? clientIdentity,
|
||||
string? ownerKeyId,
|
||||
string? clientSessionName,
|
||||
string? clientCorrelationId,
|
||||
TimeSpan commandTimeout,
|
||||
@@ -112,6 +115,7 @@ public sealed class GatewaySession
|
||||
PipeName = pipeName;
|
||||
Nonce = nonce;
|
||||
ClientIdentity = clientIdentity;
|
||||
OwnerKeyId = ownerKeyId;
|
||||
ClientSessionName = clientSessionName;
|
||||
ClientCorrelationId = clientCorrelationId;
|
||||
CommandTimeout = commandTimeout;
|
||||
@@ -148,6 +152,11 @@ public sealed class GatewaySession
|
||||
/// </summary>
|
||||
public string? ClientIdentity { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the API key identifier of the caller that created this session.
|
||||
/// </summary>
|
||||
public string? OwnerKeyId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the client-supplied session name.
|
||||
/// </summary>
|
||||
|
||||
@@ -8,11 +8,13 @@ public interface ISessionManager
|
||||
/// <summary>Opens a new gateway session and launches a worker process.</summary>
|
||||
/// <param name="request">Request payload.</param>
|
||||
/// <param name="clientIdentity">Client identity string.</param>
|
||||
/// <param name="ownerKeyId">API key identifier of the caller creating the session.</param>
|
||||
/// <param name="cancellationToken">Token to cancel the asynchronous operation.</param>
|
||||
/// <returns>The newly opened session.</returns>
|
||||
Task<GatewaySession> OpenSessionAsync(
|
||||
SessionOpenRequest request,
|
||||
string? clientIdentity,
|
||||
string? ownerKeyId,
|
||||
CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>Attempts to retrieve a session by ID.</summary>
|
||||
|
||||
@@ -58,11 +58,13 @@ public sealed class SessionManager : ISessionManager
|
||||
/// </summary>
|
||||
/// <param name="request">Session open request.</param>
|
||||
/// <param name="clientIdentity">Client authentication identity.</param>
|
||||
/// <param name="ownerKeyId">API key identifier of the caller creating the session.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>Opened gateway session.</returns>
|
||||
public async Task<GatewaySession> OpenSessionAsync(
|
||||
SessionOpenRequest request,
|
||||
string? clientIdentity,
|
||||
string? ownerKeyId,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(request);
|
||||
@@ -72,7 +74,7 @@ public sealed class SessionManager : ISessionManager
|
||||
bool sessionOpenedRecorded = false;
|
||||
try
|
||||
{
|
||||
session = CreateSession(request, clientIdentity);
|
||||
session = CreateSession(request, clientIdentity, ownerKeyId);
|
||||
if (!_registry.TryAdd(session))
|
||||
{
|
||||
throw new SessionManagerException(
|
||||
@@ -420,7 +422,8 @@ public sealed class SessionManager : ISessionManager
|
||||
|
||||
private GatewaySession CreateSession(
|
||||
SessionOpenRequest request,
|
||||
string? clientIdentity)
|
||||
string? clientIdentity,
|
||||
string? ownerKeyId)
|
||||
{
|
||||
string sessionId = CreateSessionId();
|
||||
string backendName = string.IsNullOrWhiteSpace(request.RequestedBackend)
|
||||
@@ -441,6 +444,7 @@ public sealed class SessionManager : ISessionManager
|
||||
pipeName,
|
||||
nonce,
|
||||
clientIdentity,
|
||||
ownerKeyId,
|
||||
request.ClientSessionName,
|
||||
clientCorrelationId,
|
||||
commandTimeout,
|
||||
|
||||
Reference in New Issue
Block a user