about summary refs log tree commit diff
path: root/MatrixUtils.Web/Pages/Tools
diff options
context:
space:
mode:
authorRory& <root@rory.gay>2024-03-22 17:47:29 +0100
committerRory& <root@rory.gay>2024-03-22 17:47:29 +0100
commitc69e5c790b2b277d9b11265b8f0883e9f90fe3b9 (patch)
treea2ad72230772d7459605ebc4ba13337e70d3bda4 /MatrixUtils.Web/Pages/Tools
parentChanges (diff)
downloadMatrixUtils-c69e5c790b2b277d9b11265b8f0883e9f90fe3b9.tar.xz
Changes
Diffstat (limited to 'MatrixUtils.Web/Pages/Tools')
-rw-r--r--MatrixUtils.Web/Pages/Tools/InviteCounter.razor73
-rw-r--r--MatrixUtils.Web/Pages/Tools/MassCMEBan.razor75
-rw-r--r--MatrixUtils.Web/Pages/Tools/UserTrace.razor97
3 files changed, 197 insertions, 48 deletions
diff --git a/MatrixUtils.Web/Pages/Tools/InviteCounter.razor b/MatrixUtils.Web/Pages/Tools/InviteCounter.razor
new file mode 100644
index 0000000..8f4b4dd
--- /dev/null
+++ b/MatrixUtils.Web/Pages/Tools/InviteCounter.razor
@@ -0,0 +1,73 @@
+@page "/Tools/InviteCounter"
+@using ArcaneLibs.Extensions
+@using LibMatrix.RoomTypes
+@using System.Collections.ObjectModel
+@using LibMatrix
+@using System.Collections.Frozen
+@using LibMatrix.EventTypes.Spec.State
+@using MatrixUtils.Abstractions
+<h3>User Trace</h3>
+<hr/>
+
+<br/>
+<span>Room ID: </span>
+<InputText @bind-Value="@roomId"></InputText>
+<LinkButton OnClick="@Execute">Execute</LinkButton>
+
+<br/>
+
+<details>
+    <summary>Results</summary>
+    @foreach (var (userId, events) in invites.OrderByDescending(x=>x.Value).ToList()) {
+        <p>@userId: @events</p>
+    }
+</details>
+
+<br/>
+@foreach (var line in log.Reverse()) {
+    <pre>@line</pre>
+}
+
+@code {
+    private ObservableCollection<string> log { get; set; } = new();
+    private Dictionary<string, int> invites { get; set; } = new();
+    private AuthenticatedHomeserverGeneric hs { get; set; }
+    
+    [Parameter, SupplyParameterFromQuery(Name = "room")]
+    public string roomId { get; set; }
+    
+
+    protected override async Task OnInitializedAsync() {
+        log.CollectionChanged += (sender, args) => StateHasChanged();
+        hs = await RMUStorage.GetCurrentSessionOrNavigate();
+        if (hs is null) return;
+       
+        StateHasChanged();
+        Console.WriteLine("Rerendered!");
+        await base.OnInitializedAsync();
+    }
+
+    private async Task<string> Execute() {
+        var room = hs.GetRoom(roomId);
+        var events = room.GetManyMessagesAsync(limit: int.MaxValue);
+        await foreach (var resp in events) {
+            var all = resp.State.Concat(resp.Chunk);
+            foreach (var evt in all) {
+                if(evt.Type != RoomMemberEventContent.EventId) continue;
+                var content = evt.TypedContent as RoomMemberEventContent;
+                if(content.Membership != "invite") continue;
+                if(!invites.ContainsKey(evt.Sender)) invites[evt.Sender] = 0;
+                invites[evt.Sender]++;
+            }
+
+            log.Add($"{resp.State.Count} state, {resp.Chunk.Count} timeline");
+        }
+        
+        
+        
+        StateHasChanged();
+
+        return "";
+    }
+
+}
\ No newline at end of file
diff --git a/MatrixUtils.Web/Pages/Tools/MassCMEBan.razor b/MatrixUtils.Web/Pages/Tools/MassCMEBan.razor
new file mode 100644
index 0000000..cbbca9e
--- /dev/null
+++ b/MatrixUtils.Web/Pages/Tools/MassCMEBan.razor
@@ -0,0 +1,75 @@
+@page "/Tools/MassCMEBan"
+@using ArcaneLibs.Extensions
+@using LibMatrix.RoomTypes
+@using System.Collections.ObjectModel
+@using LibMatrix
+@using System.Collections.Frozen
+@using LibMatrix.EventTypes.Spec.State
+@using LibMatrix.EventTypes.Spec.State.Policy
+@using MatrixUtils.Abstractions
+<h3>User Trace</h3>
+<hr/>
+
+<br/>
+<span>Users:</span>
+<InputTextArea @bind-Value="@roomId"></InputTextArea>
+<LinkButton OnClick="@Execute">Execute</LinkButton>
+
+<br/>
+
+<br/>
+@foreach (var line in log.Reverse()) {
+    <pre>@line</pre>
+}
+
+@code {
+    // TODO: Properly implement page to be more useful
+    private ObservableCollection<string> log { get; set; } = new();
+    private AuthenticatedHomeserverGeneric hs { get; set; }
+    
+    [Parameter, SupplyParameterFromQuery(Name = "room")]
+    public string roomId { get; set; }
+    
+
+    protected override async Task OnInitializedAsync() {
+        log.CollectionChanged += (sender, args) => StateHasChanged();
+        hs = await RMUStorage.GetCurrentSessionOrNavigate();
+        if (hs is null) return;
+       
+        StateHasChanged();
+        Console.WriteLine("Rerendered!");
+        await base.OnInitializedAsync();
+    }
+
+    private async Task<string> Execute() {
+        var room = hs.GetRoom("!fTjMjIzNKEsFlUIiru:neko.dev");
+        // var room = hs.GetRoom("!yf7OpOiRDXx6zUGpT6:conduit.rory.gay");
+        var users = roomId.Split("\n").Select(x => x.Trim()).Where(x=>x.StartsWith('@')).ToList();
+        foreach (var user in users) {
+            var exists = false;
+            try {
+                exists = !string.IsNullOrWhiteSpace((await room.GetStateAsync<UserPolicyRuleEventContent>(UserPolicyRuleEventContent.EventId, user.Replace('@', '_'))).Entity);
+            } catch (Exception e) {
+                log.Add($"Failed to get {user}");
+            }
+
+            if (!exists) {
+                var evt = await room.SendStateEventAsync(UserPolicyRuleEventContent.EventId, user.Replace('@', '_'), new UserPolicyRuleEventContent() {
+                    Entity = user,
+                    Reason = "spam (invite)",
+                    Recommendation = "m.ban"
+                });
+                log.Add($"Sent {evt.EventId} to ban {user}");
+            }
+            else {
+                log.Add($"User {user} already exists");
+            }
+        }
+        
+        
+        StateHasChanged();
+
+        return "";
+    }
+
+}
\ No newline at end of file
diff --git a/MatrixUtils.Web/Pages/Tools/UserTrace.razor b/MatrixUtils.Web/Pages/Tools/UserTrace.razor
index d78c58a..4ad9874 100644
--- a/MatrixUtils.Web/Pages/Tools/UserTrace.razor
+++ b/MatrixUtils.Web/Pages/Tools/UserTrace.razor
@@ -5,6 +5,7 @@
 @using LibMatrix
 @using System.Collections.Frozen
 @using LibMatrix.EventTypes.Spec.State
+@using MatrixUtils.Abstractions
 <h3>User Trace</h3>
 <hr/>
 
@@ -16,7 +17,7 @@
 <details>
     <summary>Rooms to be searched (@rooms.Count)</summary>
     @foreach (var room in rooms) {
-        <span>@room.RoomId</span>
+        <span>@room.Room.RoomId</span>
         <br/>
     }
 </details>
@@ -29,8 +30,13 @@
     @foreach (var (userId, events) in matches) {
         <h4>@userId</h4>
         <ul>
-            @foreach (var eventResponse in events) {
-                <li>@eventResponse.Room.RoomId</li>
+            @foreach (var match in events) {
+                <li>
+                    <ul>
+                        <li>@match.RoomName (<span>@match.Room.RoomId</span>)</li>
+                        <li>Membership: @(match.Event.RawContent.ToJson(indent: false))</li>
+                    </ul>
+                </li>
             }
         </ul>
     }
@@ -43,10 +49,8 @@
 
 @code {
     private ObservableCollection<string> log { get; set; } = new();
-    List<AuthenticatedHomeserverGeneric> hss { get; set; } = new();
-    ObservableCollection<GenericRoom> rooms { get; set; } = new();
-    Dictionary<GenericRoom, FrozenSet<StateEventResponse>> roomMembers { get; set; } = new();
-    Dictionary<string, List<Matches>> matches = new();
+    List<RoomInfo> rooms { get; set; } = new();
+    Dictionary<string, List<Match>> matches = new();
 
     private string UserIdString {
         get => string.Join("\n", UserIDs);
@@ -59,16 +63,13 @@
         log.CollectionChanged += (sender, args) => StateHasChanged();
         var hs = await RMUStorage.GetCurrentSessionOrNavigate();
         if (hs is null) return;
-        rooms.CollectionChanged += (sender, args) => StateHasChanged();
         var sessions = await RMUStorage.GetAllTokens();
+        var baseRooms = new List<GenericRoom>();
         foreach (var userAuth in sessions) {
             var session = await RMUStorage.GetSession(userAuth);
             if (session is not null) {
-                var sessionRooms = await session.GetJoinedRooms();
-                foreach (var room in sessionRooms) {
-                    rooms.Add(room);
-                }
-
+                baseRooms.AddRange(await session.GetJoinedRooms());
+                var sessionRooms = (await session.GetJoinedRooms()).Where(x => !rooms.Any(y => y.Room.RoomId == x.RoomId)).ToList();
                 StateHasChanged();
                 log.Add($"Got {sessionRooms.Count} rooms for {userAuth.UserId}");
             }
@@ -76,32 +77,28 @@
 
         log.Add("Done fetching rooms!");
 
-        var distinctRooms = rooms.DistinctBy(x => x.RoomId).ToArray();
-        Random.Shared.Shuffle(distinctRooms);
-        rooms = new ObservableCollection<GenericRoom>(distinctRooms);
-        rooms.CollectionChanged += (sender, args) => StateHasChanged();
-        try {
-            var stateTasks = rooms.Select(async x => {
-                for (int i = 0; i < 10; i++) {
-                    try {
-                        return (x, await x.GetMembersListAsync(false));
-                    }
-                    catch {
-                        //
-                    }
+        baseRooms = baseRooms.DistinctBy(x => x.RoomId).ToList();
+
+        // rooms.CollectionChanged += (sender, args) => StateHasChanged();
+        var tasks = baseRooms.Select(async newRoom => {
+            bool success = false;
+            while (!success)
+                try {
+                    var state = await newRoom.GetFullStateAsListAsync();
+                    var newRoomInfo = new RoomInfo(newRoom, state);
+                    rooms.Add(newRoomInfo);
+                    log.Add($"Got {newRoomInfo.StateEvents.Count} events for {newRoomInfo.RoomName}");
+                    success = true;
                 }
-
-                return (x, new List<StateEventResponse>().ToFrozenSet());
-            }).ToAsyncEnumerable();
-
-            await foreach (var (room, state) in stateTasks) {
-                roomMembers.Add(room, state);
-                log.Add($"Got {state.Count} members for {room.RoomId}...");
-            }
-        }
-        catch {
-            //
-        }
+                catch (MatrixException e) {
+                    log.Add($"Failed to fetch room {newRoom.RoomId}! {e}");
+                    throw;
+                }
+                catch (HttpRequestException e) {
+                    log.Add($"Failed to fetch room {newRoom.RoomId}! {e}");
+                }
+        });
+        await Task.WhenAll(tasks);
 
         log.Add($"Done fetching members!");
 
@@ -114,17 +111,22 @@
 
     private async Task<string> Execute() {
         foreach (var userId in UserIDs) {
-            matches.Add(userId, new List<Matches>());
-            foreach (var (room, events) in roomMembers) {
-                if (events.Any(x => x.Type == RoomMemberEventContent.EventId && x.StateKey == userId)) {
+            matches.Add(userId, new List<Match>());
+
+            foreach (var room in rooms) {
+                var state = room.StateEvents.Where(x => x!.Type == RoomMemberEventContent.EventId).ToList();
+                if (state!.Any(x => x.StateKey == userId)) {
                     matches[userId].Add(new() {
-                        Event = events.First(x => x.StateKey == userId && x.Type == RoomMemberEventContent.EventId),
-                        Room = room,
+                        Event = state.First(x => x.StateKey == userId),
+                        Room = room.Room,
+                        RoomName = room.RoomName ?? "No name"
                     });
                 }
             }
         }
 
+        StateHasChanged();
+
         return "";
     }
 
@@ -133,8 +135,8 @@
     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));
+            var room = rooms.FirstOrDefault(x => x.Room.RoomId == ImportFromRoomId);
+            UserIdString = string.Join("\n", (await room.Room.GetMembersListAsync()).Select(x => x.StateKey));
         }
         catch (Exception e) {
             Console.WriteLine(e);
@@ -144,11 +146,10 @@
         StateHasChanged();
     }
 
-    private class Matches {
+    private class Match {
         public GenericRoom Room;
-
         public StateEventResponse Event;
-        // public 
+        public string RoomName { get; set; }
     }
 
 }
\ No newline at end of file