diff options
author | TheArcaneBrony <myrainbowdash949@gmail.com> | 2023-05-03 18:40:53 +0200 |
---|---|---|
committer | TheArcaneBrony <myrainbowdash949@gmail.com> | 2023-05-03 18:40:53 +0200 |
commit | 3d3edeae16252a311704b390cfad6faa435a8b84 (patch) | |
tree | 34974194435fbe9789de5140ef9a9c0ddb834c74 /MatrixRoomUtils.Web | |
parent | Add policy room discovery ,add room state viewer (diff) | |
download | MatrixUtils-3d3edeae16252a311704b390cfad6faa435a8b84.tar.xz |
Refactor
Diffstat (limited to 'MatrixRoomUtils.Web')
-rw-r--r-- | MatrixRoomUtils.Web/Classes/LocalStorageWrapper.cs | 35 | ||||
-rw-r--r-- | MatrixRoomUtils.Web/Classes/RuntimeStorage.cs | 55 | ||||
-rw-r--r-- | MatrixRoomUtils.Web/Pages/DataExportPage.razor | 28 | ||||
-rw-r--r-- | MatrixRoomUtils.Web/Pages/Index.razor | 10 | ||||
-rw-r--r-- | MatrixRoomUtils.Web/Pages/LoginPage.razor | 12 | ||||
-rw-r--r-- | MatrixRoomUtils.Web/Pages/PolicyListEditorPage.razor | 8 | ||||
-rw-r--r-- | MatrixRoomUtils.Web/Pages/PolicyListRoomList.razor | 75 | ||||
-rw-r--r-- | MatrixRoomUtils.Web/Pages/RoomStateEditorPage.razor | 177 | ||||
-rw-r--r-- | MatrixRoomUtils.Web/Pages/RoomStateRoomList.razor | 73 | ||||
-rw-r--r-- | MatrixRoomUtils.Web/Pages/RoomStateViewerPage.razor | 8 | ||||
-rw-r--r-- | MatrixRoomUtils.Web/Pages/UserImportPage.razor | 14 | ||||
-rw-r--r-- | MatrixRoomUtils.Web/Shared/IndexComponents/IndexUserItem.razor | 13 | ||||
-rw-r--r-- | MatrixRoomUtils.Web/Shared/MainLayout.razor | 4 |
13 files changed, 370 insertions, 142 deletions
diff --git a/MatrixRoomUtils.Web/Classes/LocalStorageWrapper.cs b/MatrixRoomUtils.Web/Classes/LocalStorageWrapper.cs new file mode 100644 index 0000000..462364c --- /dev/null +++ b/MatrixRoomUtils.Web/Classes/LocalStorageWrapper.cs @@ -0,0 +1,35 @@ +using Blazored.LocalStorage; +using MatrixRoomUtils.Authentication; +using MatrixRoomUtils.Responses; + +namespace MatrixRoomUtils.Web.Classes; + +public partial class LocalStorageWrapper +{ + //some basic logic + public static async Task LoadFromLocalStorage(ILocalStorageService localStorage) + { + RuntimeCache.AccessToken = await localStorage.GetItemAsync<string>("rory.matrixroomutils.token"); + RuntimeCache.CurrentHomeserver = await localStorage.GetItemAsync<string>("rory.matrixroomutils.current_homeserver"); + RuntimeCache.LoginSessions = await localStorage.GetItemAsync<Dictionary<string, UserInfo>>("rory.matrixroomutils.user_cache") ?? new(); + RuntimeCache.HomeserverResolutionCache = await localStorage.GetItemAsync<Dictionary<string, HomeServerResolutionResult>>("rory.matrixroomutils.homeserver_resolution_cache") ?? new(); + Console.WriteLine($"[LocalStorageWrapper] Loaded {RuntimeCache.LoginSessions.Count} login sessions, {RuntimeCache.HomeserverResolutionCache.Count} homeserver resolution cache entries"); + if (RuntimeCache.AccessToken != null && RuntimeCache.CurrentHomeserver != null) + { + Console.WriteLine($"Access token and current homeserver are not null, creating authenticated home server"); + RuntimeCache.CurrentHomeServer = new AuthenticatedHomeServer(RuntimeCache.LoginSessions[RuntimeCache.AccessToken].LoginResponse.UserId, RuntimeCache.AccessToken, RuntimeCache.LoginSessions[RuntimeCache.AccessToken].LoginResponse.HomeServer); + Console.WriteLine("Created authenticated home server"); + } + RuntimeCache.WasLoaded = true; + } + + public static async Task SaveToLocalStorage(ILocalStorageService localStorage) + { + await localStorage.SetItemAsStringAsync("rory.matrixroomutils.token", RuntimeCache.AccessToken); + await localStorage.SetItemAsync("rory.matrixroomutils.current_homeserver", RuntimeCache.CurrentHomeserver); + await localStorage.SetItemAsync("rory.matrixroomutils.user_cache", RuntimeCache.LoginSessions); + await localStorage.SetItemAsync("rory.matrixroomutils.homeserver_resolution_cache", + RuntimeCache.HomeserverResolutionCache.DistinctBy(x => x.Key) + .ToDictionary(x => x.Key, x => x.Value)); + } +} \ No newline at end of file diff --git a/MatrixRoomUtils.Web/Classes/RuntimeStorage.cs b/MatrixRoomUtils.Web/Classes/RuntimeStorage.cs deleted file mode 100644 index d9d626f..0000000 --- a/MatrixRoomUtils.Web/Classes/RuntimeStorage.cs +++ /dev/null @@ -1,55 +0,0 @@ -using Blazored.LocalStorage; -using MatrixRoomUtils.Authentication; -using MatrixRoomUtils.Responses; - -namespace MatrixRoomUtils.Web.Classes; - -public class RuntimeStorage -{ - public static bool WasLoaded = false; - public static UserInfo? CurrentUserInfo { get; set; } - public static string AccessToken { get; set; } - public static string? CurrentHomeserver { get; set; } - - public static List<string> AccessTokens { get; set; } = new(); - //public static AppSettings AppSettings { get; set; } = new(); - - public static Dictionary<string, UserInfo> UsersCache { get; set; } = new(); - - public static Dictionary<string, HomeServerResolutionResult> HomeserverResolutionCache { get; set; } = new(); - - - //some basic logic - public static async Task LoadFromLocalStorage(ILocalStorageService localStorage) - { - AccessToken = await localStorage.GetItemAsync<string>("rory.matrixroomutils.token"); - CurrentHomeserver = await localStorage.GetItemAsync<string>("rory.matrixroomutils.current_homeserver"); - AccessTokens = await localStorage.GetItemAsync<List<string>>("rory.matrixroomutils.tokens") ?? new(); - UsersCache = await localStorage.GetItemAsync<Dictionary<string, UserInfo>>("rory.matrixroomutils.user_cache") ?? new(); - HomeserverResolutionCache = await localStorage.GetItemAsync<Dictionary<string, HomeServerResolutionResult>>("rory.matrixroomutils.homeserver_resolution_cache") ?? new(); - WasLoaded = true; - } - - public static async Task SaveToLocalStorage(ILocalStorageService localStorage) - { - await localStorage.SetItemAsStringAsync("rory.matrixroomutils.token", AccessToken); - await localStorage.SetItemAsync("rory.matrixroomutils.current_homeserver", CurrentHomeserver); - await localStorage.SetItemAsync("rory.matrixroomutils.tokens", AccessTokens); - await localStorage.SetItemAsync("rory.matrixroomutils.user_cache", UsersCache); - await localStorage.SetItemAsync("rory.matrixroomutils.homeserver_resolution_cache", - HomeserverResolutionCache.DistinctBy(x => x.Key) - .ToDictionary(x => x.Key, x => x.Value)); - } -} - -public class UserInfo -{ - public ProfileResponse Profile { get; set; } = new(); - public LoginResponse LoginResponse { get; set; } -} - -public class HomeServerResolutionResult -{ - public string Result { get; set; } - public DateTime ResolutionTime { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Web/Pages/DataExportPage.razor b/MatrixRoomUtils.Web/Pages/DataExportPage.razor index a7c6f6b..f9a4c37 100644 --- a/MatrixRoomUtils.Web/Pages/DataExportPage.razor +++ b/MatrixRoomUtils.Web/Pages/DataExportPage.razor @@ -17,13 +17,13 @@ <hr/> @if (_isLoaded) { -@foreach (var (token, user) in RuntimeStorage.UsersCache) +@foreach (var (token, user) in RuntimeCache.LoginSessions) { <IndexUserItem User="@user" Token="@token"/> <pre> @user.LoginResponse.UserId[1..].Split(":")[0]\auth\access_token=@token @user.LoginResponse.UserId[1..].Split(":")[0]\auth\device_id=@user.LoginResponse.DeviceId -@user.LoginResponse.UserId[1..].Split(":")[0]\auth\home_server=@(RuntimeStorage.HomeserverResolutionCache.ContainsKey(user.LoginResponse.HomeServer) ? RuntimeStorage.HomeserverResolutionCache[user.LoginResponse.HomeServer].Result : "loading...") +@user.LoginResponse.UserId[1..].Split(":")[0]\auth\home_server=@(RuntimeCache.HomeserverResolutionCache.ContainsKey(user.LoginResponse.HomeServer) ? RuntimeCache.HomeserverResolutionCache[user.LoginResponse.HomeServer].Result : "loading...") @user.LoginResponse.UserId[1..].Split(":")[0]\auth\user_id=@@@user.LoginResponse.UserId @user.LoginResponse.UserId[1..].Split(":")[0]\user\automatically_share_keys_with_trusted_users=true @user.LoginResponse.UserId[1..].Split(":")[0]\user\muted_tags=global @@ -46,29 +46,25 @@ else protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); - Console.WriteLine("Users in cache: " + RuntimeStorage.UsersCache.Count); - if (!RuntimeStorage.WasLoaded) + if (!RuntimeCache.WasLoaded) { - Console.WriteLine("[INDEX] !!! LOCALSTORAGE WAS NOT LOADED !!!"); - await RuntimeStorage.LoadFromLocalStorage(LocalStorage); + await LocalStorageWrapper.LoadFromLocalStorage(LocalStorage); - Console.WriteLine("Users in cache: " + RuntimeStorage.UsersCache.Count); - - var homeservers = RuntimeStorage.UsersCache.Values.Select(x => x.LoginResponse.HomeServer).Distinct(); + var homeservers = RuntimeCache.LoginSessions.Values.Select(x => x.LoginResponse.HomeServer).Distinct(); totalHomeservers = homeservers.Count(); StateHasChanged(); foreach (var hs in homeservers) { - if (RuntimeStorage.HomeserverResolutionCache.ContainsKey(hs)) continue; - var resolvedHomeserver = await MatrixAccount.ResolveHomeserverFromWellKnown(hs); + if (LocalStorageWrapper.HomeserverResolutionCache.ContainsKey(hs)) continue; + var resolvedHomeserver = await MatrixAuth.ResolveHomeserverFromWellKnown(hs); - if (RuntimeStorage.HomeserverResolutionCache.ContainsKey(hs)) - RuntimeStorage.HomeserverResolutionCache.Remove(hs); - RuntimeStorage.HomeserverResolutionCache.Add(hs, new(){Result = resolvedHomeserver, ResolutionTime = DateTime.Now}); - await RuntimeStorage.SaveToLocalStorage(LocalStorage); + if (LocalStorageWrapper.HomeserverResolutionCache.ContainsKey(hs)) + LocalStorageWrapper.HomeserverResolutionCache.Remove(hs); + LocalStorageWrapper.HomeserverResolutionCache.Add(hs, new() { Result = resolvedHomeserver, ResolutionTime = DateTime.Now }); + await LocalStorageWrapper.SaveToLocalStorage(LocalStorage); Console.WriteLine("Saved to local storage:"); - Console.WriteLine(JsonSerializer.Serialize(RuntimeStorage.HomeserverResolutionCache, new JsonSerializerOptions() + Console.WriteLine(JsonSerializer.Serialize(LocalStorageWrapper.HomeserverResolutionCache, new JsonSerializerOptions() { WriteIndented = true })); diff --git a/MatrixRoomUtils.Web/Pages/Index.razor b/MatrixRoomUtils.Web/Pages/Index.razor index 7e9facf..ea9404d 100644 --- a/MatrixRoomUtils.Web/Pages/Index.razor +++ b/MatrixRoomUtils.Web/Pages/Index.razor @@ -14,19 +14,19 @@ Small collection of tools to do not-so-everyday things. <h5>Signed in accounts - <a href="/Login">Add new account</a> or <a href="/ImportUsers">Import from TSV</a></h5> <hr/> @{ - Console.WriteLine("Users in cache: " + RuntimeStorage.UsersCache.Count); - if (!RuntimeStorage.WasLoaded) + Console.WriteLine("Users in cache: " + LocalStorageWrapper.LoginSessions.Count); + if (!LocalStorageWrapper.WasLoaded) { Console.WriteLine("[INDEX] !!! LOCALSTORAGE WAS NOT LOADED !!!"); - RuntimeStorage.LoadFromLocalStorage(LocalStorage).GetAwaiter().OnCompleted(() => + LocalStorageWrapper.LoadFromLocalStorage(LocalStorage).GetAwaiter().OnCompleted(() => { - Console.WriteLine("Users in cache: " + RuntimeStorage.UsersCache.Count); + Console.WriteLine("Users in cache: " + LocalStorageWrapper.LoginSessions.Count); StateHasChanged(); }); } } <form> - @foreach (var (token, user) in RuntimeStorage.UsersCache) + @foreach (var (token, user) in LocalStorageWrapper.LoginSessions) { <IndexUserItem User="@user" Token="@token"/> } diff --git a/MatrixRoomUtils.Web/Pages/LoginPage.razor b/MatrixRoomUtils.Web/Pages/LoginPage.razor index d193f95..aead5e8 100644 --- a/MatrixRoomUtils.Web/Pages/LoginPage.razor +++ b/MatrixRoomUtils.Web/Pages/LoginPage.razor @@ -25,22 +25,22 @@ string password = ""; async Task Login() { - var result = await MatrixAccount.Login(homeserver, username, password); + var result = await MatrixAuth.Login(homeserver, username, password); Console.WriteLine($"Obtained access token for {result.UserId}!"); - RuntimeStorage.AccessToken = result.AccessToken; + LocalStorageWrapper.AccessToken = result.AccessToken; var userinfo = new UserInfo() { LoginResponse = result }; - userinfo.Profile = await MatrixAccount.GetProfile(result.HomeServer, result.UserId); + userinfo.Profile = await MatrixAuth.GetProfile(result.HomeServer, result.UserId); - RuntimeStorage.UsersCache.Add(result.AccessToken, userinfo); - RuntimeStorage.CurrentHomeserver = await MatrixAccount.ResolveHomeserverFromWellKnown(result.HomeServer); + LocalStorageWrapper.LoginSessions.Add(result.AccessToken, userinfo); + LocalStorageWrapper.CurrentHomeserver = await MatrixAuth.ResolveHomeserverFromWellKnown(result.HomeServer); - await RuntimeStorage.SaveToLocalStorage(LocalStorage); + await LocalStorageWrapper.SaveToLocalStorage(LocalStorage); } } \ No newline at end of file diff --git a/MatrixRoomUtils.Web/Pages/PolicyListEditorPage.razor b/MatrixRoomUtils.Web/Pages/PolicyListEditorPage.razor index cedaf32..6c276b6 100644 --- a/MatrixRoomUtils.Web/Pages/PolicyListEditorPage.razor +++ b/MatrixRoomUtils.Web/Pages/PolicyListEditorPage.razor @@ -195,9 +195,9 @@ else protected override async Task OnInitializedAsync() { - if (!RuntimeStorage.WasLoaded) await RuntimeStorage.LoadFromLocalStorage(LocalStorage); + if (!LocalStorageWrapper.WasLoaded) await LocalStorageWrapper.LoadFromLocalStorage(LocalStorage); await base.OnInitializedAsync(); - if(RuntimeStorage.AccessToken == null || RuntimeStorage.CurrentHomeserver == null) + if(LocalStorageWrapper.AccessToken == null || LocalStorageWrapper.CurrentHomeserver == null) { NavigationManager.NavigateTo("/Login"); return; @@ -210,8 +210,8 @@ else private async Task LoadStatesAsync() { using var client = new HttpClient(); - client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", RuntimeStorage.AccessToken); - var response = await client.GetAsync($"{RuntimeStorage.CurrentHomeserver}/_matrix/client/r0/rooms/{RoomId}/state"); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", LocalStorageWrapper.AccessToken); + var response = await client.GetAsync($"{LocalStorageWrapper.CurrentHomeserver}/_matrix/client/r0/rooms/{RoomId}/state"); var content = await response.Content.ReadAsStringAsync(); // Console.WriteLine(JsonSerializer.Deserialize<object>(content).ToJson()); var stateEvents = JsonSerializer.Deserialize<List<StateEvent>>(content); diff --git a/MatrixRoomUtils.Web/Pages/PolicyListRoomList.razor b/MatrixRoomUtils.Web/Pages/PolicyListRoomList.razor index 9be8314..032d150 100644 --- a/MatrixRoomUtils.Web/Pages/PolicyListRoomList.razor +++ b/MatrixRoomUtils.Web/Pages/PolicyListRoomList.razor @@ -26,12 +26,12 @@ else } foreach (var s in PolicyRoomList) { - <a href="@(NavigationManager.Uri + "/" + s.RoomId.Replace('.', '~'))">@s.Name</a> + <a href="@(NavigationManager.Uri + "/" + s.RoomId.Replace('.', '~'))">[@s.Shortcode] @s.Name (@s.RoomId)</a> <br/> } - <div style="margin-bottom: 4em;"></div> } +<div style="margin-bottom: 4em;"></div> <LogView></LogView> @code { @@ -47,9 +47,9 @@ else protected override async Task OnInitializedAsync() { - if (!RuntimeStorage.WasLoaded) await RuntimeStorage.LoadFromLocalStorage(LocalStorage); + if (!LocalStorageWrapper.WasLoaded) await LocalStorageWrapper.LoadFromLocalStorage(LocalStorage); await base.OnInitializedAsync(); - if (RuntimeStorage.AccessToken == null || RuntimeStorage.CurrentHomeserver == null) + if (LocalStorageWrapper.AccessToken == null || LocalStorageWrapper.CurrentHomeserver == null) { NavigationManager.NavigateTo("/Login"); return; @@ -60,13 +60,31 @@ else private async Task EnumeratePolicyRooms() { + var xxxrooms = await LocalStorageWrapper.CurrentHomeServer.GetJoinedRooms(); + totalRoomCount = xxxrooms.Count; + StateHasChanged(); + + var xxxsemaphore = new SemaphoreSlim(256); + var xxxtasks = new List<Task<PolicyRoomInfo?>>(); + foreach (var room in xxxrooms) + { + xxxtasks.Add(GetPolicyRoomInfo(room.RoomId, xxxsemaphore)); + } + var xxxresults = await Task.WhenAll(xxxtasks); + PolicyRoomList.AddRange(xxxresults.Where(x => x != null).Select(x => x.Value)); + + Console.WriteLine($"Detected policy lists: {PolicyRoomList.ToJson()}"); + return; + using HttpClient wc = new(); - wc.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", RuntimeStorage.AccessToken); + wc.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", LocalStorageWrapper.AccessToken); + + //get room list //temporary hack until rooms get enumerated... string[] rooms = { "!fTjMjIzNKEsFlUIiru:neko.dev" }; - var _rooms = await wc.GetAsync($"{RuntimeStorage.CurrentHomeserver}/_matrix/client/v3/joined_rooms"); + var _rooms = await wc.GetAsync($"{LocalStorageWrapper.CurrentHomeserver}/_matrix/client/v3/joined_rooms"); Console.WriteLine($"Got {_rooms.StatusCode}..."); if (!_rooms.IsSuccessStatusCode) { @@ -82,15 +100,15 @@ else totalRoomCount = rooms.Length; StateHasChanged(); - var semaphore = new SemaphoreSlim(128); + var semaphore = new SemaphoreSlim(256); var tasks = new List<Task<PolicyRoomInfo?>>(); foreach (string room in rooms) { tasks.Add(GetPolicyRoomInfo(room, semaphore)); } var results = await Task.WhenAll(tasks); - PolicyRoomList.AddRange(results.Where(x => x != null).Select(x=>x.Value)); - + PolicyRoomList.AddRange(results.Where(x => x != null).Select(x => x.Value)); + //print to console Console.WriteLine($"Detected policy lists: {PolicyRoomList.ToJson()}"); @@ -101,16 +119,40 @@ else try { await semaphore.WaitAsync(); + PolicyRoomInfo roomInfo = new() + { + RoomId = room + }; using HttpClient wc = new(); - wc.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", RuntimeStorage.AccessToken); - var sk = await wc.GetAsync($"{RuntimeStorage.CurrentHomeserver}/_matrix/client/v3/rooms/{room}/state/org.matrix.mjolnir.shortcode"); + wc.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", LocalStorageWrapper.AccessToken); + var sk = await wc.GetAsync($"{LocalStorageWrapper.CurrentHomeserver}/_matrix/client/v3/rooms/{room}/state/org.matrix.mjolnir.shortcode"); if (sk.IsSuccessStatusCode) { var sko = await sk.Content.ReadFromJsonAsync<JsonElement>(); if (sko.TryGetProperty("shortcode", out JsonElement shortcode)) { Console.WriteLine($"Room {room} has a shortcode: {shortcode.GetString()}!"); - return new PolicyRoomInfo() { Name = room, Shortcode = shortcode.GetString(), RoomId = room }; + roomInfo.Shortcode = shortcode.GetString(); + // sk = await wc.GetAsync($"{LocalStorageWrapper.CurrentHomeserver}/_matrix/client/v3/rooms/{room}/state/m.room.name"); + // if (sk.IsSuccessStatusCode) + // { + // Console.WriteLine($"Got content: {await sk.Content.ReadAsStringAsync()}"); + // sko = await sk.Content.ReadFromJsonAsync<JsonElement>(); + // if (sko.TryGetProperty("name", out JsonElement roomname)) + // { + // Console.WriteLine($"Room {room} has a name: {roomname.GetString()}!"); + // roomInfo.Name = roomname.GetString(); + // } + // else Console.WriteLine("No record found..."); + // } + // else if (sk.StatusCode == System.Net.HttpStatusCode.NotFound) + // { + // } + // else Console.WriteLine($"Got failure while checking {room}: {sk.StatusCode} ({await sk.Content.ReadAsStringAsync()})..."); + var r = await LocalStorageWrapper.CurrentHomeServer.GetRoom(room); + roomInfo.Shortcode = (await r.GetStateAsync("org.matrix.mjolnir.shortcode")).Value.GetProperty("shortcode").GetString(); + roomInfo.Name = await r.GetNameAsync(); + return roomInfo; } else Console.WriteLine("No record found..."); } @@ -118,6 +160,7 @@ else { } else Console.WriteLine($"Got failure while checking {room}: {sk.StatusCode} ({await sk.Content.ReadAsStringAsync()})..."); + return null; } finally @@ -127,11 +170,11 @@ else semaphore.Release(); } } - + public struct PolicyRoomInfo { public string RoomId { get; set; } - public string Shortcode { get; set; } - public string Name { get; set; } + public string? Shortcode { get; set; } + public string? Name { get; set; } } -} \ No newline at end of file + } \ No newline at end of file diff --git a/MatrixRoomUtils.Web/Pages/RoomStateEditorPage.razor b/MatrixRoomUtils.Web/Pages/RoomStateEditorPage.razor new file mode 100644 index 0000000..6ad99d9 --- /dev/null +++ b/MatrixRoomUtils.Web/Pages/RoomStateEditorPage.razor @@ -0,0 +1,177 @@ +@page "/RoomStateViewer/{RoomId}/Edit" +@using MatrixRoomUtils.Authentication +@using MatrixRoomUtils.Web.Classes +@using Blazored.LocalStorage +@using System.Net.Http.Headers +@using System.Text.Json +@using System.Xml.Schema +@using MatrixRoomUtils.Extensions +@using MatrixRoomUtils.StateEventTypes +@using MatrixRoomUtils.Web.Shared.IndexComponents +@using Microsoft.Win32.SafeHandles +@inject ILocalStorageService LocalStorage +@inject NavigationManager NavigationManager +<h3>Room state editor</h3> +<p>Room ID: @RoomId</p> + +<p>@status</p> + +<input type="checkbox" id="showAll" @bind="ShowMembershipEvents"/> Show member events +<br/> +<InputSelect @bind-Value="shownStateKey"> + <option value="">-- State key --</option> + @foreach (var stateEvent in FilteredEvents.Where(x => x.state_key != "").Select(x => x.state_key).Distinct().OrderBy(x => x)) + { + <option value="@stateEvent">@stateEvent</option> + Console.WriteLine(stateEvent); + } +</InputSelect> +<br/> +<InputSelect @bind-Value="shownType"> + <option value="">-- Type --</option> + @foreach (var stateEvent in FilteredEvents.Where(x => x.state_key != shownStateKey).Select(x => x.type).Distinct().OrderBy(x => x)) + { + <option value="@stateEvent">@stateEvent</option> + } +</InputSelect> +<br/> + +<textarea @bind="shownEventJson" style="width: 100%; height: fit-content;"></textarea> + +<LogView></LogView> + +@code { + //get room list + // - sync withroom list filter + // type = support.feline.msc3784 + //support.feline.policy.lists.msc.v1 + + [Parameter] + public string? RoomId { get; set; } + + public List<StateEvent> FilteredEvents { get; set; } = new(); + public List<StateEvent> Events { get; set; } = new(); + public string status = ""; + + protected override async Task OnInitializedAsync() + { + if (!LocalStorageWrapper.WasLoaded) await LocalStorageWrapper.LoadFromLocalStorage(LocalStorage); + await base.OnInitializedAsync(); + if (LocalStorageWrapper.AccessToken == null || LocalStorageWrapper.CurrentHomeserver == null) + { + NavigationManager.NavigateTo("/Login"); + return; + } + RoomId = RoomId.Replace('~', '.'); + await LoadStatesAsync(); + Console.WriteLine("Policy list editor initialized!"); + } + + private DateTime _lastUpdate = DateTime.Now; + + private async Task LoadStatesAsync() + { + int StateLoaded = 0; + using var client = new HttpClient(); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", LocalStorageWrapper.AccessToken); + var response = await client.GetAsync($"{LocalStorageWrapper.CurrentHomeserver}/_matrix/client/r0/rooms/{RoomId}/state"); + // var response = await client.GetAsync($"http://localhost:5117/matrix-hq-state.json"); + //var _events = await response.Content.ReadFromJsonAsync<Queue<StateEventStruct>>(); + var _data = await response.Content.ReadAsStreamAsync(); + var __events = JsonSerializer.DeserializeAsyncEnumerable<StateEvent>(_data); + await foreach (var _ev in __events) + { + var e = new StateEvent() + { + type = _ev.type, + state_key = _ev.state_key, + origin_server_ts = _ev.origin_server_ts, + content = _ev.content + }; + Events.Add(e); + if (string.IsNullOrEmpty(e.state_key)) + { + FilteredEvents.Add(e); + } + StateLoaded++; + if ((DateTime.Now - _lastUpdate).TotalMilliseconds > 100) + { + _lastUpdate = DateTime.Now; + status = $"Loaded {StateLoaded} state events"; + StateHasChanged(); + await Task.Delay(0); + } + } + + StateHasChanged(); + } + + private async Task RebuildFilteredData() + { + status = "Rebuilding filtered data..."; + StateHasChanged(); + await Task.Delay(1); + var _FilteredEvents = Events; + if (!ShowMembershipEvents) + _FilteredEvents = _FilteredEvents.Where(x => x.type != "m.room.member").ToList(); + + status = "Done, rerendering!"; + StateHasChanged(); + await Task.Delay(1); + FilteredEvents = _FilteredEvents; + + if(_shownType != null) + shownEventJson = _FilteredEvents.Where(x => x.type == _shownType).First().content.ToJson(indent: true, ignoreNull: true); + + StateHasChanged(); + } + + + public struct PreRenderedStateEvent + { + public string content { get; set; } + public long origin_server_ts { get; set; } + public string state_key { get; set; } + public string type { get; set; } + // public string sender { get; set; } + // public string event_id { get; set; } + // public string user_id { get; set; } + // public string replaces_state { get; set; } + } + + public bool ShowMembershipEvents + { + get => _showMembershipEvents; + set + { + _showMembershipEvents = value; + RebuildFilteredData(); + } + } + + private bool _showMembershipEvents; + private string _shownStateKey; + private string _shownType; + + private string shownStateKey + { + get => _shownStateKey; + set + { + _shownStateKey = value; + RebuildFilteredData(); + } + } + + private string shownType + { + get => _shownType; + set + { + _shownType = value; + RebuildFilteredData(); + } + } + + private string shownEventJson { get; set; } +} \ No newline at end of file diff --git a/MatrixRoomUtils.Web/Pages/RoomStateRoomList.razor b/MatrixRoomUtils.Web/Pages/RoomStateRoomList.razor index 5a55b01..b13d069 100644 --- a/MatrixRoomUtils.Web/Pages/RoomStateRoomList.razor +++ b/MatrixRoomUtils.Web/Pages/RoomStateRoomList.razor @@ -9,7 +9,7 @@ @using MatrixRoomUtils.StateEventTypes @inject ILocalStorageService LocalStorage @inject NavigationManager NavigationManager -<h3>Policy list editor</h3> +<h3>Room state viewer</h3> <h5>Room list</h5> <hr/> @@ -26,7 +26,7 @@ else } foreach (var s in PolicyRoomList) { - <a href="@(NavigationManager.Uri + "/" + s.RoomId.Replace('.', '~'))">@s.Name</a> + <a href="@(NavigationManager.Uri + "/" + s.RoomId.Replace('.', '~'))">@s.Name (@s.RoomId)</a> <br/> } <div style="margin-bottom: 4em;"></div> @@ -43,9 +43,9 @@ else protected override async Task OnInitializedAsync() { - if (!RuntimeStorage.WasLoaded) await RuntimeStorage.LoadFromLocalStorage(LocalStorage); + if (!LocalStorageWrapper.WasLoaded) await LocalStorageWrapper.LoadFromLocalStorage(LocalStorage); await base.OnInitializedAsync(); - if (RuntimeStorage.AccessToken == null || RuntimeStorage.CurrentHomeserver == null) + if (LocalStorageWrapper.AccessToken == null || LocalStorageWrapper.CurrentHomeserver == null) { NavigationManager.NavigateTo("/Login"); return; @@ -57,12 +57,12 @@ else private async Task EnumeratePolicyRooms() { using HttpClient wc = new(); - wc.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", RuntimeStorage.AccessToken); + wc.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", LocalStorageWrapper.AccessToken); //get room list //temporary hack until rooms get enumerated... string[] rooms = { "!fTjMjIzNKEsFlUIiru:neko.dev" }; - var _rooms = await wc.GetAsync($"{RuntimeStorage.CurrentHomeserver}/_matrix/client/v3/joined_rooms"); + var _rooms = await wc.GetAsync($"{LocalStorageWrapper.CurrentHomeserver}/_matrix/client/v3/joined_rooms"); Console.WriteLine($"Got {_rooms.StatusCode}..."); if (!_rooms.IsSuccessStatusCode) { @@ -78,26 +78,59 @@ else totalRoomCount = rooms.Length; StateHasChanged(); - // var semaphore = new SemaphoreSlim(128); - // var tasks = new List<Task<PolicyRoomInfo?>>(); - // foreach (string room in rooms) - // { - // tasks.Add(GetPolicyRoomInfo(room, semaphore)); - // } - // var results = await Task.WhenAll(tasks); - // PolicyRoomList.AddRange(results.Where(x => x != null).Select(x=>x.Value)); - PolicyRoomList.AddRange(rooms.Select(x=>new PolicyRoomInfo() { Name = x, RoomId = x, Shortcode = "N/A" })); + var semaphore = new SemaphoreSlim(128); + var tasks = new List<Task<PolicyRoomInfo?>>(); + foreach (string room in rooms) + { + tasks.Add(GetPolicyRoomInfo(room, semaphore)); + } + var results = await Task.WhenAll(tasks); + PolicyRoomList.AddRange(results.Where(x => x != null).Select(x=>x.Value)); + StateHasChanged(); + } - //print to console - Console.WriteLine($"Detected policy lists: {PolicyRoomList.ToJson()}"); + private async Task<PolicyRoomInfo?> GetPolicyRoomInfo(string room, SemaphoreSlim semaphore) + { + try + { + await semaphore.WaitAsync(); + var roomInfo = new PolicyRoomInfo() + { + RoomId = room + }; + using HttpClient wc = new(); + wc.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", LocalStorageWrapper.AccessToken); + var sk = await wc.GetAsync($"{LocalStorageWrapper.CurrentHomeserver}/_matrix/client/v3/rooms/{room}/state/m.room.name"); + if (sk.IsSuccessStatusCode) + { + Console.WriteLine($"Got content: {await sk.Content.ReadAsStringAsync()}"); + var sko = await sk.Content.ReadFromJsonAsync<JsonElement>(); + if (sko.TryGetProperty("name", out JsonElement shortcode)) + { + Console.WriteLine($"Room {room} has a name: {shortcode.GetString()}!"); + roomInfo.Name = shortcode.GetString(); + } + else Console.WriteLine("No record found..."); + } + else if (sk.StatusCode == System.Net.HttpStatusCode.NotFound) + { + } + else Console.WriteLine($"Got failure while checking {room}: {sk.StatusCode} ({await sk.Content.ReadAsStringAsync()})..."); + return roomInfo; + } + finally + { + checkedRoomCount++; + StateHasChanged(); + semaphore.Release(); + } } - - + + public struct PolicyRoomInfo { public string RoomId { get; set; } - public string Shortcode { get; set; } public string Name { get; set; } } } \ No newline at end of file diff --git a/MatrixRoomUtils.Web/Pages/RoomStateViewerPage.razor b/MatrixRoomUtils.Web/Pages/RoomStateViewerPage.razor index ffd17d4..8c33d89 100644 --- a/MatrixRoomUtils.Web/Pages/RoomStateViewerPage.razor +++ b/MatrixRoomUtils.Web/Pages/RoomStateViewerPage.razor @@ -80,9 +80,9 @@ protected override async Task OnInitializedAsync() { - if (!RuntimeStorage.WasLoaded) await RuntimeStorage.LoadFromLocalStorage(LocalStorage); + if (!LocalStorageWrapper.WasLoaded) await LocalStorageWrapper.LoadFromLocalStorage(LocalStorage); await base.OnInitializedAsync(); - if (RuntimeStorage.AccessToken == null || RuntimeStorage.CurrentHomeserver == null) + if (LocalStorageWrapper.AccessToken == null || LocalStorageWrapper.CurrentHomeserver == null) { NavigationManager.NavigateTo("/Login"); return; @@ -97,8 +97,8 @@ { int StateLoaded = 0; using var client = new HttpClient(); - client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", RuntimeStorage.AccessToken); - var response = await client.GetAsync($"{RuntimeStorage.CurrentHomeserver}/_matrix/client/r0/rooms/{RoomId}/state"); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", LocalStorageWrapper.AccessToken); + var response = await client.GetAsync($"{LocalStorageWrapper.CurrentHomeserver}/_matrix/client/r0/rooms/{RoomId}/state"); // var response = await client.GetAsync($"http://localhost:5117/matrix-hq-state.json"); //var _events = await response.Content.ReadFromJsonAsync<Queue<StateEventStruct>>(); var _data = await response.Content.ReadAsStreamAsync(); diff --git a/MatrixRoomUtils.Web/Pages/UserImportPage.razor b/MatrixRoomUtils.Web/Pages/UserImportPage.razor index ca0a213..612b3ce 100644 --- a/MatrixRoomUtils.Web/Pages/UserImportPage.razor +++ b/MatrixRoomUtils.Web/Pages/UserImportPage.razor @@ -15,7 +15,7 @@ <table border="1"> @foreach (var (homeserver, username, password) in records) { - <tr style="background-color: @(RuntimeStorage.UsersCache.Any(x => x.Value.LoginResponse.UserId == $"@{username}:{homeserver}") ? "green" : "unset")"> + <tr style="background-color: @(LocalStorageWrapper.LoginSessions.Any(x => x.Value.LoginResponse.UserId == $"@{username}:{homeserver}") ? "green" : "unset")"> <td style="border-width: 1px;">@username</td> <td style="border-width: 1px;">@homeserver</td> <td style="border-width: 1px;">@password.Length chars</td> @@ -33,23 +33,21 @@ { foreach (var (homeserver, username, password) in records) { - if(RuntimeStorage.UsersCache.Any(x => x.Value.LoginResponse.UserId == $"@{username}:{homeserver}")) continue; - var result = await MatrixAccount.Login(homeserver, username, password); + if(LocalStorageWrapper.LoginSessions.Any(x => x.Value.LoginResponse.UserId == $"@{username}:{homeserver}")) continue; + var result = await MatrixAuth.Login(homeserver, username, password); Console.WriteLine($"Obtained access token for {result.UserId}!"); - RuntimeStorage.AccessToken = result.AccessToken; - var userinfo = new UserInfo() { LoginResponse = result }; - userinfo.Profile = await MatrixAccount.GetProfile(result.HomeServer, result.UserId); + userinfo.Profile = await MatrixAuth.GetProfile(result.HomeServer, result.UserId); - RuntimeStorage.UsersCache.Add(result.AccessToken, userinfo); + LocalStorageWrapper.LoginSessions.Add(result.AccessToken, userinfo); StateHasChanged(); } - await RuntimeStorage.SaveToLocalStorage(LocalStorage); + await LocalStorageWrapper.SaveToLocalStorage(LocalStorage); } private async Task FileChanged(InputFileChangeEventArgs obj) diff --git a/MatrixRoomUtils.Web/Shared/IndexComponents/IndexUserItem.razor b/MatrixRoomUtils.Web/Shared/IndexComponents/IndexUserItem.razor index cc6f9f6..33054e5 100644 --- a/MatrixRoomUtils.Web/Shared/IndexComponents/IndexUserItem.razor +++ b/MatrixRoomUtils.Web/Shared/IndexComponents/IndexUserItem.razor @@ -9,7 +9,7 @@ <div style="margin-bottom: 1em;"> <img style="border-radius: 50%; height: 3em; width: 3em;" src="@_avatarUrl"/> - <span style="margin-left: 1em;"><input type="radio" name="csa" checked="@(RuntimeStorage.AccessToken == Token)" onclick="@SetCurrent" style="text-decoration-line: unset;"/> <b>@User.Profile.DisplayName</b> on <b>@User.LoginResponse.HomeServer</b></span> + <span style="margin-left: 1em;"><input type="radio" name="csa" checked="@(LocalStorageWrapper.AccessToken == Token)" onclick="@SetCurrent" style="text-decoration-line: unset;"/> <b>@User.Profile.DisplayName</b> on <b>@User.LoginResponse.HomeServer</b></span> <a href="#" onclick="@RemoveUser">Remove</a> </div> @@ -32,17 +32,18 @@ private async Task RemoveUser() { - RuntimeStorage.UsersCache.Remove(Token); - await RuntimeStorage.SaveToLocalStorage(LocalStorage); + LocalStorageWrapper.LoginSessions.Remove(Token); + await LocalStorageWrapper.SaveToLocalStorage(LocalStorage); _removed = true; StateHasChanged(); } private async Task SetCurrent() { - RuntimeStorage.AccessToken = Token; - RuntimeStorage.CurrentHomeserver = await MatrixAccount.ResolveHomeserverFromWellKnown(RuntimeStorage.UsersCache[Token].LoginResponse.HomeServer); - await RuntimeStorage.SaveToLocalStorage(LocalStorage); + LocalStorageWrapper.AccessToken = Token; + LocalStorageWrapper.CurrentHomeserver = await MatrixAuth.ResolveHomeserverFromWellKnown(LocalStorageWrapper.LoginSessions[Token].LoginResponse.HomeServer); + await LocalStorageWrapper.SaveToLocalStorage(LocalStorage); + await LocalStorageWrapper.LoadFromLocalStorage(LocalStorage); StateHasChanged(); } diff --git a/MatrixRoomUtils.Web/Shared/MainLayout.razor b/MatrixRoomUtils.Web/Shared/MainLayout.razor index e0c8260..ae7c3f5 100644 --- a/MatrixRoomUtils.Web/Shared/MainLayout.razor +++ b/MatrixRoomUtils.Web/Shared/MainLayout.razor @@ -25,9 +25,9 @@ protected override async Task OnInitializedAsync() { - if (!RuntimeStorage.WasLoaded) + if (!LocalStorageWrapper.WasLoaded) { - await RuntimeStorage.LoadFromLocalStorage(LocalStorage); + await LocalStorageWrapper.LoadFromLocalStorage(LocalStorage); Console.WriteLine("Loaded from local storage"); StateHasChanged(); } |