From f61d8bc178ca9833f81f19dba47a9ef2adfe2ea7 Mon Sep 17 00:00:00 2001 From: nurdotnet <278048682+nurdotnet@users.noreply.github.com> Date: Tue, 28 Apr 2026 10:12:54 +0500 Subject: [PATCH] =?UTF-8?q?fix(auth):=20SuperAdmin=20=D0=BF=D0=BB=D0=B0?= =?UTF-8?q?=D1=82=D1=84=D0=BE=D1=80=D0=BC=D1=8B=20=D0=B1=D0=B5=D0=B7=20Org?= =?UTF-8?q?anizationId=20+=20=D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD?= =?UTF-8?q?=D1=8B=D0=B9=20Admin=20=D0=B4=D0=BB=D1=8F=20Demo=20Market?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit admin@food-market.local → SuperAdmin (OrganizationId=null, видит все орги) admin@demo-market.local → Admin Demo Market (новый, для тестов орг-уровня) Idempotent-фикс для существующих БД: исправляет роль и чистит OrganizationId. Co-Authored-By: Claude Sonnet 4.6 --- src/food-market.api/Seed/DevDataSeeder.cs | 67 ++++++++++++++++------- 1 file changed, 47 insertions(+), 20 deletions(-) diff --git a/src/food-market.api/Seed/DevDataSeeder.cs b/src/food-market.api/Seed/DevDataSeeder.cs index 0bdfe89..403c262 100644 --- a/src/food-market.api/Seed/DevDataSeeder.cs +++ b/src/food-market.api/Seed/DevDataSeeder.cs @@ -63,36 +63,63 @@ public async Task StartAsync(CancellationToken ct) await SeedTenantReferencesAsync(db, demoOrg.Id, ct); - const string adminEmail = "admin@food-market.local"; - var admin = await userMgr.FindByEmailAsync(adminEmail); - if (admin is null) + // SuperAdmin платформы — без OrganizationId, видит все организации + const string superAdminEmail = "admin@food-market.local"; + var superAdmin = await userMgr.FindByEmailAsync(superAdminEmail); + if (superAdmin is null) { - admin = new User + superAdmin = new User { - UserName = adminEmail, - Email = adminEmail, + UserName = superAdminEmail, + Email = superAdminEmail, EmailConfirmed = true, - FullName = "System Admin", - OrganizationId = demoOrg.Id, + FullName = "Platform SuperAdmin", + OrganizationId = null, }; - var result = await userMgr.CreateAsync(admin, "Admin12345!"); + var result = await userMgr.CreateAsync(superAdmin, "Admin12345!"); if (result.Succeeded) - { - // Только SuperAdmin как Identity-роль. «Администратор» — - // организационная роль внутри Employee, не Identity. - await userMgr.AddToRoleAsync(admin, SystemRoles.SuperAdmin); - } + await userMgr.AddToRoleAsync(superAdmin, SystemRoles.SuperAdmin); } else { - if (!await userMgr.IsInRoleAsync(admin, SystemRoles.SuperAdmin)) - await userMgr.AddToRoleAsync(admin, SystemRoles.SuperAdmin); - // Чистим дублирующую Identity-роль Admin (если оставалась с прошлых сидов). - if (await userMgr.IsInRoleAsync(admin, SystemRoles.Admin)) - await userMgr.RemoveFromRoleAsync(admin, SystemRoles.Admin); + // Исправляем старую БД: убираем OrganizationId и пересаживаем на SuperAdmin + if (superAdmin.OrganizationId is not null) + { + superAdmin.OrganizationId = null; + await userMgr.UpdateAsync(superAdmin); + } + var roles = await userMgr.GetRolesAsync(superAdmin); + if (!roles.Contains(SystemRoles.SuperAdmin)) + { + await userMgr.RemoveFromRolesAsync(superAdmin, roles); + await userMgr.AddToRoleAsync(superAdmin, SystemRoles.SuperAdmin); + } } - await SeedAdminEmployeeAsync(db, demoOrg.Id, admin?.Id, ct); + // Admin демо-организации — владелец/директор Demo Market + const string demoAdminEmail = "admin@demo-market.local"; + var demoAdmin = await userMgr.FindByEmailAsync(demoAdminEmail); + if (demoAdmin is null) + { + demoAdmin = new User + { + UserName = demoAdminEmail, + Email = demoAdminEmail, + EmailConfirmed = true, + FullName = "Demo Market Admin", + OrganizationId = demoOrg.Id, + }; + var result = await userMgr.CreateAsync(demoAdmin, "Admin12345!"); + if (result.Succeeded) + await userMgr.AddToRoleAsync(demoAdmin, SystemRoles.Admin); + } + else + { + if (!await userMgr.IsInRoleAsync(demoAdmin, SystemRoles.Admin)) + await userMgr.AddToRoleAsync(demoAdmin, SystemRoles.Admin); + } + + await SeedAdminEmployeeAsync(db, demoOrg.Id, superAdmin?.Id, ct); // Глобальные SystemSettings — single-row. Сидируем дефолт 30 дней // retention если ещё нет записи.