diff --git a/F4SD-Cockpit-ServerCore/DataHistoryCollectorM42Wpm.cs b/F4SD-Cockpit-ServerCore/DataHistoryCollectorM42Wpm.cs index 9c7244a..44c7a32 100644 --- a/F4SD-Cockpit-ServerCore/DataHistoryCollectorM42Wpm.cs +++ b/F4SD-Cockpit-ServerCore/DataHistoryCollectorM42Wpm.cs @@ -99,6 +99,7 @@ namespace C4IT.DataHistoryProvider private Dictionary UserWebClientCache = new Dictionary(); private readonly object _ticketOverviewCacheLock = new object(); + private readonly Dictionary _ticketOverviewUserIds = new Dictionary(); [Obsolete] private readonly Dictionary _ticketOverviewPersonalCache = new Dictionary(StringComparer.OrdinalIgnoreCase); @@ -1212,8 +1213,60 @@ namespace C4IT.DataHistoryProvider urlBuilder.Append("&queues=").Append(encodedQueues); } + private void CacheTicketOverviewUserId(Guid cockpitUserId, Guid matrix42UserId) + { + if (cockpitUserId == Guid.Empty || matrix42UserId == Guid.Empty) + return; + + lock (_ticketOverviewCacheLock) + _ticketOverviewUserIds[cockpitUserId] = matrix42UserId; + } + + private async Task ResolveTicketOverviewUserIdAsync( + cF4sdWebRequestInfo requestInfo, + int logDeep, + CancellationToken token) + { + var cockpitUserId = requestInfo?.userInfo?.Id ?? Guid.Empty; + if (cockpitUserId == Guid.Empty) + return Guid.Empty; + + lock (_ticketOverviewCacheLock) + { + if (_ticketOverviewUserIds.TryGetValue(cockpitUserId, out var cachedUserId)) + return cachedUserId; + } + + var sid = requestInfo?.userInfo?.AdSid; + if (!string.IsNullOrWhiteSpace(sid)) + { + var userInfo = await GetM42UserInfoAsync(sid, token); + var matrix42UserId = userInfo?.User?.Id ?? Guid.Empty; + if (matrix42UserId != Guid.Empty) + { + CacheTicketOverviewUserId(cockpitUserId, matrix42UserId); + return matrix42UserId; + } + } + + var userWebClient = await GetUserWebClient(requestInfo, logDeep + 1, token); + if (userWebClient != null) + { + var userInfo = await userWebClient.GetUserInfoAsync(token); + var matrix42UserId = userInfo?.User?.Id ?? Guid.Empty; + if (matrix42UserId != Guid.Empty) + { + CacheTicketOverviewUserId(cockpitUserId, matrix42UserId); + return matrix42UserId; + } + } + + LogEntry($"Could not resolve a Matrix42 user ID for authenticated F4SD user {cockpitUserId}. Ticket overview request was skipped.", LogLevels.Warning); + return Guid.Empty; + } + private async Task> FetchTicketOverviewCountsAsync( - string sid, + Guid userId, string scope, IReadOnlyCollection requestedKeys, cF4sdWebRequestInfo requestInfo, @@ -1224,27 +1277,12 @@ namespace C4IT.DataHistoryProvider var wc = await GetWebClient(requestInfo, token); var request = new cTicketOverviewFilterRequest { - Sid = sid, + UserId = userId, Scope = scope, Keys = requestedKeys?.ToList() ?? new List(), Filters = GetTicketFilters() }; var res = await PostJsonAsync(wc, constUrlGetTicketOverviewCountsV2, request, token); - if (res?.StatusCode == HttpStatusCode.NotFound) - { - if (!TryGetLegacyQueueFilter(out var queueOption, out var encodedQueues)) - { - LogEntry("The ticket filter policy requires the v2 overview API; legacy fallback was rejected (fail closed).", LogLevels.Warning); - return new Dictionary(StringComparer.OrdinalIgnoreCase); - } - var urlBuilder = new StringBuilder(constUrlGetTicketOverviewCounts); - urlBuilder.Append("?sid=").Append(HttpUtility.UrlEncode(sid)); - urlBuilder.Append("&scope=").Append(HttpUtility.UrlEncode(scope ?? string.Empty)); - if (requestedKeys != null && requestedKeys.Count > 0) - urlBuilder.Append("&keys=").Append(HttpUtility.UrlEncode(string.Join(",", requestedKeys))); - AppendQueueFilterQuery(urlBuilder, queueOption, encodedQueues); - res = await wc.HttpEnh.GetAsync(urlBuilder.ToString(), token); - } if (token.IsCancellationRequested) return new Dictionary(StringComparer.OrdinalIgnoreCase); @@ -1308,8 +1346,8 @@ namespace C4IT.DataHistoryProvider if (!await CheckOnline()) return new Dictionary(StringComparer.OrdinalIgnoreCase); - var sid = requestInfo?.userInfo?.AdSid; - if (string.IsNullOrWhiteSpace(sid)) + var userId = await ResolveTicketOverviewUserIdAsync(requestInfo, LogDeep, Token); + if (userId == Guid.Empty) return new Dictionary(StringComparer.OrdinalIgnoreCase); var normalizedKeys = (keys ?? Enumerable.Empty()) @@ -1317,7 +1355,7 @@ namespace C4IT.DataHistoryProvider .Distinct(StringComparer.OrdinalIgnoreCase) .ToList(); var scope = useRoleScope ? "role" : "personal"; - return await FetchTicketOverviewCountsAsync(sid, scope, normalizedKeys, requestInfo, Token); + return await FetchTicketOverviewCountsAsync(userId, scope, normalizedKeys, requestInfo, Token); } catch (Exception E) { @@ -1346,36 +1384,21 @@ namespace C4IT.DataHistoryProvider if (string.IsNullOrWhiteSpace(key)) return new List(); - var sid = requestInfo?.userInfo?.AdSid; - if (string.IsNullOrWhiteSpace(sid)) + var userId = await ResolveTicketOverviewUserIdAsync(requestInfo, LogDeep, Token); + if (userId == Guid.Empty) return new List(); var scope = useRoleScope ? "role" : "personal"; var wc = await GetWebClient(requestInfo, Token); var request = new cTicketOverviewFilterRequest { - Sid = sid, + UserId = userId, Scope = scope, Key = key, Count = Math.Max(0, count), Filters = GetTicketFilters() }; var res = await PostJsonAsync(wc, constUrlGetTicketOverviewRelationsV2, request, Token); - if (res?.StatusCode == HttpStatusCode.NotFound) - { - if (!TryGetLegacyQueueFilter(out var queueOption, out var encodedQueues)) - { - LogEntry("The ticket filter policy requires the v2 relation API; legacy fallback was rejected (fail closed).", LogLevels.Warning); - return new List(); - } - var urlBuilder = new StringBuilder(constUrlGetTicketOverviewRelations); - urlBuilder.Append("?sid=").Append(HttpUtility.UrlEncode(sid)); - urlBuilder.Append("&scope=").Append(HttpUtility.UrlEncode(scope)); - urlBuilder.Append("&key=").Append(HttpUtility.UrlEncode(key)); - urlBuilder.Append("&count=").Append(Math.Max(0, count)); - AppendQueueFilterQuery(urlBuilder, queueOption, encodedQueues); - res = await wc.HttpEnh.GetAsync(urlBuilder.ToString(), Token); - } if (Token.IsCancellationRequested) return new List(); @@ -2357,6 +2380,8 @@ namespace C4IT.DataHistoryProvider if (Token.IsCancellationRequested) return; + CacheTicketOverviewUserId(userInfo.Id, _M42UserInfo?.User?.Id ?? Guid.Empty); + // if yes, set M42 for an addidional automatic logon possibility if (_M42UserInfo?.User != null) { @@ -2431,6 +2456,8 @@ namespace C4IT.DataHistoryProvider // get the role memberships relatet to the M42 roles if (m42UserInfo?.User?.Id != null) { + CacheTicketOverviewUserId(userInfo.Id, (Guid)m42UserInfo.User.Id); + var _F4SDRoles = await GetF4SDRoles((Guid)m42UserInfo.User.Id, Token); if (_F4SDRoles?.Count > 0)