From 2e8aa30daa4a33fa33622bccb344dfc24483e320 Mon Sep 17 00:00:00 2001 From: TheArcaneBrony Date: Thu, 9 Nov 2023 07:36:02 +0100 Subject: Fix sync --- .../AuthenticatedHomeserverProviderService.cs | 4 +- MxApiExtensions/Services/AuthenticationService.cs | 31 ++++++++++++--- MxApiExtensions/Services/UserContextService.cs | 44 ++++++++++++++++++++++ 3 files changed, 73 insertions(+), 6 deletions(-) create mode 100644 MxApiExtensions/Services/UserContextService.cs (limited to 'MxApiExtensions/Services') diff --git a/MxApiExtensions/Services/AuthenticatedHomeserverProviderService.cs b/MxApiExtensions/Services/AuthenticatedHomeserverProviderService.cs index e0f9db5..741beb3 100644 --- a/MxApiExtensions/Services/AuthenticatedHomeserverProviderService.cs +++ b/MxApiExtensions/Services/AuthenticatedHomeserverProviderService.cs @@ -6,6 +6,7 @@ using MxApiExtensions.Classes.LibMatrix; namespace MxApiExtensions.Services; public class AuthenticatedHomeserverProviderService(AuthenticationService authenticationService, HomeserverProviderService homeserverProviderService, IHttpContextAccessor request) { + public HttpContext? _context = request.HttpContext; public async Task TryGetRemoteHomeserver() { try { return await GetRemoteHomeserver(); @@ -21,7 +22,8 @@ public class AuthenticatedHomeserverProviderService(AuthenticationService authen } catch (MxApiMatrixException e) { if (e is not { ErrorCode: "M_MISSING_TOKEN" }) throw; - if (!request.HttpContext!.Request.Headers.Keys.Any(x=>x.ToUpper() == "MXAE_UPSTREAM")) + if (request is null) throw new MxApiMatrixException() { ErrorCode = "M_UNKNOWN", Error = "[MxApiExtensions] Request was null for unauthenticated request!" }; + if (!_context.Request.Headers.Keys.Any(x=>x.ToUpper() == "MXAE_UPSTREAM")) throw new MxApiMatrixException() { ErrorCode = "MXAE_MISSING_UPSTREAM", Error = "[MxApiExtensions] Missing MXAE_UPSTREAM header for unauthenticated request, this should be a server_name!" diff --git a/MxApiExtensions/Services/AuthenticationService.cs b/MxApiExtensions/Services/AuthenticationService.cs index 0dcc8b1..7430fcd 100644 --- a/MxApiExtensions/Services/AuthenticationService.cs +++ b/MxApiExtensions/Services/AuthenticationService.cs @@ -1,3 +1,5 @@ +using ArcaneLibs.Extensions; +using LibMatrix; using LibMatrix.Services; using MxApiExtensions.Classes.LibMatrix; @@ -17,7 +19,7 @@ public class AuthenticationService(ILogger logger, MxApiE token = _request.Query["access_token"]; } - if (token == null && fail) { + if (string.IsNullOrWhiteSpace(token) && fail) { throw new MxApiMatrixException { ErrorCode = "M_MISSING_TOKEN", Error = "Missing access token" @@ -29,7 +31,7 @@ public class AuthenticationService(ILogger logger, MxApiE public async Task GetMxidFromToken(string? token = null, bool fail = true) { token ??= GetToken(fail); - if (token == null) { + if (string.IsNullOrWhiteSpace(token)) { if (fail) { throw new MxApiMatrixException { ErrorCode = "M_MISSING_TOKEN", @@ -44,15 +46,34 @@ public class AuthenticationService(ILogger logger, MxApiE _tokenMap = (await File.ReadAllLinesAsync("token_map")) .Select(l => l.Split('\t')) .ToDictionary(l => l[0], l => l[1]); + + //THIS IS BROKEN, DO NOT USE! + // foreach (var (mapToken, mapUser) in _tokenMap) { + // try { + // var hs = await homeserverProviderService.GetAuthenticatedWithToken(mapUser.Split(':', 2)[1], mapToken); + // } + // catch (MatrixException e) { + // if (e is { ErrorCode: "M_UNKNOWN_TOKEN" }) _tokenMap[mapToken] = ""; + // } + // catch { + // // ignored + // } + // } + // _tokenMap.RemoveAll((x, y) => string.IsNullOrWhiteSpace(y)); + // await File.WriteAllTextAsync("token_map", _tokenMap.Aggregate("", (x, y) => $"{y.Key}\t{y.Value}\n")); } + if (_tokenMap.TryGetValue(token, out var mxid)) return mxid; var lookupTasks = new Dictionary>(); foreach (var homeserver in config.AuthHomeservers) { - lookupTasks.Add(homeserver, GetMxidFromToken(token, homeserver)); - await lookupTasks[homeserver].WaitAsync(TimeSpan.FromMilliseconds(250)); - if(lookupTasks[homeserver].IsCompletedSuccessfully && !string.IsNullOrWhiteSpace(lookupTasks[homeserver].Result)) break; + try { + lookupTasks.Add(homeserver, GetMxidFromToken(token, homeserver)); + await lookupTasks[homeserver].WaitAsync(TimeSpan.FromMilliseconds(500)); + if (lookupTasks[homeserver].IsCompletedSuccessfully && !string.IsNullOrWhiteSpace(lookupTasks[homeserver].Result)) break; + } + catch {} } await Task.WhenAll(lookupTasks.Values); diff --git a/MxApiExtensions/Services/UserContextService.cs b/MxApiExtensions/Services/UserContextService.cs new file mode 100644 index 0000000..ef19ced --- /dev/null +++ b/MxApiExtensions/Services/UserContextService.cs @@ -0,0 +1,44 @@ +using System.Collections.Concurrent; +using System.Text.Json.Serialization; +using ArcaneLibs.Extensions; +using LibMatrix; +using LibMatrix.Homeservers; +using MxApiExtensions.Classes; + +namespace MxApiExtensions.Services; + +public class UserContextService(MxApiExtensionsConfiguration config, AuthenticatedHomeserverProviderService hsProvider) { + internal static ConcurrentDictionary UserContextStore { get; set; } = new(); + public int SessionCount = UserContextStore.Count; + + public class UserContext { + public SyncState? SyncState { get; set; } + [JsonIgnore] + public AuthenticatedHomeserverGeneric Homeserver { get; set; } + public MxApiExtensionsUserConfiguration UserConfiguration { get; set; } + } + + private readonly SemaphoreSlim _getUserContextSemaphore = new SemaphoreSlim(1, 1); + public async Task GetCurrentUserContext() { + var hs = await hsProvider.GetHomeserver(); + // await _getUserContextSemaphore.WaitAsync(); + var ucs = await UserContextStore.GetOrCreateAsync($"{hs.WhoAmI.UserId}/{hs.WhoAmI.DeviceId}/{hs.ServerName}:{hs.AccessToken}", async x => { + var userContext = new UserContext() { + Homeserver = hs + }; + try { + userContext.UserConfiguration = await hs.GetAccountDataAsync(MxApiExtensionsUserConfiguration.EventId); + } + catch (MatrixException e) { + if (e is not { ErrorCode: "M_NOT_FOUND" }) throw; + userContext.UserConfiguration = config.DefaultUserConfiguration; + } + + await hs.SetAccountDataAsync(MxApiExtensionsUserConfiguration.EventId, userContext.UserConfiguration); + + return userContext; + }, _getUserContextSemaphore); + // _getUserContextSemaphore.Release(); + return ucs; + } +} \ No newline at end of file -- cgit 1.5.1