package lagoon import ( "fmt" "strings" "gorm.io/gorm" ) // OrderBy appends a database-default ORDER BY for an allow-listed qualified // column. Identifiers and directions are never taken from untrusted input: // column must match allowed exactly, and dir must be asc or desc. No COLLATE // is emitted; Postgres ICU pl-PL is the database default (CheckLocale). func OrderBy(db *gorm.DB, column, dir string, allowed []string) (*gorm.DB, error) { if db == nil { return nil, fmt.Errorf("lagoon: gorm db is nil") } clause, err := orderClause(column, dir, allowed) if err != nil { return nil, err } return db.Order(clause), nil } func orderClause(column, dir string, allowed []string) (string, error) { if !allowListed(column, allowed) { return "", fmt.Errorf("lagoon: order column %q is not allow-listed", column) } switch strings.ToLower(strings.TrimSpace(dir)) { case "asc": return column + " ASC", nil case "desc": return column + " DESC", nil default: return "", fmt.Errorf("lagoon: order direction %q is not allow-listed", dir) } } func allowListed(column string, allowed []string) bool { for _, a := range allowed { if a == column { return true } } return false }