diff --git a/session/sql_migration.go b/session/sql_migration.go index 428cc0fce..0f79cd9da 100644 --- a/session/sql_migration.go +++ b/session/sql_migration.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" "reflect" + "sort" "time" "github.com/davecgh/go-spew/spew" @@ -380,11 +381,18 @@ func overrideSessionTimeZone(session *Session) { // as nil in the bbolt store. Therefore, we also override the permissions // or caveats to nil for the migrated session in that scenario, so that the // deep equals check does not fail in this scenario either. +// +// Additionally, we sort the caveats of both the kv and sql sessions by +// their ID, so that they are always comparable in a deterministic way with deep +// equals. func overrideMacaroonRecipe(kvSession *Session, migratedSession *Session) { if kvSession.MacaroonRecipe != nil { kvPerms := kvSession.MacaroonRecipe.Permissions kvCaveats := kvSession.MacaroonRecipe.Caveats + // If the kvSession has a MacaroonRecipe with nil set for any + // of the fields, we need to override the migratedSession + // MacaroonRecipe to match that. if kvPerms == nil && kvCaveats == nil { migratedSession.MacaroonRecipe = &MacaroonRecipe{} } else if kvPerms == nil { @@ -392,5 +400,26 @@ func overrideMacaroonRecipe(kvSession *Session, migratedSession *Session) { } else if kvCaveats == nil { migratedSession.MacaroonRecipe.Caveats = nil } + + sqlCaveats := migratedSession.MacaroonRecipe.Caveats + + // If there have been caveats set for the MacaroonRecipe, + // the order of the postgres db caveats will in very rare cases + // differ from the kv store caveats. Therefore, we sort + // both the kv and sql caveats by their ID, so that we can + // compare them in a deterministic way. + if kvCaveats != nil { + sort.Slice(kvCaveats, func(i, j int) bool { + return bytes.Compare( + kvCaveats[i].Id, kvCaveats[j].Id, + ) < 0 + }) + + sort.Slice(sqlCaveats, func(i, j int) bool { + return bytes.Compare( + sqlCaveats[i].Id, sqlCaveats[j].Id, + ) < 0 + }) + } } }