using IM.Admin.Api; using IM.Admin.Data; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; namespace IM.Admin.Services; public static class AdminBootstrap { public static async Task Run(IServiceProvider services, string[] args) { using var scope = services.CreateScope(); var db = scope.ServiceProvider.GetRequiredService(); if (args.Contains("--migrate")) { await db.Database.MigrateAsync(); Console.WriteLine("管理数据库迁移完成"); } if (!args.Contains("--init-admin") && !args.Contains("--reset-admin")) return; var name = Environment.GetEnvironmentVariable("IM_ADMIN_ACCOUNT")?.Trim().ToLowerInvariant() ?? throw new InvalidOperationException("IM_ADMIN_ACCOUNT is required"); var password = Environment.GetEnvironmentVariable("IM_ADMIN_PASSWORD") ?? throw new InvalidOperationException("IM_ADMIN_PASSWORD is required"); AuthEndpoints.CheckPassword(password); var a = await db.Accounts.SingleOrDefaultAsync(x => x.Account == name); if (args.Contains("--init-admin")) { if (await db.Accounts.AnyAsync()) throw new InvalidOperationException("已存在管理员,禁止重复初始化"); a = new AdminAccount { Account = name, Name = name, Role = "super", Email = Environment.GetEnvironmentVariable("IM_ADMIN_EMAIL") ?? "" }; db.Accounts.Add(a); } if (a is null) throw new InvalidOperationException("管理员不存在"); a.PasswordHash = scope.ServiceProvider.GetRequiredService>().HashPassword(a, password); a.Stamp = Guid.NewGuid().ToString("N"); a.FailedAttempts = 0; a.LockedUntil = null; db.Audit.Add(new AuditRecord { ActorId = a.Id, ActorName = "部署初始化命令", Action = "初始化或重置管理员", TargetId = a.Id.ToString(), Reason = "部署命令操作", After = "凭据已更新" }); await db.SaveChangesAsync(); Console.WriteLine("管理员凭据已更新;请清除临时密码环境变量。"); } }