fix: read privileged membership and the admin actions through a clean statement (T-12.1-38, T-12.1-39)

classes.fresh chained WithContext onto a lazy NewDB session, which clones the
caller's statement with its conditions. A handle that carried a condition
made IsPrivilegedMember answer false for a member of a privileged group, so
the takeover guard would have let the request through. No caller passes such
a handle today: the admin hooks hand over the write's transaction handle.

- fresh builds the empty statement before anything is chained onto it
- IsPrivilegedMember and PrivilegedGroupIDs read through fresh
This commit is contained in:
Jakub Zych
2026-10-05 14:53:41 +02:00
parent ba43ad9c03
commit f4969591e2
2 changed files with 10 additions and 5 deletions

View File

@@ -248,9 +248,13 @@ func ForceDeleteCleanup(ctx context.Context, db *gorm.DB, bucket *blob.Bucket, u
}
// fresh returns db with an empty statement on ctx, so a query never continues
// from conditions the caller's handle already carries.
// from conditions the caller's handle already carries. A NewDB session is
// lazy: GORM builds the empty statement on the next chain method, and a
// WithContext chained directly onto it clones the caller's statement with its
// conditions instead. Clauses() makes the empty statement exist first, so the
// handle stays clean whatever is chained next.
func fresh(ctx context.Context, db *gorm.DB) *gorm.DB {
return db.Session(&gorm.Session{NewDB: true}).WithContext(ctx)
return db.Session(&gorm.Session{NewDB: true, Context: ctx}).Clauses().Session(&gorm.Session{NewDB: true})
}
// userIDs returns the ids of users, skipping nil and unsaved entries.