diff --git a/ModAS.Server/Controllers/RoomQueryController.cs b/ModAS.Server/Controllers/Admin/RoomQueryController.cs
index a49e5c0..a49e5c0 100644
--- a/ModAS.Server/Controllers/RoomQueryController.cs
+++ b/ModAS.Server/Controllers/Admin/RoomQueryController.cs
diff --git a/ModAS.Server/Controllers/AppService/PingController.cs b/ModAS.Server/Controllers/AppService/PingController.cs
new file mode 100644
index 0000000..7b073c1
--- /dev/null
+++ b/ModAS.Server/Controllers/AppService/PingController.cs
@@ -0,0 +1,73 @@
+using System.IO.Pipelines;
+using System.Net;
+using System.Net.Http.Headers;
+using System.Text.Json;
+using ArcaneLibs;
+using LibMatrix;
+using LibMatrix.EventTypes.Spec;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Configuration.Json;
+using ModAS.Server;
+using ModAS.Server.Attributes;
+using ModAS.Server.Services;
+using MxApiExtensions.Services;
+
+namespace ModAS.Server.Controllers.AppService;
+
+[ApiController]
+public class PingController(
+ AppServiceRegistration asr,
+ ModASConfiguration config,
+ UserProviderService userProvider,
+ RoomContextService roomContextService,
+ RoomStateCacheService stateCacheService) : ControllerBase {
+ private static List<string> _ignoredInvalidationEvents { get; set; } = [
+ RoomMessageEventContent.EventId,
+ RoomMessageReactionEventContent.EventId
+ ];
+
+ [HttpPut("/_matrix/app/v1/transactions/{txnId}")]
+ [UserAuth(AuthType = AuthType.Server)]
+ public async Task<IActionResult> PutTransactions(string txnId) {
+ var data = await JsonSerializer.DeserializeAsync<EventList>(Request.Body);
+ Console.WriteLine(
+ $"PutTransaction: {txnId}: {data.Events.Count} events, {Util.BytesToString(Request.Headers.ContentLength ?? Request.ContentLength ?? Request.Body.Length)}");
+
+ if (!Directory.Exists("data"))
+ Directory.CreateDirectory("data");
+ Directory.CreateDirectory($"data/{txnId}");
+ // var pipe = PipeReader.Create(Request.Body);
+ // await using var file = System.IO.File.OpenWrite($"data/{txnId}");
+ // await pipe.CopyToAsync(file);
+ // await pipe.CompleteAsync();
+ //
+ // Console.WriteLine($"PutTransaction: {txnId}: {Util.BytesToString(file.Length)}");
+ for (var i = 0; i < data.Events.Count; i++) {
+ var evt = data.Events[i];
+ Console.WriteLine($"PutTransaction: {txnId}/{i}: {evt.Type} {evt.StateKey} {evt.Sender}");
+ await System.IO.File.WriteAllTextAsync($"data/{txnId}/{i}-{evt.Type.Replace("/", "")}-{evt.StateKey.Replace("/", "")}-{evt.Sender?.Replace("/", "")}.json",
+ JsonSerializer.Serialize(evt));
+
+ if (evt.Sender.EndsWith(':' + config.ServerName)) {
+ Console.WriteLine("PutTransaction: sender is local user, updating data...");
+ try {
+ var user = await userProvider.GetImpersonatedHomeserver(evt.Sender);
+ var rooms = await user.GetJoinedRooms();
+ foreach (var room in rooms) {
+ await roomContextService.GetRoomContext(room);
+ }
+ }
+ catch (Exception e) {
+ Console.WriteLine($"PutTransaction: failed to update data: {e}");
+ }
+ }
+ else
+ Console.WriteLine("PutTransaction: sender is remote user");
+
+ if (!string.IsNullOrWhiteSpace(evt.RoomId) && !_ignoredInvalidationEvents.Contains(evt.Type))
+ await stateCacheService.InvalidateRoomState(evt.RoomId);
+ }
+
+ return Ok(new { });
+ }
+}
\ No newline at end of file
diff --git a/ModAS.Server/Controllers/AppService/TransactionsController.cs b/ModAS.Server/Controllers/AppService/TransactionsController.cs
index b74e1e1..53bfaf5 100644
--- a/ModAS.Server/Controllers/AppService/TransactionsController.cs
+++ b/ModAS.Server/Controllers/AppService/TransactionsController.cs
@@ -8,6 +8,7 @@ using LibMatrix.EventTypes.Spec;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration.Json;
using ModAS.Server;
+using ModAS.Server.Attributes;
using ModAS.Server.Services;
using MxApiExtensions.Services;
@@ -26,16 +27,17 @@ public class TransactionsController(
];
[HttpPut("/_matrix/app/v1/transactions/{txnId}")]
+ [UserAuth(AuthType = AuthType.Server)]
public async Task<IActionResult> PutTransactions(string txnId) {
- if (!Request.Headers.ContainsKey("Authorization")) {
- Console.WriteLine("PutTransaction: missing authorization header");
- return Unauthorized();
- }
-
- if (Request.GetTypedHeaders().Get<AuthenticationHeaderValue>("Authorization")?.Parameter != asr.HomeserverToken) {
- Console.WriteLine($"PutTransaction: invalid authorization header: {Request.Headers["Authorization"]}");
- return Unauthorized();
- }
+ // if (!Request.Headers.ContainsKey("Authorization")) {
+ // Console.WriteLine("PutTransaction: missing authorization header");
+ // return Unauthorized();
+ // }
+ //
+ // if (Request.GetTypedHeaders().Get<AuthenticationHeaderValue>("Authorization")?.Parameter != asr.HomeserverToken) {
+ // Console.WriteLine($"PutTransaction: invalid authorization header: {Request.Headers["Authorization"]}");
+ // return Unauthorized();
+ // }
var data = await JsonSerializer.DeserializeAsync<EventList>(Request.Body);
Console.WriteLine(
@@ -53,7 +55,8 @@ public class TransactionsController(
for (var i = 0; i < data.Events.Count; i++) {
var evt = data.Events[i];
Console.WriteLine($"PutTransaction: {txnId}/{i}: {evt.Type} {evt.StateKey} {evt.Sender}");
- await System.IO.File.WriteAllTextAsync($"data/{txnId}/{i}-{evt.Type}-{evt.StateKey}-{evt.Sender}.json", JsonSerializer.Serialize(evt));
+ await System.IO.File.WriteAllTextAsync($"data/{txnId}/{i}-{evt.Type.Replace("/", "")}-{evt.StateKey.Replace("/", "")}-{evt.Sender?.Replace("/", "")}.json",
+ JsonSerializer.Serialize(evt));
if (evt.Sender.EndsWith(':' + config.ServerName)) {
Console.WriteLine("PutTransaction: sender is local user, updating data...");
diff --git a/ModAS.Server/Controllers/DebugController.cs b/ModAS.Server/Controllers/Debug/DebugController.cs
index f0fe91e..7bec3e5 100644
--- a/ModAS.Server/Controllers/DebugController.cs
+++ b/ModAS.Server/Controllers/Debug/DebugController.cs
@@ -2,16 +2,28 @@ using System.Collections.Frozen;
using ArcaneLibs.Extensions;
using Elastic.Apm;
using Elastic.Apm.Api;
-using LibMatrix;
using LibMatrix.Homeservers;
+using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
+using ModAS.Server.Attributes;
using ModAS.Server.Services;
using MxApiExtensions.Services;
-namespace ModAS.Server.Controllers;
+namespace ModAS.Server.Controllers.Debug;
+/// <summary>
+/// Provides debugging endpoints.
+/// </summary>
+/// <param name="config"><inheritdoc cref="ModASConfiguration"/></param>
+/// <param name="authHsProvider"><inheritdoc cref="UserProviderService"/></param>
+/// <param name="roomContextService"><inheritdoc cref="RoomContextService"/></param>
[ApiController]
+[UserAuth(AnyRoles = AuthRoles.Developer | AuthRoles.Administrator)]
public class DebugController(ModASConfiguration config, UserProviderService authHsProvider, RoomContextService roomContextService) : ControllerBase {
+ /// <summary>
+ /// Returns a JSON object containing the request and response headers.
+ /// </summary>
+ /// <returns>JSON object with request and partial response headers.</returns>
[HttpGet("/_matrix/_modas/debug")]
public IActionResult Index() {
return Ok(new {
@@ -20,6 +32,10 @@ public class DebugController(ModASConfiguration config, UserProviderService auth
});
}
+ /// <summary>
+ /// Returns a JSON object containing the configuration.
+ /// </summary>
+ /// <returns></returns>
[HttpGet("/_matrix/_modas/debug/config")]
public IActionResult Config() {
return Ok(config);
@@ -32,17 +48,17 @@ public class DebugController(ModASConfiguration config, UserProviderService auth
[HttpGet("/_matrix/_modas/debug/test_locate_users")]
public async IAsyncEnumerable<string> TestLocateUsers([FromQuery] string startUser) {
- List<AuthenticatedHomeserverGeneric> foundUsers = (await authHsProvider.GetValidUsers()).Select(x=>x.Value).ToList();
- if(!foundUsers.Any(x=>x.WhoAmI.UserId == startUser)) {
+ List<AuthenticatedHomeserverGeneric> foundUsers = (await authHsProvider.GetValidUsers()).Select(x => x.Value).ToList();
+ if (!foundUsers.Any(x => x.WhoAmI.UserId == startUser)) {
foundUsers.Add(await authHsProvider.GetImpersonatedHomeserver(startUser));
}
-
+
List<string> processedRooms = [], processedUsers = [];
var foundNew = true;
while (foundNew) {
var span1 = currentTransaction.StartSpan("iterateUsers", ApiConstants.TypeApp);
foundNew = false;
- var usersToProcess = foundUsers.Where(x => !processedUsers.Any(y=>x.WhoAmI.UserId == y)).ToFrozenSet();
+ var usersToProcess = foundUsers.Where(x => !processedUsers.Any(y => x.WhoAmI.UserId == y)).ToFrozenSet();
Console.WriteLine($"Got {usersToProcess.Count} users: {string.Join(", ", usersToProcess)}");
var rooms = usersToProcess.Select(async x => await x.GetJoinedRooms());
@@ -54,7 +70,7 @@ public class DebugController(ModASConfiguration config, UserProviderService auth
processedRooms.Add(room.RoomId);
var roomMembers = await room.GetMembersListAsync(false);
foreach (var roomMember in roomMembers) {
- if (roomMember.StateKey.EndsWith(':' + config.ServerName) && !foundUsers.Any(x=>x.WhoAmI.UserId == roomMember.StateKey)) {
+ if (roomMember.StateKey.EndsWith(':' + config.ServerName) && !foundUsers.Any(x => x.WhoAmI.UserId == roomMember.StateKey)) {
foundUsers.Add(await authHsProvider.GetImpersonatedHomeserver(roomMember.StateKey));
foundNew = true;
yield return roomMember.StateKey;
diff --git a/ModAS.Server/Controllers/HomeController.cs b/ModAS.Server/Controllers/HomeController.cs
index 5fd309f..eb17966 100644
--- a/ModAS.Server/Controllers/HomeController.cs
+++ b/ModAS.Server/Controllers/HomeController.cs
@@ -3,17 +3,14 @@ using Microsoft.AspNetCore.Mvc;
namespace ModAS.Server.Controllers;
+/// <summary>
+/// Manages the visual homepage.
+/// </summary>
[ApiController]
public class HomeController : Controller {
- private readonly ILogger<HomeController> _logger;
-
- public HomeController(ILogger<HomeController> logger) {
- _logger = logger;
- }
-
+ /// <inheritdoc cref="HomeController"/>
[HttpGet("/_matrix/_modas")]
public IActionResult Index() {
- //return wwwroot/index.html
return LocalRedirect("/index.html");
}
}
\ No newline at end of file
|