butterrobot/internal/migration/migrations.go
Felipe M. ece8280358
All checks were successful
ci/woodpecker/tag/release Pipeline was successful
feat: db migrations, encrypted passwords
2025-04-21 15:32:46 +02:00

102 lines
No EOL
2.2 KiB
Go

package migration
import (
"database/sql"
"golang.org/x/crypto/bcrypt"
)
func init() {
// Register migrations
Register(1, "Initial schema with bcrypt passwords", migrateInitialSchemaUp, migrateInitialSchemaDown)
}
// Initial schema creation with bcrypt passwords - version 1
func migrateInitialSchemaUp(db *sql.DB) error {
// Create channels table
_, err := db.Exec(`
CREATE TABLE IF NOT EXISTS channels (
id INTEGER PRIMARY KEY AUTOINCREMENT,
platform TEXT NOT NULL,
platform_channel_id TEXT NOT NULL,
enabled BOOLEAN NOT NULL DEFAULT 0,
channel_raw TEXT NOT NULL,
UNIQUE(platform, platform_channel_id)
)
`)
if err != nil {
return err
}
// Create channel_plugin table
_, err = db.Exec(`
CREATE TABLE IF NOT EXISTS channel_plugin (
id INTEGER PRIMARY KEY AUTOINCREMENT,
channel_id INTEGER NOT NULL,
plugin_id TEXT NOT NULL,
enabled BOOLEAN NOT NULL DEFAULT 0,
config TEXT NOT NULL DEFAULT '{}',
UNIQUE(channel_id, plugin_id),
FOREIGN KEY (channel_id) REFERENCES channels (id) ON DELETE CASCADE
)
`)
if err != nil {
return err
}
// Create users table with bcrypt passwords
_, err = db.Exec(`
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL UNIQUE,
password TEXT NOT NULL
)
`)
if err != nil {
return err
}
// Create default admin user with bcrypt password
hashedPassword, err := bcrypt.GenerateFromPassword([]byte("admin"), 12)
if err != nil {
return err
}
// Check if users table is empty before inserting
var count int
err = db.QueryRow("SELECT COUNT(*) FROM users").Scan(&count)
if err != nil {
return err
}
if count == 0 {
_, err = db.Exec(
"INSERT INTO users (username, password) VALUES (?, ?)",
"admin", string(hashedPassword),
)
if err != nil {
return err
}
}
return nil
}
func migrateInitialSchemaDown(db *sql.DB) error {
// Drop tables in reverse order of dependencies
_, err := db.Exec(`DROP TABLE IF EXISTS channel_plugin`)
if err != nil {
return err
}
_, err = db.Exec(`DROP TABLE IF EXISTS channels`)
if err != nil {
return err
}
_, err = db.Exec(`DROP TABLE IF EXISTS users`)
if err != nil {
return err
}
return nil
}