mirror of
https://github.com/truewhile/MeBox.git
synced 2026-09-29 11:36:36 +08:00
fix: harden bot accounts and download handling
This commit is contained in:
@@ -72,7 +72,46 @@ func buildDSN(cfg *config.Config) string {
|
||||
|
||||
// AutoMigrate creates tables for every model registered in the model package.
|
||||
func AutoMigrate(db *gorm.DB) error {
|
||||
return db.AutoMigrate(model.AllModels()...)
|
||||
if err := db.AutoMigrate(model.AllModels()...); err != nil {
|
||||
return err
|
||||
}
|
||||
return enforceTelegramBindingOneToOne(db)
|
||||
}
|
||||
|
||||
func enforceTelegramBindingOneToOne(db *gorm.DB) error {
|
||||
if !db.Migrator().HasTable(&model.TelegramBinding{}) {
|
||||
return nil
|
||||
}
|
||||
return db.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Exec(`
|
||||
DELETE FROM telegram_bindings
|
||||
WHERE deleted_at IS NULL
|
||||
AND user_id IN (
|
||||
SELECT user_id
|
||||
FROM telegram_bindings
|
||||
WHERE deleted_at IS NULL
|
||||
GROUP BY user_id
|
||||
HAVING COUNT(*) > 1
|
||||
)
|
||||
AND id NOT IN (
|
||||
SELECT id
|
||||
FROM (
|
||||
SELECT id,
|
||||
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at ASC, id ASC) AS rn
|
||||
FROM telegram_bindings
|
||||
WHERE deleted_at IS NULL
|
||||
)
|
||||
WHERE rn = 1
|
||||
)
|
||||
`).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Exec(`
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_telegram_bindings_user_id_active
|
||||
ON telegram_bindings(user_id)
|
||||
WHERE deleted_at IS NULL
|
||||
`).Error
|
||||
})
|
||||
}
|
||||
|
||||
// zapStdLogger adapts a *zap.Logger to GORM's tiny logger interface.
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/glebarez/sqlite"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/ShukeBta/MediaStationGo/internal/model"
|
||||
)
|
||||
|
||||
func TestEnforceTelegramBindingOneToOneCleansDuplicatesAndAddsIndex(t *testing.T) {
|
||||
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := db.AutoMigrate(&model.TelegramBinding{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
createdAt := time.Now().Add(-time.Hour)
|
||||
rows := []model.TelegramBinding{
|
||||
{TelegramUserID: 10001, ChatID: 10001, UserID: "user-1"},
|
||||
{TelegramUserID: 10002, ChatID: 10002, UserID: "user-1"},
|
||||
}
|
||||
for i := range rows {
|
||||
rows[i].CreatedAt = createdAt.Add(time.Duration(i) * time.Minute)
|
||||
if err := db.Create(&rows[i]).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := enforceTelegramBindingOneToOne(db); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var count int64
|
||||
if err := db.Model(&model.TelegramBinding{}).Where("user_id = ?", "user-1").Count(&count).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if count != 1 {
|
||||
t.Fatalf("active bindings for user-1 = %d, want 1", count)
|
||||
}
|
||||
if err := db.Create(&model.TelegramBinding{TelegramUserID: 10003, ChatID: 10003, UserID: "user-1"}).Error; err == nil {
|
||||
t.Fatal("expected unique index to reject another active binding for the same user")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user