diff --git a/ModAS.Server/Controllers/Admin/RoomQueryController.cs b/ModAS.Server/Controllers/Admin/RoomQueryController.cs
index a49e5c0..02100e9 100644
--- a/ModAS.Server/Controllers/Admin/RoomQueryController.cs
+++ b/ModAS.Server/Controllers/Admin/RoomQueryController.cs
@@ -25,16 +25,12 @@ public class RoomQueryController(UserProviderService ahsProvider, ModASConfigura
getUsersSpan.End();
var collectRoomsSpan = currentTransaction.StartSpan("collectRooms", ApiConstants.TypeApp);
- // var userRoomLists = validUsers.Values.Select(ahs => ahs.GetJoinedRooms()).ToList();
- // await Task.WhenAll(userRoomLists);
- // var rooms = userRoomLists.SelectMany(r => r.Result).DistinctBy(x => x.RoomId).ToFrozenSet();
var roomsTasks = validUsers.Values.Select(u => userProviderService.GetUserRoomsCached(u.WhoAmI.UserId)).ToList();
await Task.WhenAll(roomsTasks);
var rooms = roomsTasks.SelectMany(r => r.Result).DistinctBy(x => x.RoomId).ToFrozenSet();
collectRoomsSpan.End();
var collectRoomStateSpan = currentTransaction.StartSpan("collectRoomState", ApiConstants.TypeApp);
- //make sure we lock!!!!
await stateCacheService.EnsureCachedFromRoomList(rooms);
var roomStateTasks = rooms.Select(GetRoomState).ToAsyncEnumerable();
var awaitRoomStateSpan = currentTransaction.StartSpan("fetchRoomState", ApiConstants.TypeApp);
@@ -46,6 +42,7 @@ public class RoomQueryController(UserProviderService ahsProvider, ModASConfigura
var roomMembers = roomState.Where(r => r.Type == RoomMemberEventContent.EventId).ToFrozenSet();
var localRoomMembers = roomMembers.Where(x => x.StateKey.EndsWith(':' + config.ServerName)).ToFrozenSet();
var nonMemberState = roomState.Where(x => !roomMembers.Contains(x)).ToFrozenSet();
+ var creationEvent = nonMemberState.FirstOrDefault(r => r.Type == RoomCreateEventContent.EventId);
filterStateEventsSpan.End();
var buildResultSpan = currentTransaction.StartSpan($"buildResult {room.RoomId}", ApiConstants.TypeApp);
@@ -56,21 +53,21 @@ public class RoomQueryController(UserProviderService ahsProvider, ModASConfigura
//members
TotalMembers = roomMembers.Count,
TotalLocalMembers = localRoomMembers.Count,
- JoinedMembers = roomMembers.Count(x => (x.TypedContent as RoomMemberEventContent)?.Membership == "join"),
- JoinedLocalMembers = localRoomMembers.Count(x => (x.TypedContent as RoomMemberEventContent)?.Membership == "join"),
+ JoinedMembers = roomMembers.Count(x => x.RawContent?["membership"]?.GetValue<string>() == "join"),
+ JoinedLocalMembers = localRoomMembers.Count(x => x.RawContent?["membership"]?.GetValue<string>() == "join"),
//-members
//creation event
- Creator = nonMemberState.FirstOrDefault(r => r.Type == RoomCreateEventContent.EventId)?.Sender,
- Version = nonMemberState.FirstOrDefault(r => r.Type == RoomCreateEventContent.EventId)?.RawContent?["room_version"]?.GetValue<string>(),
- Type = nonMemberState.FirstOrDefault(r => r.Type == RoomCreateEventContent.EventId)?.RawContent?["type"]?.GetValue<string>(),
- Federatable = nonMemberState.FirstOrDefault(r => r.Type == RoomCreateEventContent.EventId)?.RawContent?["m.federate"]?.GetValue<bool>() ?? true,
+ Creator = creationEvent!.Sender,
+ Version = creationEvent.RawContent?["room_version"]?.GetValue<string>(),
+ Type = creationEvent.RawContent?["type"]?.GetValue<string>(),
+ Federatable = creationEvent.RawContent?["m.federate"]?.GetValue<bool>() ?? true,
//-creation event
Name = nonMemberState.FirstOrDefault(r => r.Type == RoomNameEventContent.EventId)?.RawContent?["name"]?.GetValue<string>(),
CanonicalAlias = nonMemberState.FirstOrDefault(r => r.Type == RoomCanonicalAliasEventContent.EventId)?.RawContent?["alias"]?.GetValue<string>(),
- JoinRules = nonMemberState.FirstOrDefault(r => r.Type == RoomJoinRulesEventContent.EventId)?.RawContent?["join_rule"]?.GetValue<string>(),
GuestAccess = nonMemberState.FirstOrDefault(r => r.Type == RoomGuestAccessEventContent.EventId)?.RawContent?["guest_access"]?.GetValue<string>(),
HistoryVisibility =
nonMemberState.FirstOrDefault(r => r.Type == RoomHistoryVisibilityEventContent.EventId)?.RawContent?["history_visibility"]?.GetValue<string>(),
+ JoinRules = nonMemberState.FirstOrDefault(r => r.Type == RoomJoinRulesEventContent.EventId)?.RawContent?["join_rule"]?.GetValue<string>(),
Public = nonMemberState.FirstOrDefault(r => r.Type == RoomJoinRulesEventContent.EventId)?.RawContent?["join_rule"]?.GetValue<string>() == "public",
Encryption = nonMemberState.FirstOrDefault(r => r.Type == RoomEncryptionEventContent.EventId)?.RawContent?["algorithm"]?.GetValue<string>(),
AvatarUrl = nonMemberState.FirstOrDefault(r => r.Type == RoomAvatarEventContent.EventId)?.RawContent?["url"]?.GetValue<string>(),
diff --git a/ModAS.Server/Controllers/AppService/PingController.cs b/ModAS.Server/Controllers/AppService/PingController.cs
index 7b073c1..6db9033 100644
--- a/ModAS.Server/Controllers/AppService/PingController.cs
+++ b/ModAS.Server/Controllers/AppService/PingController.cs
@@ -1,73 +1,21 @@
-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 System.Text.Json.Serialization;
using Microsoft.AspNetCore.Mvc;
-using Microsoft.Extensions.Configuration.Json;
-using ModAS.Server;
+using Microsoft.OpenApi.Validations.Rules;
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}")]
+[ApiExplorerSettings(IgnoreApi = true)] //hide from swagger
+public class PingController : ControllerBase {
+ [HttpPost("/_matrix/app/v1/ping")]
[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);
- }
-
+ public IActionResult PutTransactions([FromBody] TransactionIdContainer data) {
return Ok(new { });
}
+
+ public class TransactionIdContainer {
+ [JsonPropertyName("transaction_id")]
+ public string TransactionId { get; set; }
+ }
}
\ No newline at end of file
diff --git a/ModAS.Server/Controllers/AppService/TransactionsController.cs b/ModAS.Server/Controllers/AppService/TransactionsController.cs
index 53bfaf5..fd8a6d3 100644
--- a/ModAS.Server/Controllers/AppService/TransactionsController.cs
+++ b/ModAS.Server/Controllers/AppService/TransactionsController.cs
@@ -15,6 +15,7 @@ using MxApiExtensions.Services;
namespace ModAS.Server.Controllers.AppService;
[ApiController]
+[ApiExplorerSettings(IgnoreApi = true)] //hide from swagger
public class TransactionsController(
AppServiceRegistration asr,
ModASConfiguration config,
diff --git a/ModAS.Server/Controllers/HomeController.cs b/ModAS.Server/Controllers/HomeController.cs
index eb17966..48432d5 100644
--- a/ModAS.Server/Controllers/HomeController.cs
+++ b/ModAS.Server/Controllers/HomeController.cs
@@ -1,5 +1,13 @@
using System.Diagnostics;
+using System.Net.Http.Headers;
+using System.Security.Cryptography;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Nodes;
+using System.Web;
using Microsoft.AspNetCore.Mvc;
+using ModAS.Server.Controllers.AppService;
+using MxApiExtensions.Services;
namespace ModAS.Server.Controllers;
@@ -7,10 +15,38 @@ namespace ModAS.Server.Controllers;
/// Manages the visual homepage.
/// </summary>
[ApiController]
-public class HomeController : Controller {
+public class HomeController(AppServiceRegistration asr, ModASConfiguration config) : Controller {
+ private const string ValidChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
/// <inheritdoc cref="HomeController"/>
[HttpGet("/_matrix/_modas")]
+ [ApiExplorerSettings(IgnoreApi = true)] //hide from swagger
public IActionResult Index() {
return LocalRedirect("/index.html");
}
+
+ [HttpGet("/_matrix/_modas/version")]
+ public IActionResult Version() {
+ return Ok(new {
+ Version = Modas.Server.Version.VersionString
+ });
+ }
+
+ [HttpGet("/_matrix/_modas/ping")]
+ public async Task<IActionResult> Ping() {
+ var txn = new PingController.TransactionIdContainer() {
+ TransactionId = RandomNumberGenerator.GetString(ValidChars, 32)
+ };
+ var url = $"{config.HomeserverUrl}/_matrix/client/v1/appservice/{HttpUtility.UrlEncode(asr.Id)}/ping";
+ var hrm = new HttpRequestMessage(HttpMethod.Post, url) {
+ Content = new StringContent(JsonSerializer.Serialize(txn), Encoding.UTF8, "application/json"),
+ Headers = {
+ Authorization = new AuthenticationHeaderValue("Bearer", asr.AppServiceToken)
+ }
+ };
+ var req = await new HttpClient().SendAsync(hrm);
+ var resp = await req.Content.ReadFromJsonAsync<JsonObject>();
+ resp!["tnxId"] = txn.TransactionId;
+ return Ok(resp);
+ }
}
\ No newline at end of file
|