blob: b74e1e17f06e354b5595fdda889cd75e2162b5f4 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
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.Services;
using MxApiExtensions.Services;
namespace ModAS.Server.Controllers.AppService;
[ApiController]
public class TransactionsController(
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}")]
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();
}
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}-{evt.StateKey}-{evt.Sender}.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 { });
}
}
|