about summary refs log tree commit diff
path: root/LibMatrix/Homeservers/RemoteHomeServer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'LibMatrix/Homeservers/RemoteHomeServer.cs')
-rw-r--r--LibMatrix/Homeservers/RemoteHomeServer.cs89
1 files changed, 67 insertions, 22 deletions
diff --git a/LibMatrix/Homeservers/RemoteHomeServer.cs b/LibMatrix/Homeservers/RemoteHomeServer.cs

index adaac6d..45ecb18 100644 --- a/LibMatrix/Homeservers/RemoteHomeServer.cs +++ b/LibMatrix/Homeservers/RemoteHomeServer.cs
@@ -1,35 +1,34 @@ using System.Net.Http.Json; +using System.Text; using System.Text.Json; -using System.Text.Json.Nodes; using System.Text.Json.Serialization; using System.Web; using ArcaneLibs.Extensions; using LibMatrix.Extensions; using LibMatrix.Responses; using LibMatrix.Services; -using Microsoft.Extensions.Logging.Abstractions; namespace LibMatrix.Homeservers; public class RemoteHomeserver { - public RemoteHomeserver(string baseUrl, HomeserverResolverService.WellKnownUris wellKnownUris, string? proxy) { + public RemoteHomeserver(string serverName, HomeserverResolverService.WellKnownUris wellKnownUris, string? proxy) { if (string.IsNullOrWhiteSpace(proxy)) proxy = null; - BaseUrl = baseUrl; + ServerNameOrUrl = serverName; WellKnownUris = wellKnownUris; ClientHttpClient = new MatrixHttpClient { - BaseAddress = new Uri(proxy?.TrimEnd('/') ?? wellKnownUris.Client?.TrimEnd('/') ?? throw new InvalidOperationException($"No client URI for {baseUrl}!")), + BaseAddress = new Uri(proxy?.TrimEnd('/') ?? wellKnownUris.Client?.TrimEnd('/') ?? throw new InvalidOperationException($"No client URI for {serverName}!")), // Timeout = TimeSpan.FromSeconds(300) // TODO: Re-implement this }; - if (proxy is not null) ClientHttpClient.DefaultRequestHeaders.Add("MXAE_UPSTREAM", baseUrl); + if (proxy is not null) ClientHttpClient.DefaultRequestHeaders.Add("MXAE_UPSTREAM", serverName); if (!string.IsNullOrWhiteSpace(wellKnownUris.Server)) FederationClient = new FederationClient(WellKnownUris.Server!, proxy); Auth = new(this); } private Dictionary<string, object> _profileCache { get; set; } = new(); - public string BaseUrl { get; } + public string ServerNameOrUrl { get; } [JsonIgnore] public MatrixHttpClient ClientHttpClient { get; set; } @@ -51,7 +50,7 @@ public class RemoteHomeserver { var resp = await ClientHttpClient.GetAsync($"/_matrix/client/v3/profile/{HttpUtility.UrlEncode(mxid)}"); var data = await resp.Content.ReadFromJsonAsync<UserProfileResponse>(); if (!resp.IsSuccessStatusCode) Console.WriteLine("Profile: " + data); - _profileCache[mxid] = data; + _profileCache[mxid] = data ?? throw new InvalidOperationException($"Could not get profile for {mxid}"); return data; } @@ -62,7 +61,7 @@ public class RemoteHomeserver { var resp = await ClientHttpClient.GetAsync($"/_matrix/client/versions"); var data = await resp.Content.ReadFromJsonAsync<ClientVersionsResponse>(); if (!resp.IsSuccessStatusCode) Console.WriteLine("ClientVersions: " + data); - return data; + return data ?? throw new InvalidOperationException("ClientVersionsResponse is null"); } public async Task<AliasResult> ResolveRoomAliasAsync(string alias) { @@ -70,7 +69,16 @@ public class RemoteHomeserver { var data = await resp.Content.ReadFromJsonAsync<AliasResult>(); //var text = await resp.Content.ReadAsStringAsync(); if (!resp.IsSuccessStatusCode) Console.WriteLine("ResolveAlias: " + data.ToJson()); - return data; + return data ?? throw new InvalidOperationException($"Could not resolve alias {alias}"); + } + + public Task<PublicRoomDirectoryResult> GetPublicRoomsAsync(int limit = 100, string? server = null, string? since = null) => + ClientHttpClient.GetFromJsonAsync<PublicRoomDirectoryResult>(buildUriWithParams("/_matrix/client/v3/publicRooms", (nameof(limit), true, limit), + (nameof(server), !string.IsNullOrWhiteSpace(server), server), (nameof(since), !string.IsNullOrWhiteSpace(since), since))); + + // TODO: move this somewhere else + private string buildUriWithParams(string url, params (string name, bool include, object? value)[] values) { + return url + "?" + string.Join("&", values.Where(x => x.include)); } #region Authentication @@ -82,12 +90,11 @@ public class RemoteHomeserver { type = "m.id.user", user = username }, - password = password, + password, initial_device_display_name = deviceName }); var data = await resp.Content.ReadFromJsonAsync<LoginResponse>(); - if (!resp.IsSuccessStatusCode) Console.WriteLine("Login: " + data.ToJson()); - return data; + return data ?? throw new InvalidOperationException("LoginResponse is null"); } public async Task<LoginResponse> RegisterAsync(string username, string password, string? deviceName = null) { @@ -103,26 +110,64 @@ public class RemoteHomeserver { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }); var data = await resp.Content.ReadFromJsonAsync<LoginResponse>(); - if (!resp.IsSuccessStatusCode) Console.WriteLine("Register: " + data.ToJson()); - return data; + return data ?? throw new InvalidOperationException("LoginResponse is null"); } #endregion [Obsolete("This call uses the deprecated unauthenticated media endpoints, please switch to the relevant AuthenticatedHomeserver methods instead.", true)] - public string? ResolveMediaUri(string? mxcUri) { - if (mxcUri is null) return null; - if (mxcUri.StartsWith("https://")) return mxcUri; - return $"{ClientHttpClient.BaseAddress}/_matrix/media/v3/download/{mxcUri.Replace("mxc://", "")}".Replace("//_matrix", "/_matrix"); - } + public virtual string? ResolveMediaUri(string? mxcUri) => null; public UserInteractiveAuthClient Auth; } +public class PublicRoomDirectoryResult { + [JsonPropertyName("chunk")] + public List<PublicRoomListItem> Chunk { get; set; } + + [JsonPropertyName("next_batch")] + public string? NextBatch { get; set; } + + [JsonPropertyName("prev_batch")] + public string? PrevBatch { get; set; } + + [JsonPropertyName("total_room_count_estimate")] + public int TotalRoomCountEstimate { get; set; } + + public class PublicRoomListItem { + [JsonPropertyName("avatar_url")] + public string? AvatarUrl { get; set; } + + [JsonPropertyName("canonical_alias")] + public string? CanonicalAlias { get; set; } + + [JsonPropertyName("guest_can_join")] + public bool GuestCanJoin { get; set; } + + [JsonPropertyName("join_rule")] + public string JoinRule { get; set; } + + [JsonPropertyName("name")] + public string? Name { get; set; } + + [JsonPropertyName("num_joined_members")] + public int NumJoinedMembers { get; set; } + + [JsonPropertyName("room_id")] + public string RoomId { get; set; } + + [JsonPropertyName("topic")] + public string? Topic { get; set; } + + [JsonPropertyName("world_readable")] + public bool WorldReadable { get; set; } + } +} + public class AliasResult { [JsonPropertyName("room_id")] - public string RoomId { get; set; } = null!; + public string RoomId { get; set; } [JsonPropertyName("servers")] - public List<string> Servers { get; set; } = null!; + public List<string> Servers { get; set; } } \ No newline at end of file