about summary refs log tree commit diff
diff options
context:
space:
mode:
m---------LibMatrix0
-rw-r--r--MatrixAntiDmSpam.Core/PolicyExecutor.cs71
2 files changed, 54 insertions, 17 deletions
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) {