From 440807e02393410327cd86d5ffa007dee98f8954 Mon Sep 17 00:00:00 2001 From: Rory& Date: Fri, 19 Apr 2024 15:54:30 +0200 Subject: Partial User-Interactive Authentication, allow skipping homeserver typing --- .../Homeservers/AuthenticatedHomeserverGeneric.cs | 18 ++++- LibMatrix/Homeservers/RemoteHomeServer.cs | 4 + LibMatrix/Homeservers/UserInteractiveAuthClient.cs | 85 ++++++++++++++++++++++ 3 files changed, 103 insertions(+), 4 deletions(-) create mode 100644 LibMatrix/Homeservers/UserInteractiveAuthClient.cs (limited to 'LibMatrix/Homeservers') diff --git a/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs b/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs index afa6a6c..267b54d 100644 --- a/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs +++ b/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs @@ -128,10 +128,20 @@ public class AuthenticatedHomeserverGeneric : RemoteHomeserver { public virtual async IAsyncEnumerable GetJoinedRoomsByType(string type) { var rooms = await GetJoinedRooms(); var tasks = rooms.Select(async room => { - var roomType = await room.GetRoomType(); - if (roomType == type) return room; - - return null; + while (true) { + try { + var roomType = await room.GetRoomType(); + if (roomType == type) return room; + return null; + } + catch (MatrixException e) { + throw; + } + catch (Exception e) { + Console.WriteLine($"Failed to get room type for {room.RoomId}: {e.Message}"); + await Task.Delay(1000); + } + } }).ToAsyncEnumerable(); await foreach (var result in tasks) diff --git a/LibMatrix/Homeservers/RemoteHomeServer.cs b/LibMatrix/Homeservers/RemoteHomeServer.cs index e6d58b1..c29137c 100644 --- a/LibMatrix/Homeservers/RemoteHomeServer.cs +++ b/LibMatrix/Homeservers/RemoteHomeServer.cs @@ -1,5 +1,6 @@ using System.Net.Http.Json; using System.Text.Json; +using System.Text.Json.Nodes; using System.Text.Json.Serialization; using System.Web; using ArcaneLibs.Extensions; @@ -24,6 +25,7 @@ public class RemoteHomeserver { if (proxy is not null) ClientHttpClient.DefaultRequestHeaders.Add("MXAE_UPSTREAM", baseUrl); if (!string.IsNullOrWhiteSpace(wellKnownUris.Server)) FederationClient = new FederationClient(WellKnownUris.Server!, proxy); + Auth = new(this); } private Dictionary _profileCache { get; set; } = new(); @@ -106,6 +108,8 @@ public class RemoteHomeserver { if (mxcUri.StartsWith("https://")) return mxcUri; return $"{ClientHttpClient.BaseAddress}/_matrix/media/v3/download/{mxcUri.Replace("mxc://", "")}".Replace("//_matrix", "/_matrix"); } + + public UserInteractiveAuthClient Auth; } public class AliasResult { diff --git a/LibMatrix/Homeservers/UserInteractiveAuthClient.cs b/LibMatrix/Homeservers/UserInteractiveAuthClient.cs new file mode 100644 index 0000000..8be2cb9 --- /dev/null +++ b/LibMatrix/Homeservers/UserInteractiveAuthClient.cs @@ -0,0 +1,85 @@ +using System.Net.Http.Json; +using System.Text.Json.Nodes; +using System.Text.Json.Serialization; +using ArcaneLibs.Extensions; +using LibMatrix.Responses; + +namespace LibMatrix.Homeservers; + +public class UserInteractiveAuthClient { + public UserInteractiveAuthClient(RemoteHomeserver hs) { + Homeserver = hs; + } + + [JsonIgnore] + public RemoteHomeserver Homeserver { get; } + private LoginResponse? _guestLogin; + + public async Task GetAvailableFlowsAsync(bool enableRegister = false, bool enableGuest = false) { + // var resp = await Homeserver.ClientHttpClient.GetAsync("/_matrix/client/v3/login"); + // var data = await resp.Content.ReadFromJsonAsync(); + // if (!resp.IsSuccessStatusCode) Console.WriteLine("LoginFlows: " + await resp.Content.ReadAsStringAsync()); + // var loginFlows = data; + // + // try { + // var req = new HttpRequestMessage(HttpMethod.Post, "/_matrix/client/v3/register") { + // Content = new StringContent("{}") + // }; + // var resp2 = await Homeserver.ClientHttpClient.SendUnhandledAsync(req, CancellationToken.None); + // var data2 = await resp2.Content.ReadFromJsonAsync(); + // if (!resp.IsSuccessStatusCode) Console.WriteLine("RegisterFlows: " + data2.ToJson()); + // // return data; + // } + // catch (MatrixException e) { + // if (e is { ErrorCode: "M_FORBIDDEN" }) return null; + // throw; + // } + // catch (Exception e) { + // Console.WriteLine(e); + // throw; + // } + // + // + return new UIAStage1Client() { + + }; + } + + private async Task GetRegisterFlowsAsync() { + return null; + } + + internal class RegisterFlowsResponse { + [JsonPropertyName("session")] + public string Session { get; set; } = null!; + + [JsonPropertyName("flows")] + public List Flows { get; set; } = null!; + + [JsonPropertyName("params")] + public JsonObject Params { get; set; } = null!; + + public class RegisterFlow { + [JsonPropertyName("stages")] + public List Stages { get; set; } = null!; + } + } + + internal class LoginFlowsResponse { + [JsonPropertyName("flows")] + public List Flows { get; set; } = null!; + + public class LoginFlow { + [JsonPropertyName("type")] + public string Type { get; set; } = null!; + } + } + + public interface IUIAStage { + public IUIAStage? PreviousStage { get; } + } + public class UIAStage1Client : IUIAStage { + public IUIAStage? PreviousStage { get; } + // public LoginFlowsResponse LoginFlows { get; set; } + } +} \ No newline at end of file -- cgit 1.4.1