feat: 添加 Flyway V2 迁移,自动初始化默认管理员账号

- 首次部署自动创建 admin@par.local (trust_level=2)
- 已有账号自动提权(member→admin)
- 幂等安全,重复执行无副作用
- 使用项目 PasswordUtil 生成 bcrypt 哈希,无外部依赖
This commit is contained in:
mediabot-pt
2026-06-29 14:14:16 +08:00
parent a5279e0a69
commit d2c226c25f

View File

@@ -0,0 +1,60 @@
package com.par.core.db.migration;
import com.par.common.util.PasswordUtil;
import org.flywaydb.core.api.migration.BaseJavaMigration;
import org.flywaydb.core.api.migration.Context;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
/**
* Flyway V2 迁移:初始化默认管理员账号
* <p>
* 首次部署时自动创建管理员,已有账号则跳过(幂等)。
* 默认密码部署后应立即修改。
*/
public class V2__InitAdmin extends BaseJavaMigration {
private static final String ADMIN_EMAIL = "admin@par.local";
private static final String ADMIN_PASSWORD = "Admin@123456";
private static final String ADMIN_DISPLAY = "Administrator";
@Override
public void migrate(Context context) throws Exception {
// 幂等检查:查询管理员账号是否已存在
try (PreparedStatement check = context.getConnection().prepareStatement(
"SELECT id, trust_level FROM accounts WHERE email = ?")) {
check.setString(1, ADMIN_EMAIL);
try (ResultSet rs = check.executeQuery()) {
if (rs.next()) {
// 账号已存在,若信任等级不足则自动提权
long id = rs.getLong("id");
int level = rs.getInt("trust_level");
if (level < 2) {
try (PreparedStatement promote = context.getConnection().prepareStatement(
"UPDATE accounts SET trust_level = 2 WHERE id = ?")) {
promote.setLong(1, id);
promote.executeUpdate();
}
System.out.println("[Flyway V2] Account " + ADMIN_EMAIL + " promoted to admin");
}
return;
}
}
}
// 账号不存在,创建默认管理员
String hash = PasswordUtil.encode(ADMIN_PASSWORD);
try (PreparedStatement insert = context.getConnection().prepareStatement(
"INSERT INTO accounts (email, password_hash, display_name, trust_level, is_active) " +
"VALUES (?, ?, ?, ?, ?)")) {
insert.setString(1, ADMIN_EMAIL);
insert.setString(2, hash);
insert.setString(3, ADMIN_DISPLAY);
insert.setInt(4, 2); // trust_level: 2 = ADMIN
insert.setBoolean(5, true);
insert.executeUpdate();
}
System.out.println("[Flyway V2] Default admin created: " + ADMIN_EMAIL);
}
}