diff --git a/pkg/identity/identity.go b/pkg/identity/identity.go index 045725a8d..5b7a3db49 100644 --- a/pkg/identity/identity.go +++ b/pkg/identity/identity.go @@ -44,27 +44,31 @@ 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) - } - // If sender has no canonical ID, try matching platform + platformID - return strings.EqualFold(platform, sender.Platform) && - sender.PlatformID == id - } - } - // Keep track of explicit username format isAtUsername := strings.HasPrefix(allowed, "@") // Strip leading "@" for username matching trimmed := strings.TrimPrefix(allowed, "@") + // Try canonical match first: "platform:id" format. + // Skip when the entry starts with "@" — the "@" prefix signals a + // username or Matrix MXID (e.g. "@alice:matrix.org"), not a platform:id pair. + if !isAtUsername { + 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 + } + } + } + // Split compound "id|username" format allowedID := trimmed allowedUser := "" @@ -83,6 +87,18 @@ func MatchAllowed(sender bus.SenderInfo, allowed string) bool { return true } + // Match the full "@"-prefixed entry against PlatformID or Username. + // Needed for Matrix MXIDs where both the config entry and the + // sender identifiers include the "@" prefix (e.g. "@alice:matrix.org"). + if isAtUsername { + if sender.PlatformID != "" && sender.PlatformID == allowed { + return true + } + if sender.Username != "" && sender.Username == allowed { + return true + } + } + // Match compound sender format against allowed parts if allowedUser != "" && sender.PlatformID != "" && sender.PlatformID == allowedID { return true diff --git a/pkg/identity/identity_test.go b/pkg/identity/identity_test.go index c60402d19..d10bab0e0 100644 --- a/pkg/identity/identity_test.go +++ b/pkg/identity/identity_test.go @@ -223,6 +223,53 @@ func TestMatchAllowed(t *testing.T) { allowed: " 123456 ", want: true, }, + // Matrix MXID matching (issue #2815) + // Matrix user IDs look like "@alice:matrix.org" — the colon must + // not be misinterpreted as a canonical "platform:id" separator. + { + name: "matrix MXID with @ prefix matches PlatformID", + sender: bus.SenderInfo{ + Platform: "matrix", + PlatformID: "@alice:matrix.org", + CanonicalID: BuildCanonicalID("matrix", "@alice:matrix.org"), + Username: "@alice:matrix.org", + }, + allowed: "@alice:matrix.org", + want: true, + }, + { + name: "matrix MXID without @ prefix matches PlatformID", + sender: bus.SenderInfo{ + Platform: "matrix", + PlatformID: "@alice:matrix.org", + CanonicalID: BuildCanonicalID("matrix", "@alice:matrix.org"), + Username: "@alice:matrix.org", + }, + allowed: "alice:matrix.org", + want: false, // ambiguous — could be a canonical "platform:id" entry + }, + { + name: "matrix canonical format matches", + sender: bus.SenderInfo{ + Platform: "matrix", + PlatformID: "@alice:matrix.org", + CanonicalID: BuildCanonicalID("matrix", "@alice:matrix.org"), + Username: "@alice:matrix.org", + }, + allowed: "matrix:@alice:matrix.org", + want: true, + }, + { + name: "matrix MXID rejects unlisted sender", + sender: bus.SenderInfo{ + Platform: "matrix", + PlatformID: "@eve:evil.org", + CanonicalID: BuildCanonicalID("matrix", "@eve:evil.org"), + Username: "@eve:evil.org", + }, + allowed: "@alice:matrix.org", + want: false, + }, } for _, tt := range tests {