about summary refs log tree commit diff
path: root/LibMatrix/Homeservers
diff options
context:
space:
mode:
authorRory& <root@rory.gay>2024-04-19 15:54:30 +0200
committerRory& <root@rory.gay>2024-04-19 15:54:30 +0200
commit440807e02393410327cd86d5ffa007dee98f8954 (patch)
treee750b0bab55a9ee7b507cd48eaa4ccb2ddd25fc0 /LibMatrix/Homeservers
parentFix homeserver resolution, rewrite homeserver initialisation, HSE work (diff)
downloadLibMatrix-440807e02393410327cd86d5ffa007dee98f8954.tar.xz
Partial User-Interactive Authentication, allow skipping homeserver typing
Diffstat (limited to '')
-rw-r--r--LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs18
-rw-r--r--LibMatrix/Homeservers/RemoteHomeServer.cs4
-rw-r--r--LibMatrix/Homeservers/UserInteractiveAuthClient.cs85
3 files changed, 103 insertions, 4 deletions
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<GenericRoom> 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<string, object> _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<UIAStage1Client> GetAvailableFlowsAsync(bool enableRegister = false, bool enableGuest = false) {
+        // var resp = await Homeserver.ClientHttpClient.GetAsync("/_matrix/client/v3/login");
+        // var data = await resp.Content.ReadFromJsonAsync<LoginFlowsResponse>();
+        // 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<RegisterFlowsResponse>();
+        //     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<RegisterFlowsResponse?> GetRegisterFlowsAsync() {
+        return null;
+    }
+
+    internal class RegisterFlowsResponse {
+        [JsonPropertyName("session")]
+        public string Session { get; set; } = null!;
+
+        [JsonPropertyName("flows")]
+        public List<RegisterFlow> Flows { get; set; } = null!;
+
+        [JsonPropertyName("params")]
+        public JsonObject Params { get; set; } = null!;
+
+        public class RegisterFlow {
+            [JsonPropertyName("stages")]
+            public List<string> Stages { get; set; } = null!;
+        }
+    }
+
+    internal class LoginFlowsResponse {
+        [JsonPropertyName("flows")]
+        public List<LoginFlow> 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