From 05b1915278d8b54e7952bdaeb3288e2308ff11b2 Mon Sep 17 00:00:00 2001 From: liaoyinglong Date: Mon, 30 Mar 2026 16:14:38 +0800 Subject: [PATCH] fix: skip canonical ID parsing for @-prefixed allow_from entries Matrix user IDs (@user:server) were incorrectly parsed as canonical IDs (platform:id), causing allow_from matching to always fail. Skip canonical parsing when the entry starts with '@', and match PlatformID/Username against the original value (with '@') for platforms like Matrix where IDs include '@'. Co-authored-by: Amp --- pkg/identity/identity.go | 40 +++++++++++++++++++++++------------ pkg/identity/identity_test.go | 27 +++++++++++++++++++++++ 2 files changed, 54 insertions(+), 13 deletions(-) diff --git a/pkg/identity/identity.go b/pkg/identity/identity.go index 045725a8d..383dabd0b 100644 --- a/pkg/identity/identity.go +++ b/pkg/identity/identity.go @@ -44,18 +44,22 @@ func MatchAllowed(sender bus.SenderInfo, allowed string) bool { return false } - // Try canonical match first: "platform:id" format - if platform, id, ok := ParseCanonicalID(allowed); ok { - // Only treat as canonical if the platform portion looks like a known platform name - // (not a pure-numeric string, which could be a compound ID) - if !isNumeric(platform) { - candidate := BuildCanonicalID(platform, id) - if candidate != "" && sender.CanonicalID != "" { - return strings.EqualFold(sender.CanonicalID, candidate) + // Try canonical match first: "platform:id" format. + // Skip when allowed starts with "@" — that indicates a username + // (e.g., Matrix user IDs like "@alice:matrix.org"), not a canonical ID. + if !strings.HasPrefix(allowed, "@") { + if platform, id, ok := ParseCanonicalID(allowed); ok { + // Only treat as canonical if the platform portion looks like a known platform name + // (not a pure-numeric string, which could be a compound ID) + if !isNumeric(platform) { + candidate := BuildCanonicalID(platform, id) + if candidate != "" && sender.CanonicalID != "" { + return strings.EqualFold(sender.CanonicalID, candidate) + } + // If sender has no canonical ID, try matching platform + platformID + return strings.EqualFold(platform, sender.Platform) && + sender.PlatformID == id } - // If sender has no canonical ID, try matching platform + platformID - return strings.EqualFold(platform, sender.Platform) && - sender.PlatformID == id } } @@ -78,8 +82,18 @@ func MatchAllowed(sender bus.SenderInfo, allowed string) bool { return true } - // Match against Username only when explicitly requested via "@username" - if isAtUsername && sender.Username != "" && sender.Username == trimmed { + // Match against Username only when explicitly requested via "@username". + // Compare against both the trimmed value and the original allowed value, + // because some platforms (e.g., Matrix) include "@" in their user IDs. + if isAtUsername && sender.Username != "" { + if sender.Username == trimmed || sender.Username == allowed { + return true + } + } + + // Also try matching PlatformID against the original "@..." value + // for platforms where PlatformID itself contains "@" (e.g., Matrix "@user:server"). + if isAtUsername && sender.PlatformID != "" && sender.PlatformID == allowed { return true } diff --git a/pkg/identity/identity_test.go b/pkg/identity/identity_test.go index c60402d19..d643f8820 100644 --- a/pkg/identity/identity_test.go +++ b/pkg/identity/identity_test.go @@ -78,6 +78,14 @@ func TestMatchAllowed(t *testing.T) { Username: "carol", } + matrixSender := bus.SenderInfo{ + Platform: "matrix", + PlatformID: "@example:matrix.org", + CanonicalID: "matrix:@example:matrix.org", + Username: "@example:matrix.org", + DisplayName: "@example:matrix.org", + } + tests := []struct { name string sender bus.SenderInfo @@ -223,6 +231,25 @@ func TestMatchAllowed(t *testing.T) { allowed: " 123456 ", want: true, }, + // Matrix user ID format "@user:server" + { + name: "matrix user ID matches via @username", + sender: matrixSender, + allowed: "@example:matrix.org", + want: true, + }, + { + name: "matrix canonical format also works", + sender: matrixSender, + allowed: "matrix:@example:matrix.org", + want: true, + }, + { + name: "matrix user ID wrong user does not match", + sender: matrixSender, + allowed: "@other:matrix.org", + want: false, + }, } for _, tt := range tests {