From 55741a91ccccea1569a8eb1d5157b2e65951e18b Mon Sep 17 00:00:00 2001 From: Derek Collison Date: Mon, 5 Aug 2024 14:56:09 -0700 Subject: [PATCH] When checking for import cycles, only need to check 'from', not the 'to' which could lead to false positives. However we need to pre-transform the 'from' token in case it contains transform direcrives, e.g. $1, {{}}. Signed-off-by: Derek Collison --- server/accounts.go | 11 +++++++---- test/accounts_cycles_test.go | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/server/accounts.go b/server/accounts.go index 33f926b10c5..b47a99afefa 100644 --- a/server/accounts.go +++ b/server/accounts.go @@ -1514,11 +1514,13 @@ func (a *Account) addServiceImportWithClaim(destination *Account, from, to strin } // Check if this introduces a cycle before proceeding. - if err := a.serviceImportFormsCycle(destination, from); err != nil { - return err + // From will be the mapped subject. + // If the 'to' has a wildcard make sure we pre-transform the 'from' before we check for cycles, e.g. '$1' + fromT := from + if subjectHasWildcard(to) { + fromT, _ = transformUntokenize(from) } - - if err := a.serviceImportFormsCycle(destination, to); err != nil { + if err := a.serviceImportFormsCycle(destination, fromT); err != nil { return err } @@ -1963,6 +1965,7 @@ func (a *Account) addServiceImport(dest *Account, from, to string, claim *jwt.Im tr *subjectTransform err error ) + if subjectHasWildcard(to) { // If to and from match, then we use the published subject. if to == from { diff --git a/test/accounts_cycles_test.go b/test/accounts_cycles_test.go index 0b3bac30ed7..9a192bb446b 100644 --- a/test/accounts_cycles_test.go +++ b/test/accounts_cycles_test.go @@ -524,6 +524,25 @@ func TestAccountCycleWithRenaming(t *testing.T) { } } +// https://github.com/nats-io/nats-server/issues/5752 +func TestAccountCycleFalsePositiveSubjectMapping(t *testing.T) { + conf := createConfFile(t, []byte(` + accounts { + A { + exports [ { service: "a.*" } ] + imports [ { service { subject: "a.*", account: B }, to: "b.*" } ] + } + B { + exports [ { service: "a.*" } ] + imports [ { service { subject: "a.foo", account: A }, to: "c.foo" } ] + } + } + `)) + if _, err := server.ProcessConfigFile(conf); err != nil { + t.Fatalf("Expected no errors on cycle service import, got error") + } +} + func clientConnectToServer(t *testing.T, s *server.Server) *nats.Conn { t.Helper() nc, err := nats.Connect(s.ClientURL(),