diff options
Diffstat (limited to 'MatrixRoomUtils.Core')
-rw-r--r-- | MatrixRoomUtils.Core/AuthenticatedHomeServer.cs | 10 | ||||
-rw-r--r-- | MatrixRoomUtils.Core/Authentication/MatrixAuth.cs | 19 | ||||
-rw-r--r-- | MatrixRoomUtils.Core/Helpers/SyncHelper.cs | 28 | ||||
-rw-r--r-- | MatrixRoomUtils.Core/Interfaces/IHomeServer.cs | 44 | ||||
-rw-r--r-- | MatrixRoomUtils.Core/MatrixRoomUtils.Core.csproj | 3 | ||||
-rw-r--r-- | MatrixRoomUtils.Core/RemoteHomeServer.cs | 9 | ||||
-rw-r--r-- | MatrixRoomUtils.Core/Responses/LoginResponse.cs | 13 | ||||
-rw-r--r-- | MatrixRoomUtils.Core/Services/HomeserverProviderService.cs | 22 | ||||
-rw-r--r-- | MatrixRoomUtils.Core/Services/HomeserverResolverService.cs | 76 | ||||
-rw-r--r-- | MatrixRoomUtils.Core/Services/ServiceInstaller.cs | 2 |
10 files changed, 117 insertions, 109 deletions
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<AuthenticatedHomeServer> 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<WhoAmIResponse>("/_matrix/client/v3/account/whoami"))!; - - return this; - } public async Task<GenericRoom> 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<LoginResponse> 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<ProfileResponse> GetProfile(string homeserver, string mxid) => await (await new RemoteHomeServer(homeserver).Configure()).GetProfile(mxid); - - private static async Task<bool> 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 { /// <summary> /// Event fired when a room invite is received /// </summary> - public event EventHandler<KeyValuePair<string, SyncResult.RoomsDataStructure.InvitedRoomDataStructure>>? - InviteReceived; - - public event EventHandler<StateEventResponse>? TimelineEventReceived; - public event EventHandler<StateEventResponse>? AccountDataReceived; + public List<Func<KeyValuePair<string, SyncResult.RoomsDataStructure.InvitedRoomDataStructure>, Task>> + InviteReceivedHandlers { get; } = new(); + public List<Func<StateEventResponse, Task>> TimelineEventHandlers { get; } = new(); + public List<Func<StateEventResponse, Task>> 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<string> 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<string> _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<JsonElement>($"{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<JsonElement>($"{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<ProfileResponse> 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 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" /> + <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" /> + <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.1" /> </ItemGroup> </Project> 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<RemoteHomeServer> 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<ProfileResponse> GetProfile() { - var hc = new HttpClient(); - var resp = await hc.GetAsync($"{HomeServer}/_matrix/client/v3/profile/{UserId}"); - var data = await resp.Content.ReadFromJsonAsync<JsonElement>(); - if (!resp.IsSuccessStatusCode) Console.WriteLine("Profile: " + data); - return data.Deserialize<ProfileResponse>(); - } - - public async Task<string> 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<HomeserverProviderService> _logger; + private readonly HomeserverResolverService _homeserverResolverService; - public HomeserverProviderService(TieredStorageService tieredStorageService) { + public HomeserverProviderService(TieredStorageService tieredStorageService, ILogger<HomeserverProviderService> 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<AuthenticatedHomeServer> 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<WhoAmIResponse>("/_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<HomeserverResolverService> _logger; + + public HomeserverResolverService(HttpClient httpClient, ILogger<HomeserverResolverService> logger) { + _httpClient = httpClient; + _logger = logger; + } + + public async Task<string> 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<string> _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<string?> _tryResolveFromClientWellknown(string homeserver) { + if (!homeserver.StartsWith("http")) homeserver = "https://" + homeserver; + if (await _httpClient.CheckSuccessStatus($"{homeserver}/.well-known/matrix/client")) { + var resp = await _httpClient.GetFromJsonAsync<JsonElement>($"{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<string?> _tryResolveFromServerWellknown(string homeserver) { + if (!homeserver.StartsWith("http")) homeserver = "https://" + homeserver; + if (await _httpClient.CheckSuccessStatus($"{homeserver}/.well-known/matrix/server")) { + var resp = await _httpClient.GetFromJsonAsync<JsonElement>($"{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<string?> _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<string?> _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<HomeserverProviderService>(); + services.AddScoped<HomeserverResolverService>(); + services.AddScoped<HttpClient>(); return services; } |