about summary refs log tree commit diff
path: root/LibMatrix/Homeservers
diff options
context:
space:
mode:
Diffstat (limited to 'LibMatrix/Homeservers')
-rw-r--r--LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs36
-rw-r--r--LibMatrix/Homeservers/AuthenticatedHomeserverSynapse.cs2
-rw-r--r--LibMatrix/Homeservers/RemoteHomeServer.cs48
3 files changed, 60 insertions, 26 deletions
diff --git a/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs b/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs
index e5e4274..c3684a1 100644
--- a/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs
+++ b/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs
@@ -13,19 +13,29 @@ using LibMatrix.Services;
 
 namespace LibMatrix.Homeservers;
 
-public class AuthenticatedHomeserverGeneric(string baseUrl, string accessToken) : RemoteHomeServer(baseUrl) {
+public class AuthenticatedHomeserverGeneric(string baseUrl, string accessToken) : RemoteHomeserver(baseUrl) {
     public static async Task<T> Create<T>(string baseUrl, string accessToken) where T : AuthenticatedHomeserverGeneric {
         var instance = Activator.CreateInstance(typeof(T), baseUrl, accessToken) as T
                        ?? throw new InvalidOperationException($"Failed to create instance of {typeof(T).Name}");
-        instance._httpClient = new() {
-            BaseAddress = new Uri(await new HomeserverResolverService().ResolveHomeserverFromWellKnown(baseUrl)
+        var urls = await new HomeserverResolverService().ResolveHomeserverFromWellKnown(baseUrl);
+        
+        instance.ClientHttpClient = new() {
+            BaseAddress = new Uri(urls.client
                                   ?? throw new InvalidOperationException("Failed to resolve homeserver")),
             Timeout = TimeSpan.FromMinutes(15),
             DefaultRequestHeaders = {
                 Authorization = new AuthenticationHeaderValue("Bearer", accessToken)
             }
         };
-        instance.WhoAmI = await instance._httpClient.GetFromJsonAsync<WhoAmIResponse>("/_matrix/client/v3/account/whoami");
+        instance.ServerHttpClient = new() {
+            BaseAddress = new Uri(urls.server
+                                  ?? throw new InvalidOperationException("Failed to resolve homeserver")),
+            Timeout = TimeSpan.FromMinutes(15),
+            DefaultRequestHeaders = {
+                Authorization = new AuthenticationHeaderValue("Bearer", accessToken)
+            }
+        };
+        instance.WhoAmI = await instance.ClientHttpClient.GetFromJsonAsync<WhoAmIResponse>("/_matrix/client/v3/account/whoami");
         return instance;
     }
 
@@ -59,7 +69,7 @@ public class AuthenticatedHomeserverGeneric(string baseUrl, string accessToken)
     }
 
     public virtual async Task<List<GenericRoom>> GetJoinedRooms() {
-        var roomQuery = await _httpClient.GetAsync("/_matrix/client/v3/joined_rooms");
+        var roomQuery = await ClientHttpClient.GetAsync("/_matrix/client/v3/joined_rooms");
 
         var roomsJson = await roomQuery.Content.ReadFromJsonAsync<JsonElement>();
         var rooms = roomsJson.GetProperty("joined_rooms").EnumerateArray().Select(room => GetRoom(room.GetString()!)).ToList();
@@ -70,7 +80,7 @@ public class AuthenticatedHomeserverGeneric(string baseUrl, string accessToken)
     }
 
     public virtual async Task<string> UploadFile(string fileName, Stream fileStream, string contentType = "application/octet-stream") {
-        var res = await _httpClient.PostAsync($"/_matrix/media/v3/upload?filename={fileName}", new StreamContent(fileStream));
+        var res = await ClientHttpClient.PostAsync($"/_matrix/media/v3/upload?filename={fileName}", new StreamContent(fileStream));
         if (!res.IsSuccessStatusCode) {
             Console.WriteLine($"Failed to upload file: {await res.Content.ReadAsStringAsync()}");
             throw new InvalidDataException($"Failed to upload file: {await res.Content.ReadAsStringAsync()}");
@@ -99,7 +109,7 @@ public class AuthenticatedHomeserverGeneric(string baseUrl, string accessToken)
         }
 
         creationEvent.CreationContent["creator"] = WhoAmI.UserId;
-        var res = await _httpClient.PostAsJsonAsync("/_matrix/client/v3/createRoom", creationEvent, new JsonSerializerOptions {
+        var res = await ClientHttpClient.PostAsJsonAsync("/_matrix/client/v3/createRoom", creationEvent, new JsonSerializerOptions {
             DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
         });
         if (!res.IsSuccessStatusCode) {
@@ -116,7 +126,7 @@ public class AuthenticatedHomeserverGeneric(string baseUrl, string accessToken)
     }
 
     public virtual async Task Logout() {
-        var res = await _httpClient.PostAsync("/_matrix/client/v3/logout", null);
+        var res = await ClientHttpClient.PostAsync("/_matrix/client/v3/logout", null);
         if (!res.IsSuccessStatusCode) {
             Console.WriteLine($"Failed to logout: {await res.Content.ReadAsStringAsync()}");
             throw new InvalidDataException($"Failed to logout: {await res.Content.ReadAsStringAsync()}");
@@ -153,11 +163,11 @@ public class AuthenticatedHomeserverGeneric(string baseUrl, string accessToken)
         // }
         //
         // return await res.Content.ReadFromJsonAsync<T>();
-        return await _httpClient.GetFromJsonAsync<T>($"/_matrix/client/v3/user/{WhoAmI.UserId}/account_data/{key}");
+        return await ClientHttpClient.GetFromJsonAsync<T>($"/_matrix/client/v3/user/{WhoAmI.UserId}/account_data/{key}");
     }
 
     public virtual async Task SetAccountDataAsync(string key, object data) {
-        var res = await _httpClient.PutAsJsonAsync($"/_matrix/client/v3/user/{WhoAmI.UserId}/account_data/{key}", data);
+        var res = await ClientHttpClient.PutAsJsonAsync($"/_matrix/client/v3/user/{WhoAmI.UserId}/account_data/{key}", data);
         if (!res.IsSuccessStatusCode) {
             Console.WriteLine($"Failed to set account data: {await res.Content.ReadAsStringAsync()}");
             throw new InvalidDataException($"Failed to set account data: {await res.Content.ReadAsStringAsync()}");
@@ -169,7 +179,7 @@ public class AuthenticatedHomeserverGeneric(string baseUrl, string accessToken)
     public string? ResolveMediaUri(string? mxcUri) {
         if (mxcUri is null) return null;
         if (mxcUri.StartsWith("https://")) return mxcUri;
-        return $"{_httpClient.BaseAddress}/_matrix/media/v3/download/{mxcUri.Replace("mxc://", "")}".Replace("//_matrix", "/_matrix");
+        return $"{ClientHttpClient.BaseAddress}/_matrix/media/v3/download/{mxcUri.Replace("mxc://", "")}".Replace("//_matrix", "/_matrix");
     }
 
     public async Task UpdateProfileAsync(UserProfileResponse? newProfile, bool preserveCustomRoomProfile = true) {
@@ -217,14 +227,14 @@ public class AuthenticatedHomeserverGeneric(string baseUrl, string accessToken)
         }
 
         if (oldProfile.DisplayName != newProfile.DisplayName) {
-            await _httpClient.PutAsJsonAsync($"/_matrix/client/v3/profile/{WhoAmI.UserId}/displayname", new { displayname = newProfile.DisplayName });
+            await ClientHttpClient.PutAsJsonAsync($"/_matrix/client/v3/profile/{WhoAmI.UserId}/displayname", new { displayname = newProfile.DisplayName });
         }
         else {
             Console.WriteLine($"Not updating display name because {oldProfile.DisplayName} == {newProfile.DisplayName}");
         }
 
         if (oldProfile.AvatarUrl != newProfile.AvatarUrl) {
-            await _httpClient.PutAsJsonAsync($"/_matrix/client/v3/profile/{WhoAmI.UserId}/avatar_url", new { avatar_url = newProfile.AvatarUrl });
+            await ClientHttpClient.PutAsJsonAsync($"/_matrix/client/v3/profile/{WhoAmI.UserId}/avatar_url", new { avatar_url = newProfile.AvatarUrl });
         }
         else {
             Console.WriteLine($"Not updating avatar URL because {newProfile.AvatarUrl} == {newProfile.AvatarUrl}");
diff --git a/LibMatrix/Homeservers/AuthenticatedHomeserverSynapse.cs b/LibMatrix/Homeservers/AuthenticatedHomeserverSynapse.cs
index 6d60dd7..0910cbe 100644
--- a/LibMatrix/Homeservers/AuthenticatedHomeserverSynapse.cs
+++ b/LibMatrix/Homeservers/AuthenticatedHomeserverSynapse.cs
@@ -23,7 +23,7 @@ public class AuthenticatedHomeserverSynapse : AuthenticatedHomeserverGeneric {
 
                 Console.WriteLine($"--- ADMIN Querying Room List with URL: {url} - Already have {i} items... ---");
 
-                res = await _authenticatedHomeserver._httpClient.GetFromJsonAsync<AdminRoomListingResult>(url);
+                res = await _authenticatedHomeserver.ClientHttpClient.GetFromJsonAsync<AdminRoomListingResult>(url);
                 totalRooms ??= res?.TotalRooms;
                 Console.WriteLine(res.ToJson(false));
                 foreach (var room in res.Rooms) {
diff --git a/LibMatrix/Homeservers/RemoteHomeServer.cs b/LibMatrix/Homeservers/RemoteHomeServer.cs
index a8d0326..0757f6e 100644
--- a/LibMatrix/Homeservers/RemoteHomeServer.cs
+++ b/LibMatrix/Homeservers/RemoteHomeServer.cs
@@ -9,19 +9,25 @@ using LibMatrix.Services;
 
 namespace LibMatrix.Homeservers;
 
-public class RemoteHomeServer(string baseUrl) {
-    public static async Task<RemoteHomeServer> Create(string baseUrl) =>
-        new(baseUrl) {
-            _httpClient = new() {
-                BaseAddress = new Uri(await new HomeserverResolverService().ResolveHomeserverFromWellKnown(baseUrl)
-                                      ?? throw new InvalidOperationException("Failed to resolve homeserver")),
+public class RemoteHomeserver(string baseUrl) {
+    public static async Task<RemoteHomeserver> Create(string baseUrl) {
+        var urls = await new HomeserverResolverService().ResolveHomeserverFromWellKnown(baseUrl);
+        return new RemoteHomeserver(baseUrl) {
+            ClientHttpClient = new() {
+                BaseAddress = new Uri(urls.client ?? throw new InvalidOperationException("Failed to resolve homeserver")),
+                Timeout = TimeSpan.FromSeconds(120)
+            },
+            ServerHttpClient = new() {
+                BaseAddress = new Uri(urls.server ?? throw new InvalidOperationException("Failed to resolve homeserver")),
                 Timeout = TimeSpan.FromSeconds(120)
             }
         };
+    }
 
     private Dictionary<string, object> _profileCache { get; set; } = new();
     public string BaseUrl { get; } = baseUrl;
-    public MatrixHttpClient _httpClient { get; set; }
+    public MatrixHttpClient ClientHttpClient { get; set; }
+    public MatrixHttpClient ServerHttpClient { get; set; }
 
     public async Task<UserProfileResponse> GetProfileAsync(string mxid) {
         if (mxid is null) throw new ArgumentNullException(nameof(mxid));
@@ -32,7 +38,7 @@ public class RemoteHomeServer(string baseUrl) {
 
         _profileCache[mxid] = new SemaphoreSlim(1);
 
-        var resp = await _httpClient.GetAsync($"/_matrix/client/v3/profile/{mxid}");
+        var resp = await ClientHttpClient.GetAsync($"/_matrix/client/v3/profile/{mxid}");
         var data = await resp.Content.ReadFromJsonAsync<UserProfileResponse>();
         if (!resp.IsSuccessStatusCode) Console.WriteLine("Profile: " + data);
         _profileCache[mxid] = data;
@@ -41,14 +47,14 @@ public class RemoteHomeServer(string baseUrl) {
     }
 
     public async Task<ClientVersionsResponse> GetClientVersionsAsync() {
-        var resp = await _httpClient.GetAsync($"/_matrix/client/versions");
+        var resp = await ClientHttpClient.GetAsync($"/_matrix/client/versions");
         var data = await resp.Content.ReadFromJsonAsync<ClientVersionsResponse>();
         if (!resp.IsSuccessStatusCode) Console.WriteLine("ClientVersions: " + data);
         return data;
     }
 
     public async Task<AliasResult> ResolveRoomAliasAsync(string alias) {
-        var resp = await _httpClient.GetAsync($"/_matrix/client/v3/directory/room/{alias.Replace("#", "%23")}");
+        var resp = await ClientHttpClient.GetAsync($"/_matrix/client/v3/directory/room/{alias.Replace("#", "%23")}");
         var data = await resp.Content.ReadFromJsonAsync<AliasResult>();
         var text = await resp.Content.ReadAsStringAsync();
         if (!resp.IsSuccessStatusCode) Console.WriteLine("ResolveAlias: " + data.ToJson());
@@ -58,7 +64,7 @@ public class RemoteHomeServer(string baseUrl) {
 #region Authentication
 
     public async Task<LoginResponse> LoginAsync(string username, string password, string? deviceName = null) {
-        var resp = await _httpClient.PostAsJsonAsync("/_matrix/client/r0/login", new {
+        var resp = await ClientHttpClient.PostAsJsonAsync("/_matrix/client/r0/login", new {
             type = "m.login.password",
             identifier = new {
                 type = "m.id.user",
@@ -73,7 +79,7 @@ public class RemoteHomeServer(string baseUrl) {
     }
 
     public async Task<LoginResponse> RegisterAsync(string username, string password, string? deviceName = null) {
-        var resp = await _httpClient.PostAsJsonAsync("/_matrix/client/r0/register", new {
+        var resp = await ClientHttpClient.PostAsJsonAsync("/_matrix/client/r0/register", new {
             kind = "user",
             auth = new {
                 type = "m.login.dummy"
@@ -90,6 +96,24 @@ public class RemoteHomeServer(string baseUrl) {
     }
 
 #endregion
+
+    public async Task<ServerVersionResponse> GetServerVersionAsync() {
+        return await ServerHttpClient.GetFromJsonAsync<ServerVersionResponse>("/_matrix/federation/v1/version");
+    }
+}
+
+public class ServerVersionResponse {
+
+    [JsonPropertyName("server")]
+    public ServerInfo Server { get; set; }
+    
+    public class ServerInfo {
+        [JsonPropertyName("name")]
+        public string Name { get; set; }
+        
+        [JsonPropertyName("version")]
+        public string Version { get; set; }
+    }
 }
 
 public class AliasResult {