session: cover empty caveat verification ids

Add migration coverage for nested empty caveat verification IDs
and normalize the migrated SQL representation so empty byte
slices compare consistently with the KV store.
This commit is contained in:
Viktor Torstensson 2026-05-18 12:23:06 +02:00
parent ebd7ac39c6
commit 7b3916596f
No known key found for this signature in database
GPG key ID: 961CC8259AE675D4
2 changed files with 49 additions and 0 deletions

View file

@ -678,6 +678,33 @@ func overrideMacaroonRecipe(kvSession *Session, migratedSession *Session) {
})
}
// Empty caveat verification IDs can be persisted as nil by SQL
// backends, while the KV store can retain them as empty slices.
// After sorting, we only normalize caveats that still line up
// by ID. If the lengths or IDs differ, we leave the slices
// as-is and let the subsequent DeepEqual report the migration
// mismatch, hence let the migration fail.
if len(kvCaveats) == len(sqlCaveats) {
for i := range kvCaveats {
IDMatches := bytes.Equal(
kvCaveats[i].Id, sqlCaveats[i].Id,
)
if !IDMatches {
break
}
// Override the VerificationId if it's an empty
// slice in the KV store, but nil in SQL.
if len(kvCaveats[i].VerificationId) == 0 &&
kvCaveats[i].VerificationId != nil &&
sqlCaveats[i].VerificationId == nil {
sqlCaveats[i].VerificationId = []byte{}
}
}
}
// Similarly, we sort the macaroon permissions for both the kv
// and sql sessions, so that we can compare them in a
// deterministic way.

View file

@ -289,6 +289,28 @@ func TestSessionsStoreMigration(t *testing.T) {
return getBoltStoreSessions(t, store)
},
},
{
name: "one session with empty caveat verification id",
populateDB: func(t *testing.T, store *BoltStore,
_ accounts.Store) []*Session {
rCaveats := []macaroon.Caveat{
{
Id: []byte("id"),
VerificationId: []byte{},
},
}
_, err := store.NewSession(
ctx, "test", TypeMacaroonAdmin,
time.Unix(1000, 0), "foo.bar.baz:1234",
WithMacaroonRecipe(rCaveats, perms),
)
require.NoError(t, err)
return getBoltStoreSessions(t, store)
},
},
{
name: "one session with macaroon recipe nil perms",
populateDB: func(t *testing.T, store *BoltStore,