From a331eb2f118e0051c6c6744a20d6b0934c4d6d6f Mon Sep 17 00:00:00 2001 From: TheArcaneBrony Date: Wed, 28 Jun 2023 10:38:45 +0200 Subject: Update stuff --- MatrixRoomUtils.Core/AuthenticatedHomeServer.cs | 10 --- MatrixRoomUtils.Core/Authentication/MatrixAuth.cs | 19 +----- MatrixRoomUtils.Core/Helpers/SyncHelper.cs | 28 ++++---- MatrixRoomUtils.Core/Interfaces/IHomeServer.cs | 44 ------------- MatrixRoomUtils.Core/MatrixRoomUtils.Core.csproj | 3 +- MatrixRoomUtils.Core/RemoteHomeServer.cs | 9 --- MatrixRoomUtils.Core/Responses/LoginResponse.cs | 13 ---- .../Services/HomeserverProviderService.cs | 22 ++++++- .../Services/HomeserverResolverService.cs | 76 ++++++++++++++++++++++ MatrixRoomUtils.Core/Services/ServiceInstaller.cs | 2 + 10 files changed, 117 insertions(+), 109 deletions(-) create mode 100644 MatrixRoomUtils.Core/Services/HomeserverResolverService.cs (limited to 'MatrixRoomUtils.Core') diff --git a/MatrixRoomUtils.Core/AuthenticatedHomeServer.cs b/MatrixRoomUtils.Core/AuthenticatedHomeServer.cs index b7e01dd..10bbb36 100644 --- a/MatrixRoomUtils.Core/AuthenticatedHomeServer.cs +++ b/MatrixRoomUtils.Core/AuthenticatedHomeServer.cs @@ -31,16 +31,6 @@ public class AuthenticatedHomeServer : IHomeServer { public string UserId { get; } public string AccessToken { get; set; } - public async Task Configure() { - FullHomeServerDomain = await ResolveHomeserverFromWellKnown(HomeServerDomain); - _httpClient.Dispose(); - _httpClient = new MatrixHttpClient { BaseAddress = new Uri(FullHomeServerDomain) }; - _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken); - Console.WriteLine("[AHS] Finished setting up http client"); - WhoAmI = (await _httpClient.GetFromJsonAsync("/_matrix/client/v3/account/whoami"))!; - - return this; - } public async Task GetRoom(string roomId) => new(this, roomId); diff --git a/MatrixRoomUtils.Core/Authentication/MatrixAuth.cs b/MatrixRoomUtils.Core/Authentication/MatrixAuth.cs index b1b0362..28e0c49 100644 --- a/MatrixRoomUtils.Core/Authentication/MatrixAuth.cs +++ b/MatrixRoomUtils.Core/Authentication/MatrixAuth.cs @@ -7,9 +7,10 @@ using MatrixRoomUtils.Core.StateEventTypes; namespace MatrixRoomUtils.Core.Authentication; public class MatrixAuth { + [Obsolete("This is possibly broken and should not be used.", true)] public static async Task Login(string homeserver, string username, string password) { Console.WriteLine($"Logging in to {homeserver} as {username}..."); - homeserver = (await new RemoteHomeServer(homeserver).Configure()).FullHomeServerDomain; + homeserver = (new RemoteHomeServer(homeserver)).FullHomeServerDomain; var hc = new MatrixHttpClient(); var payload = new { type = "m.login.password", @@ -31,20 +32,4 @@ public class MatrixAuth { //var token = data.GetProperty("access_token").GetString(); //return token; } - - [Obsolete("Migrate to IHomeServer instance")] - public static async Task GetProfile(string homeserver, string mxid) => await (await new RemoteHomeServer(homeserver).Configure()).GetProfile(mxid); - - private static async Task CheckSuccessStatus(string url) { - //cors causes failure, try to catch - try { - using var hc = new HttpClient(); - var resp = await hc.GetAsync(url); - return resp.IsSuccessStatusCode; - } - catch (Exception e) { - Console.WriteLine($"Failed to check success status: {e.Message}"); - return false; - } - } } \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Helpers/SyncHelper.cs b/MatrixRoomUtils.Core/Helpers/SyncHelper.cs index bb4ddd5..1b9c598 100644 --- a/MatrixRoomUtils.Core/Helpers/SyncHelper.cs +++ b/MatrixRoomUtils.Core/Helpers/SyncHelper.cs @@ -3,6 +3,7 @@ using System.Net.Http.Json; using System.Text.Json.Serialization; using MatrixRoomUtils.Core.Interfaces; using MatrixRoomUtils.Core.Responses; +using MatrixRoomUtils.Core.Responses.Admin; using MatrixRoomUtils.Core.Services; using MatrixRoomUtils.Core.StateEventTypes; @@ -45,21 +46,24 @@ public class SyncHelper { [SuppressMessage("ReSharper", "FunctionNeverReturns")] public async Task RunSyncLoop(CancellationToken? cancellationToken = null, bool skipInitialSyncEvents = true) { SyncResult? sync = null; + string? nextBatch = null; while (cancellationToken is null || !cancellationToken.Value.IsCancellationRequested) { - sync = await Sync(sync?.NextBatch, cancellationToken); - Console.WriteLine($"Got sync, next batch: {sync?.NextBatch}!"); - if (sync == null) continue; + sync = await Sync(nextBatch, cancellationToken); + nextBatch = sync?.NextBatch ?? nextBatch; + if(sync is null) continue; + Console.WriteLine($"Got sync, next batch: {nextBatch}!"); if (sync.Rooms is { Invite.Count: > 0 }) { foreach (var roomInvite in sync.Rooms.Invite) { - Console.WriteLine(roomInvite.Value.GetType().Name); - InviteReceived?.Invoke(this, roomInvite); + var tasks = InviteReceivedHandlers.Select(x => x(roomInvite)).ToList(); + await Task.WhenAll(tasks); } } if (sync.AccountData is { Events: { Count: > 0 } }) { foreach (var accountDataEvent in sync.AccountData.Events) { - AccountDataReceived?.Invoke(this, accountDataEvent); + var tasks = AccountDataReceivedHandlers.Select(x => x(accountDataEvent)).ToList(); + await Task.WhenAll(tasks); } } @@ -73,7 +77,8 @@ public class SyncHelper { foreach (var updatedRoom in sync.Rooms.Join) { foreach (var stateEventResponse in updatedRoom.Value.Timeline.Events) { stateEventResponse.RoomId = updatedRoom.Key; - TimelineEventReceived?.Invoke(this, stateEventResponse); + var tasks = TimelineEventHandlers.Select(x => x(stateEventResponse)).ToList(); + await Task.WhenAll(tasks); } } } @@ -83,11 +88,10 @@ public class SyncHelper { /// /// Event fired when a room invite is received /// - public event EventHandler>? - InviteReceived; - - public event EventHandler? TimelineEventReceived; - public event EventHandler? AccountDataReceived; + public List, Task>> + InviteReceivedHandlers { get; } = new(); + public List> TimelineEventHandlers { get; } = new(); + public List> AccountDataReceivedHandlers { get; } = new(); } public class SyncResult { diff --git a/MatrixRoomUtils.Core/Interfaces/IHomeServer.cs b/MatrixRoomUtils.Core/Interfaces/IHomeServer.cs index 029530c..4fa6c1b 100644 --- a/MatrixRoomUtils.Core/Interfaces/IHomeServer.cs +++ b/MatrixRoomUtils.Core/Interfaces/IHomeServer.cs @@ -12,50 +12,6 @@ public class IHomeServer { protected internal MatrixHttpClient _httpClient { get; set; } = new(); - public async Task ResolveHomeserverFromWellKnown(string homeserver) { - var res = await _resolveHomeserverFromWellKnown(homeserver); - if (!res.StartsWith("http")) res = "https://" + res; - if (res.EndsWith(":443")) res = res.Substring(0, res.Length - 4); - return res; - } - - private async Task _resolveHomeserverFromWellKnown(string homeserver) { - string result = null; - Console.WriteLine($"Resolving homeserver: {homeserver}"); - if (!homeserver.StartsWith("http")) homeserver = "https://" + homeserver; - if (await _httpClient.CheckSuccessStatus($"{homeserver}/.well-known/matrix/client")) { - Console.WriteLine("Got successful response for client well-known..."); - var resp = await _httpClient.GetFromJsonAsync($"{homeserver}/.well-known/matrix/client"); - Console.WriteLine($"Response: {resp.ToString()}"); - var hs = resp.GetProperty("m.homeserver").GetProperty("base_url").GetString(); - result = hs; - } - else { - Console.WriteLine("No client well-known..."); - if (await _httpClient.CheckSuccessStatus($"{homeserver}/.well-known/matrix/server")) { - var resp = await _httpClient.GetFromJsonAsync($"{homeserver}/.well-known/matrix/server"); - var hs = resp.GetProperty("m.server").GetString(); - result = hs; - } - else { - Console.WriteLine("No server well-known..."); - if (await _httpClient.CheckSuccessStatus($"{homeserver}/_matrix/client/versions")) - result = homeserver; - else { - Console.WriteLine("No homeserver on shortname..."); - if (await _httpClient.CheckSuccessStatus($"{homeserver.Replace("//", "//matrix.")}/_matrix/client/versions")) result = homeserver.Replace("//", "//matrix."); - else Console.WriteLine($"Failed to resolve homeserver, not on {homeserver}, nor do client or server well-knowns exist!"); - } - } - } - - if (result != null) { - Console.WriteLine($"Resolved homeserver: {homeserver} -> {result}"); - return result; - } - - throw new InvalidDataException($"Failed to resolve homeserver, not on {homeserver}, nor do client or server well-knowns exist!"); - } public async Task GetProfile(string mxid, bool debounce = false, bool cache = true) { if (cache) { diff --git a/MatrixRoomUtils.Core/MatrixRoomUtils.Core.csproj b/MatrixRoomUtils.Core/MatrixRoomUtils.Core.csproj index 60f11f0..3571eab 100644 --- a/MatrixRoomUtils.Core/MatrixRoomUtils.Core.csproj +++ b/MatrixRoomUtils.Core/MatrixRoomUtils.Core.csproj @@ -7,7 +7,8 @@ - + + diff --git a/MatrixRoomUtils.Core/RemoteHomeServer.cs b/MatrixRoomUtils.Core/RemoteHomeServer.cs index c593318..9c5f2a3 100644 --- a/MatrixRoomUtils.Core/RemoteHomeServer.cs +++ b/MatrixRoomUtils.Core/RemoteHomeServer.cs @@ -12,13 +12,4 @@ public class RemoteHomeServer : IHomeServer { _httpClient.Timeout = TimeSpan.FromSeconds(5); } - public async Task Configure() { - FullHomeServerDomain = await ResolveHomeserverFromWellKnown(HomeServerDomain); - _httpClient.Dispose(); - _httpClient = new MatrixHttpClient { BaseAddress = new Uri(FullHomeServerDomain) }; - _httpClient.Timeout = TimeSpan.FromSeconds(5); - Console.WriteLine("[RHS] Finished setting up http client"); - - return this; - } } \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Responses/LoginResponse.cs b/MatrixRoomUtils.Core/Responses/LoginResponse.cs index 8d0d94f..b248739 100644 --- a/MatrixRoomUtils.Core/Responses/LoginResponse.cs +++ b/MatrixRoomUtils.Core/Responses/LoginResponse.cs @@ -1,7 +1,4 @@ -using System.Net.Http.Json; -using System.Text.Json; using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.StateEventTypes; namespace MatrixRoomUtils.Core.Responses; @@ -17,14 +14,4 @@ public class LoginResponse { [JsonPropertyName("user_id")] public string UserId { get; set; } - - public async Task GetProfile() { - var hc = new HttpClient(); - var resp = await hc.GetAsync($"{HomeServer}/_matrix/client/v3/profile/{UserId}"); - var data = await resp.Content.ReadFromJsonAsync(); - if (!resp.IsSuccessStatusCode) Console.WriteLine("Profile: " + data); - return data.Deserialize(); - } - - public async Task GetCanonicalHomeserverUrl() => (await new RemoteHomeServer(HomeServer).Configure()).FullHomeServerDomain; } \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Services/HomeserverProviderService.cs b/MatrixRoomUtils.Core/Services/HomeserverProviderService.cs index 0f09a45..8a22d33 100644 --- a/MatrixRoomUtils.Core/Services/HomeserverProviderService.cs +++ b/MatrixRoomUtils.Core/Services/HomeserverProviderService.cs @@ -1,16 +1,32 @@ +using System.Net.Http.Headers; +using System.Net.Http.Json; +using MatrixRoomUtils.Core.Extensions; +using Microsoft.Extensions.Logging; namespace MatrixRoomUtils.Core.Services; public class HomeserverProviderService { private readonly TieredStorageService _tieredStorageService; + private readonly ILogger _logger; + private readonly HomeserverResolverService _homeserverResolverService; - public HomeserverProviderService(TieredStorageService tieredStorageService) { + public HomeserverProviderService(TieredStorageService tieredStorageService, ILogger logger, HomeserverResolverService homeserverResolverService) { Console.WriteLine("Homeserver provider service instantiated!"); _tieredStorageService = tieredStorageService; - Console.WriteLine( + _logger = logger; + _homeserverResolverService = homeserverResolverService; + logger.LogDebug( $"New HomeserverProviderService created with TieredStorageService<{string.Join(", ", tieredStorageService.GetType().GetProperties().Select(x => x.Name))}>!"); } public async Task GetAuthenticatedWithToken(string homeserver, string accessToken) { - return await new AuthenticatedHomeServer(_tieredStorageService, homeserver, accessToken).Configure(); + var hs = new AuthenticatedHomeServer(_tieredStorageService, homeserver, accessToken); + hs.FullHomeServerDomain = await _homeserverResolverService.ResolveHomeserverFromWellKnown(homeserver); + hs._httpClient.Dispose(); + hs._httpClient = new MatrixHttpClient { BaseAddress = new Uri(hs.FullHomeServerDomain) }; + hs._httpClient.Timeout = TimeSpan.FromSeconds(5); + hs._httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); + + hs.WhoAmI = (await hs._httpClient.GetFromJsonAsync("/_matrix/client/v3/account/whoami"))!; + return hs; } } \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Services/HomeserverResolverService.cs b/MatrixRoomUtils.Core/Services/HomeserverResolverService.cs new file mode 100644 index 0000000..f6363ab --- /dev/null +++ b/MatrixRoomUtils.Core/Services/HomeserverResolverService.cs @@ -0,0 +1,76 @@ +using System.Net.Http.Json; +using System.Text.Json; +using MatrixRoomUtils.Core.Extensions; +using Microsoft.Extensions.Logging; + +namespace MatrixRoomUtils.Core.Services; + +public class HomeserverResolverService { + private readonly HttpClient _httpClient; + private readonly ILogger _logger; + + public HomeserverResolverService(HttpClient httpClient, ILogger logger) { + _httpClient = httpClient; + _logger = logger; + } + + public async Task ResolveHomeserverFromWellKnown(string homeserver) { + var res = await _resolveHomeserverFromWellKnown(homeserver); + if (!res.StartsWith("http")) res = "https://" + res; + if (res.EndsWith(":443")) res = res.Substring(0, res.Length - 4); + return res; + } + + private async Task _resolveHomeserverFromWellKnown(string homeserver) { + string? result = null; + _logger.LogInformation($"Attempting to resolve homeserver: {homeserver}"); + if (!homeserver.StartsWith("http")) homeserver = "https://" + homeserver; + result ??= await _tryResolveFromClientWellknown(homeserver); + result ??= await _tryResolveFromServerWellknown(homeserver); + result ??= await _tryCheckIfDomainHasHomeserver(homeserver); + // if(!homeserver.Contains("http")) homeserver = "https://" + homeserver; + // result ??= await _tryCheckIfSubDomainHasHomeserver(homeserver, "matrix"); + // result ??= await _tryCheckIfSubDomainHasHomeserver(homeserver, "chat"); + + if(result is not null) { + _logger.LogInformation($"Resolved homeserver: {homeserver} -> {result}"); + return result; + } + + throw new InvalidDataException($"Failed to resolve homeserver for {homeserver}! Is it online and configured correctly?"); + } + + private async Task _tryResolveFromClientWellknown(string homeserver) { + if (!homeserver.StartsWith("http")) homeserver = "https://" + homeserver; + if (await _httpClient.CheckSuccessStatus($"{homeserver}/.well-known/matrix/client")) { + var resp = await _httpClient.GetFromJsonAsync($"{homeserver}/.well-known/matrix/client"); + var hs = resp.GetProperty("m.homeserver").GetProperty("base_url").GetString(); + return hs; + } + _logger.LogInformation("No client well-known..."); + return null; + } + private async Task _tryResolveFromServerWellknown(string homeserver) { + if (!homeserver.StartsWith("http")) homeserver = "https://" + homeserver; + if (await _httpClient.CheckSuccessStatus($"{homeserver}/.well-known/matrix/server")) { + var resp = await _httpClient.GetFromJsonAsync($"{homeserver}/.well-known/matrix/server"); + var hs = resp.GetProperty("m.server").GetString(); + return hs; + } + _logger.LogInformation("No server well-known..."); + return null; + } + + private async Task _tryCheckIfDomainHasHomeserver(string homeserver) { + _logger.LogInformation($"Checking if {homeserver} hosts a homeserver..."); + if (await _httpClient.CheckSuccessStatus($"{homeserver}/_matrix/client/versions")) + return homeserver; + _logger.LogInformation("No homeserver on shortname..."); + return null; + } + + private async Task _tryCheckIfSubDomainHasHomeserver(string homeserver, string subdomain) { + homeserver = homeserver.Replace("https://", $"https://{subdomain}."); + return await _tryCheckIfDomainHasHomeserver(homeserver); + } +} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Services/ServiceInstaller.cs b/MatrixRoomUtils.Core/Services/ServiceInstaller.cs index 1b275c5..4a831c1 100644 --- a/MatrixRoomUtils.Core/Services/ServiceInstaller.cs +++ b/MatrixRoomUtils.Core/Services/ServiceInstaller.cs @@ -16,6 +16,8 @@ public static class ServiceInstaller { } //Add services services.AddScoped(); + services.AddScoped(); + services.AddScoped(); return services; } -- cgit 1.5.1