From 4601c2f1fcdaf551705a9da3c5e6ddfc3eff9138 Mon Sep 17 00:00:00 2001 From: Rory& Date: Fri, 22 Nov 2024 06:42:27 +0100 Subject: Some fixes all over, policy list work --- .../Draupnir/DraupnirProtectedRoomsEditor.razor | 10 +- .../Pages/Tools/Moderation/FindUsersByRegex.razor | 193 +++++++++++++++++++++ 2 files changed, 196 insertions(+), 7 deletions(-) create mode 100644 MatrixUtils.Web/Pages/Tools/Moderation/FindUsersByRegex.razor (limited to 'MatrixUtils.Web/Pages/Tools/Moderation') diff --git a/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirProtectedRoomsEditor.razor b/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirProtectedRoomsEditor.razor index 8745459..51f8e1b 100644 --- a/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirProtectedRoomsEditor.razor +++ b/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirProtectedRoomsEditor.razor @@ -3,6 +3,7 @@ @page "/Tools/Moderation/Draupnir/ProtectedRoomsEditor" @using System.Text.Json.Serialization @using LibMatrix +@using LibMatrix.EventTypes.Interop.Draupnir @using LibMatrix.EventTypes.Spec.State @using LibMatrix.RoomTypes

Edit Draupnir protected rooms

@@ -64,7 +65,7 @@ protected override async Task OnInitializedAsync() { hs = await RMUStorage.GetCurrentSessionOrNavigate(); if (hs is null) return; - data = await hs.GetAccountDataAsync("org.matrix.mjolnir.protected_rooms"); + data = await hs.GetAccountDataAsync(DraupnirProtectedRoomsData.EventId); StateHasChanged(); var tasks = (await hs.GetJoinedRooms()).Select(async room => { var plTask = room.GetPowerLevelsAsync(); @@ -121,12 +122,7 @@ StateHasChanged(); } - - private class DraupnirProtectedRoomsData { - [JsonPropertyName("rooms")] - public List Rooms { get; set; } = new(); - } - + private class EditorRoomInfo { public GenericRoom Room { get; set; } public bool IsProtected { get; set; } diff --git a/MatrixUtils.Web/Pages/Tools/Moderation/FindUsersByRegex.razor b/MatrixUtils.Web/Pages/Tools/Moderation/FindUsersByRegex.razor new file mode 100644 index 0000000..2d78f4e --- /dev/null +++ b/MatrixUtils.Web/Pages/Tools/Moderation/FindUsersByRegex.razor @@ -0,0 +1,193 @@ +@page "/Tools/Moderation/FindUsersByRegex" +@using System.Collections.Frozen +@using ArcaneLibs.Extensions +@using LibMatrix.RoomTypes +@using System.Collections.ObjectModel +@using System.Text.RegularExpressions +@using LibMatrix +@using LibMatrix.EventTypes.Spec.State +@using LibMatrix.Filters +@using LibMatrix.Helpers +@using LibMatrix.Utilities +

Find users by regex

+
+ +

Users (regex):

+ + +Execute +
+Remove kicks +Remove bans +
+ + +
+ Results + @foreach (var (userId, events) in matches) { +

@userId

+
    + @foreach (var match in events) { +
  • +
      +
    • @match.RoomName (@match.Room.RoomId)
    • +
    • Membership: @(match.Event.RawContent.ToJson(indent: false)) (sent by @match.Event.Sender)
    • +
    +
  • + } +
+ } +
+ +
+@foreach (var line in log.Reverse()) { +
@line
+} + +@code { + + private ObservableCollection log { get; set; } = new(); + + // List rooms { get; set; } = new(); + List rooms { get; set; } = []; + Dictionary> matches = new(); + + private string UserIdString { + get => string.Join("\n", UserIDs); + set => UserIDs = value.Split("\n").Select(x => x.Trim()).Where(x => !string.IsNullOrWhiteSpace(x)).ToList(); + } + + private List UserIDs { get; set; } = new(); + + private AuthenticatedHomeserverGeneric hs { get; set; } + + protected override async Task OnInitializedAsync() { + log.CollectionChanged += (sender, args) => StateHasChanged(); + log.Add("Authenticating"); + hs = await RMUStorage.GetCurrentSessionOrNavigate(); + if (hs is null) return; + + StateHasChanged(); + Console.WriteLine("Rerendered!"); + await base.OnInitializedAsync(); + } + + private async Task Execute() { + log.Add("Constructing sync helper..."); + var sh = new SyncHelper(hs) { + Filter = new SyncFilter() { + AccountData = new(types: []), + Presence = new(types: []), + Room = new() { + AccountData = new(types: []), + Ephemeral = new(types: []), + State = new(types: [RoomMemberEventContent.EventId]), + Timeline = new(types: []), + IncludeLeave = false + }, + } + }; + + log.Add("Starting sync..."); + var res = await sh.SyncAsync(); + + log.Add("Got sync response, parsing..."); + + var roomNames = (await Task.WhenAll((await hs.GetJoinedRooms()).Select(async room => { return (room.RoomId, await room.GetNameOrFallbackAsync()); }).ToList())).ToFrozenDictionary(x => x.Item1, x => x.Item2); + + foreach (var userIdRegex in UserIDs) { + var regex = new Regex(userIdRegex, RegexOptions.Compiled); + log.Add($"Searching for {regex}:"); + foreach (var (roomId, joinedRoom) in res.Rooms.Join) { + log.Add($"- Checking room {roomId}..."); + foreach (var evt in joinedRoom.State.Events) { + if (evt.StateKey is null) continue; + if (evt.Type is not RoomMemberEventContent.EventId) continue; + + if (regex.IsMatch(evt.StateKey)) { + log.Add($" - Found match in {roomId} for {evt.StateKey}"); + if (!matches.ContainsKey(evt.StateKey)) { + matches[evt.StateKey] = new(); + } + + var room = hs.GetRoom(roomId); + matches[evt.StateKey].Add(new Match { + Room = room, + Event = evt, + RoomName = roomNames[roomId] + }); + } + } + } + } + + log.Add("Done!"); + + StateHasChanged(); + + return ""; + } + + public string? ImportFromRoomId { get; set; } + + private async Task DoImportFromRoomId() { + try { + if (ImportFromRoomId is null) return; + var room = rooms.FirstOrDefault(x => x.RoomId == ImportFromRoomId); + UserIdString = string.Join("\n", (await room.GetMembersListAsync()).Select(x => x.StateKey)); + } + catch (Exception e) { + Console.WriteLine(e); + log.Add("Could not fetch members list!\n" + e.ToString()); + } + + StateHasChanged(); + } + + private class Match { + public GenericRoom Room; + public StateEventResponse Event; + public string RoomName { get; set; } + } + + private async IAsyncEnumerable GetMatches(string userId) { + var results = rooms.Select(async room => { + var state = await room.GetStateEventOrNullAsync(room.RoomId, userId); + if (state is not null) { + return new Match { + Room = room, + Event = state, + RoomName = await room.GetNameOrFallbackAsync() + }; + } + + return null; + }).ToAsyncEnumerable(); + await foreach (var result in results) { + if (result is not null) { + yield return result; + } + } + } + + private Task RemoveKicks() { + foreach (var (userId, matches) in matches) { + matches.RemoveAll(x => x.Event.ContentAs()!.Membership == "leave" && x.Event.Sender != x.Event.StateKey); + } + + matches.RemoveAll((x, y) => y.Count == 0); + StateHasChanged(); + return Task.CompletedTask; + } + + private Task RemoveBans() { + foreach (var (userId, matches) in matches) { + matches.RemoveAll(x => x.Event.ContentAs()!.Membership == "ban" && x.Event.Sender != x.Event.StateKey); + } + + matches.RemoveAll((x, y) => y.Count == 0); + StateHasChanged(); + return Task.CompletedTask; + } + +} \ No newline at end of file -- cgit 1.5.1