seed super-admin
This commit is contained in:
parent
db0a4b7c00
commit
b8e18a52b3
|
|
@ -0,0 +1,137 @@
|
|||
using Koogle.Domain.Entities;
|
||||
using Koogle.Infrastructure.Identity;
|
||||
using KoogleApp.Data;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Koogle.Infrastructure.Security;
|
||||
|
||||
|
||||
public static class BootstrapSeeder
|
||||
{
|
||||
public static async Task SeedAsync(IServiceProvider services, IConfiguration config, IHostEnvironment env)
|
||||
{
|
||||
// Nur in Dev automatisch – Prod nur mit explizitem Flag
|
||||
var allowSeed = env.IsDevelopment() || config.GetValue<bool>("Bootstrap:EnableSeeding");
|
||||
if (!allowSeed) return;
|
||||
|
||||
using var scope = services.CreateScope();
|
||||
|
||||
var roleManager = scope.ServiceProvider.GetRequiredService<RoleManager<ApplicationRole>>();
|
||||
var userManager = scope.ServiceProvider.GetRequiredService<UserManager<ApplicationUser>>();
|
||||
var appDb = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
||||
|
||||
// 1) Rollen
|
||||
var roles = new[] { "SuperAdmin", "Admin", "Editor", "Viewer" };
|
||||
foreach (var r in roles)
|
||||
{
|
||||
if (!await roleManager.RoleExistsAsync(r))
|
||||
await roleManager.CreateAsync(new ApplicationRole { Name = r });
|
||||
}
|
||||
|
||||
// 2) SuperAdmin User (Identity)
|
||||
var adminEmail = config["Bootstrap:SuperAdmin:Email"];
|
||||
var adminUserName = config["Bootstrap:SuperAdmin:UserName"] ?? adminEmail;
|
||||
var adminPassword = config["Bootstrap:SuperAdmin:Password"];
|
||||
|
||||
if (string.IsNullOrWhiteSpace(adminEmail) || string.IsNullOrWhiteSpace(adminPassword))
|
||||
throw new InvalidOperationException("Bootstrap SuperAdmin credentials missing. Set Bootstrap:SuperAdmin:Email and :Password.");
|
||||
|
||||
var adminUser = await userManager.FindByEmailAsync(adminEmail);
|
||||
if (adminUser == null)
|
||||
{
|
||||
adminUser = new ApplicationUser
|
||||
{
|
||||
UserName = adminUserName,
|
||||
Email = adminEmail,
|
||||
EmailConfirmed = env.IsDevelopment() // Dev: praktisch, Prod: lieber false + Confirm Flow
|
||||
};
|
||||
|
||||
var createResult = await userManager.CreateAsync(adminUser, adminPassword);
|
||||
if (!createResult.Succeeded)
|
||||
throw new InvalidOperationException("Failed to create SuperAdmin: " +
|
||||
string.Join("; ", createResult.Errors.Select(e => $"{e.Code}:{e.Description}")));
|
||||
}
|
||||
|
||||
// 3) Rolle zuweisen
|
||||
if (!await userManager.IsInRoleAsync(adminUser, "SuperAdmin"))
|
||||
await userManager.AddToRoleAsync(adminUser, "SuperAdmin");
|
||||
|
||||
// 4) Domain UserProfile anlegen
|
||||
var profile = await appDb.UserProfiles.SingleOrDefaultAsync(p => p.IdentityUserId == adminUser.Id);
|
||||
if (profile == null)
|
||||
{
|
||||
profile = new UserProfile
|
||||
{
|
||||
IdentityUserId = adminUser.Id,
|
||||
DisplayName = "Super Admin",
|
||||
Locale = "de-DE",
|
||||
TimeZone = "Europe/Berlin",
|
||||
CreatedAt = DateTime.UtcNow
|
||||
};
|
||||
appDb.UserProfiles.Add(profile);
|
||||
await appDb.SaveChangesAsync();
|
||||
}
|
||||
|
||||
// Optional: Default-Club erstellen + Membership + RoleAssignments (nur wenn gewünscht)
|
||||
if (config.GetValue<bool>("Bootstrap:CreateDefaultClub"))
|
||||
{
|
||||
var clubName = config["Bootstrap:DefaultClub:Name"] ?? "Default Club";
|
||||
|
||||
var club = await appDb.Clubs.FirstOrDefaultAsync(c => c.Name == clubName);
|
||||
if (club == null)
|
||||
{
|
||||
club = new Club { Name = clubName, CreatedAt = DateTime.UtcNow };
|
||||
appDb.Clubs.Add(club);
|
||||
await appDb.SaveChangesAsync();
|
||||
}
|
||||
|
||||
// Membership (UserProfileClub) – wenn du das nutzt
|
||||
var membership = await appDb.UserProfileClubs
|
||||
.FindAsync(profile.Id, club.Id);
|
||||
|
||||
if (membership == null)
|
||||
{
|
||||
membership = new UserProfileClub
|
||||
{
|
||||
UserProfileId = profile.Id,
|
||||
ClubId = club.Id,
|
||||
IsDefault = true,
|
||||
AssignedAt = DateTime.UtcNow,
|
||||
AssignedById = adminUser.Id
|
||||
};
|
||||
appDb.UserProfileClubs.Add(membership);
|
||||
await appDb.SaveChangesAsync();
|
||||
}
|
||||
|
||||
// Club-Rollen assignments (B2): Admin/Editor/Viewer o.ä.
|
||||
// Hier: Admin im Default-Club
|
||||
var roleExists = await appDb.UserProfileClubRoleAssignments.AnyAsync(a =>
|
||||
a.UserProfileId == profile.Id && a.ClubId == club.Id && a.RoleName == "Admin" && !a.IsDeleted);
|
||||
|
||||
if (!roleExists)
|
||||
{
|
||||
appDb.UserProfileClubRoleAssignments.Add(new UserProfileClubRoleAssignment
|
||||
{
|
||||
UserProfileId = profile.Id,
|
||||
ClubId = club.Id,
|
||||
RoleId = Guid.Empty, // optional, wenn du RoleId nicht zwingend brauchst
|
||||
RoleName = "Admin",
|
||||
AssignedAt = DateTime.UtcNow,
|
||||
AssignedById = adminUser.Id,
|
||||
CreatedAt = DateTime.UtcNow
|
||||
});
|
||||
|
||||
await appDb.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -51,7 +51,7 @@ using (var scope = app.Services.CreateScope())
|
|||
{
|
||||
await IdentityRoleSeeder.SeedAsync(scope.ServiceProvider);
|
||||
}
|
||||
|
||||
await BootstrapSeeder.SeedAsync(app.Services, app.Configuration, app.Environment);
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,18 @@
|
|||
{
|
||||
|
||||
"Bootstrap": {
|
||||
"EnableSeeding": true,
|
||||
"CreateDefaultClub": true,
|
||||
"SuperAdmin": {
|
||||
"Email": "ch@koogle.de",
|
||||
"UserName": "ch@koogle.de",
|
||||
"Password": "DEV_only3000!"
|
||||
},
|
||||
"DefaultClub": {
|
||||
"Name": "Koogle Demo Club"
|
||||
}
|
||||
},
|
||||
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
|
|
|
|||
Loading…
Reference in New Issue