use sea_orm_migration::prelude::*; use sea_orm_migration::sea_orm::DatabaseBackend; use argon2::{Argon2, password_hash::{SaltString, PasswordHasher}}; #[derive(DeriveMigrationName)] pub struct Migration; #[async_trait::async_trait] impl MigrationTrait for Migration { async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { manager .create_table( Table::create() .table(Users::Table) .if_not_exists() .col(ColumnDef::new(Users::Id).big_integer().not_null().auto_increment().primary_key()) .col(ColumnDef::new(Users::Username).string().not_null().unique_key()) .col(ColumnDef::new(Users::PasswordHash).string().not_null()) .col(ColumnDef::new(Users::Nickname).string().null()) .col(ColumnDef::new(Users::Status).integer().not_null().default(1)) .col(ColumnDef::new(Users::CreatedAt).timestamp().not_null().default(Expr::current_timestamp())) .col(ColumnDef::new(Users::UpdatedAt).timestamp().not_null().default(Expr::current_timestamp())) .to_owned() ) .await?; // seed admin user (cross-DB) let salt = SaltString::generate(&mut rand::thread_rng()); let hash = Argon2::default().hash_password("Admin@123".as_bytes(), &salt).unwrap().to_string(); let backend = manager.get_database_backend(); let conn = manager.get_connection(); match backend { DatabaseBackend::MySql => { conn.execute_unprepared(&format!( "INSERT INTO users (username, password_hash, nickname, status) VALUES ('admin', '{}', 'Administrator', 1) ON DUPLICATE KEY UPDATE username=username", hash )) .await?; } DatabaseBackend::Postgres => { conn.execute_unprepared(&format!( "INSERT INTO users (username, password_hash, nickname, status) VALUES ('admin', '{}', 'Administrator', 1) ON CONFLICT (username) DO NOTHING", hash )) .await?; } DatabaseBackend::Sqlite => { conn.execute_unprepared(&format!( "INSERT OR IGNORE INTO users (username, password_hash, nickname, status) VALUES ('admin', '{}', 'Administrator', 1)", hash )) .await?; } } Ok(()) } async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { manager.drop_table(Table::drop().table(Users::Table).to_owned()).await } } #[derive(Iden)] enum Users { Table, Id, Username, PasswordHash, Nickname, Status, CreatedAt, UpdatedAt }