diff --git a/LibMatrix b/LibMatrix
-Subproject 51ff4a3b95ab38dd46c88f4e5482bf78449bb88
+Subproject a2b318f6f52dfec7f217643273e5b4e0855fe9e
diff --git a/MatrixAntiDmSpam.Core/PolicyExecutor.cs b/MatrixAntiDmSpam.Core/PolicyExecutor.cs
index 40432b8..8a24995 100644
--- a/MatrixAntiDmSpam.Core/PolicyExecutor.cs
+++ b/MatrixAntiDmSpam.Core/PolicyExecutor.cs
@@ -27,18 +27,7 @@ public class PolicyExecutor(
roomInviteHandler.OnInviteReceived.Add(CheckPoliciesAgainstInvite);
policyStore.OnPolicyAdded.Add(CheckPolicyAgainstOutstandingInvites);
if (config.IgnoreBannedUsers) {
- var ignoreList = await homeserver.GetAccountDataOrNullAsync<IgnoredUserListEventContent>(IgnoredUserListEventContent.EventId);
- if (ignoreList != null) {
- ignoreList.IgnoredUsers.RemoveAll((id, meta) => {
- if (meta.AdditionalData?.ContainsKey(MadsIgnoreMetadataContent.EventId) ?? false) {
- var metadata = meta.GetAdditionalData<JsonObject>(MadsIgnoreMetadataContent.EventId);
- if (metadata?["was_user_added"]?.GetValue<bool>() ?? false) {
- return true;
- }
- }
- return false;
- });
- }
+ await CleanupInvalidIgnoreListEntries();
policyStore.OnPoliciesChanged.Add(UpdateIgnoreList);
}
}
@@ -52,7 +41,7 @@ public class PolicyExecutor(
List<(StateEventResponse Old, StateEventResponse New)> UpdatedPolicies,
List<(StateEventResponse Old, StateEventResponse New)> RemovedPolicies) updates
) {
- var ignoreListContent = await homeserver.GetIgnoredUserListAsync();
+ var ignoreListContent = await FilterInvalidIgnoreListEntries();
foreach (var newEvent in updates.NewPolicies) {
var content = newEvent.TypedContent as PolicyRuleEventContent;
@@ -110,17 +99,64 @@ public class PolicyExecutor(
await homeserver.SetAccountDataAsync(IgnoredUserListEventContent.EventId, ignoreListContent);
}
+
+ private async Task<IgnoredUserListEventContent> FilterInvalidIgnoreListEntries() {
+ var ignoreList = await homeserver.GetAccountDataOrNullAsync<IgnoredUserListEventContent>(IgnoredUserListEventContent.EventId);
+ if (ignoreList != null) {
+ ignoreList.IgnoredUsers.RemoveAll((id, ignoredUserData) => {
+ if (ignoredUserData.AdditionalData is null) return false;
+ if (!ignoredUserData.AdditionalData.ContainsKey(MadsIgnoreMetadataContent.EventId)) return false;
+ var metadata = ignoredUserData.GetAdditionalData<JsonObject>(MadsIgnoreMetadataContent.EventId)!;
+
+ if (metadata.ContainsKey("policies")) {
+ var policies = metadata["policies"]!.AsArray();
+
+ bool IsPolicyEntryValid(JsonNode? p) =>
+ p!["room_id"]?.GetValue<string>() != null && p["type"]?.GetValue<string>() != null && p["state_key"]?.GetValue<string>() != null;
+
+ if (policies.Any(x => !IsPolicyEntryValid(x))) {
+ logger.LogWarning("Found invalid policy reference in ignore list, removing! {policy}",
+ policies.Where(x => !IsPolicyEntryValid(x)).Select(x => x.ToJson(ignoreNull: true)));
+ metadata["policies"] = new JsonArray(policies.Where(IsPolicyEntryValid).ToArray());
+ }
+ }
+
+ return metadata["was_user_added"]?.GetValue<bool>() is null or false;
+ });
+ }
- private async Task<IgnoredUserListEventContent> TryRecoverIgnoreList(IgnoredUserListEventContent content) {
+ return ignoreList;
+ }
+
+ private async Task CleanupInvalidIgnoreListEntries() {
+ var ignoreList = await FilterInvalidIgnoreListEntries();
+ ignoreList.IgnoredUsers.RemoveAll((id, _) => !(id.StartsWith('@') && id.Contains(':')));
+ List<string> idsToRemove = [];
+ foreach (var (id, ignoredUserData) in ignoreList.IgnoredUsers) {
+ if (ignoredUserData.AdditionalData is null) continue;
+ if (!ignoredUserData.AdditionalData.ContainsKey(MadsIgnoreMetadataContent.EventId)) continue;
+ try {
+ var metadata = ignoredUserData.GetAdditionalData<MadsIgnoreMetadataContent>(MadsIgnoreMetadataContent.EventId)!;
+
+ if (metadata.Policies.Count == 0 && !metadata.WasUserAdded) {
+ idsToRemove.Add(id);
+ }
+ }
+ catch (Exception e) {
+ logger.LogError(e, "Failed to parse ignore list entry for {}", id);
+ }
+ }
+ foreach (var id in idsToRemove) {
+ ignoreList.IgnoredUsers.Remove(id);
+ }
+ await homeserver.SetAccountDataAsync(IgnoredUserListEventContent.EventId, ignoreList);
}
#endregion
#region Feature: Report blocked invites
-
-
#endregion
#region Feature: Reject invites
@@ -172,7 +208,8 @@ public class PolicyExecutor(
}
if (!policyMatches) return null;
- logger.LogWarning("[{}] Rejecting invite to {}, matching {} {}", homeserver.WhoAmI.UserId, invite.RoomId, policy.GetType().GetFriendlyName(), policy.ToJson(ignoreNull: true));
+ logger.LogWarning("[{}] Rejecting invite to {}, matching {} {}", homeserver.WhoAmI.UserId, invite.RoomId, policy.GetType().GetFriendlyName(),
+ policy.ToJson(ignoreNull: true));
return Task.Run(async () => {
if (_logRoom is not null) {
|