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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
using ArcaneLibs.Extensions;
using LibMatrix.EventTypes.Spec.State.Policy;
using LibMatrix.EventTypes.Spec.State.RoomInfo;
using LibMatrix.Helpers;
using LibMatrix.Homeservers;
using LibMatrix.RoomTypes;
using LibMatrix.Utilities.Bot.Services;
namespace MatrixAntiDmSpam;
public class PolicyExecutor(
ILogger<PolicyExecutor> logger,
AntiDmSpamConfiguration config,
InviteStore inviteStore,
PolicyStore policyStore,
AuthenticatedHomeserverGeneric homeserver) : IHostedService {
private GenericRoom? _logRoom = string.IsNullOrWhiteSpace(config.LogRoom) ? null : homeserver.GetRoom(config.LogRoom);
public async Task StartAsync(CancellationToken cancellationToken) {
inviteStore.OnInviteReceived.Add(CheckPoliciesAgainstInvite);
policyStore.OnPolicyUpdated.Add(CheckPolicyAgainstInvites);
}
public async Task StopAsync(CancellationToken cancellationToken) { }
public async Task CheckPoliciesAgainstInvite(InviteHandlerHostedService.InviteEventArgs invite) {
string roomName = await GetRoomNameAsync(invite);
var roomPolicy = policyStore.RoomPolicies.Any(x => x.Value.EntityMatches(invite.RoomId))
? policyStore.RoomPolicies.First(x => x.Value.EntityMatches(invite.RoomId)).Value
: null;
if (roomPolicy is not null) {
logger.LogWarning("Rejecting invite to {}, matching room policy {}", invite.RoomId, roomPolicy.ToJson(ignoreNull: true));
var message = new MessageBuilder()
.WithColoredBody("#FF0000", cb => cb.WithBody("Rejecting invite to ").WithMention(invite.RoomId, roomName).WithBody(", matching room policy.").WithNewline())
.WithCollapsibleSection("Policy JSON", cb => cb.WithCodeBlock(roomPolicy.ToJson(ignoreNull: true), "json"))
.Build();
if (_logRoom is not null)
await _logRoom.SendMessageEventAsync(message);
await homeserver.GetRoom(invite.RoomId).LeaveAsync();
}
var userPolicy = policyStore.UserPolicies.Any(x => x.Value.EntityMatches(invite.MemberEvent.Sender!))
? policyStore.UserPolicies.First(x => x.Value.EntityMatches(invite.MemberEvent.Sender!)).Value
: null;
if (userPolicy is not null) {
logger.LogWarning("Rejecting invite to {}, matching user policy {}", invite.RoomId, userPolicy.ToJson(ignoreNull: true));
var message = new MessageBuilder()
.WithColoredBody("#FF0000", cb => cb.WithBody("Rejecting invite to ").WithMention(invite.RoomId, roomName).WithBody(", matching user policy.").WithNewline())
.WithCollapsibleSection("Policy JSON", cb => cb.WithCodeBlock(userPolicy.ToJson(ignoreNull: true), "json"))
.Build();
if (_logRoom is not null)
await _logRoom.SendMessageEventAsync(message);
await homeserver.GetRoom(invite.RoomId).LeaveAsync();
}
}
public async Task CheckPolicyAgainstInvites(PolicyRuleEventContent policy) {
Console.WriteLine("CheckPolicyAgainstInvites called!!!!");
}
private async Task<string> GetRoomNameAsync(InviteHandlerHostedService.InviteEventArgs invite) {
// try to get room name from invite state
var name = invite.InviteData.InviteState?.Events?
.FirstOrDefault(evt => evt is { Type: RoomNameEventContent.EventId, StateKey: "" })?
.ContentAs<RoomNameEventContent>()?.Name;
if (!string.IsNullOrWhiteSpace(name))
return name;
// try to get room alias
var alias = invite.InviteData.InviteState?.Events?
.FirstOrDefault(evt => evt is { Type: RoomCanonicalAliasEventContent.EventId, StateKey: "" })?
.ContentAs<RoomCanonicalAliasEventContent>()?.Alias;
if (!string.IsNullOrWhiteSpace(alias))
return alias;
// try get room name via public previews
try {
#pragma warning disable CS0618 // Type or member is obsolete
name = await invite.Homeserver.GetRoom(invite.RoomId).GetNameOrFallbackAsync();
#pragma warning restore CS0618 // Type or member is obsolete
if (name != invite.RoomId && !string.IsNullOrWhiteSpace(name))
return name;
}
catch {
//ignored
}
// fallback to room alias via public previews
try {
alias = (await invite.Homeserver.GetRoom(invite.RoomId).GetCanonicalAliasAsync())?.Alias;
if (!string.IsNullOrWhiteSpace(alias))
return alias;
}
catch {
//ignored
}
// fall back to room ID
return invite.RoomId;
}
}
|