using AutoMapper; using Bit.Core.Entities; using Bit.Infrastructure.EntityFramework.Repositories; using Bit.Seeder.Options; using Bit.Seeder.Pipeline; using Bit.Seeder.Services; using Microsoft.AspNetCore.Identity; namespace Bit.Seeder.Recipes; /// /// Seeds an organization from an embedded preset or programmatic options. /// /// /// Thin facade over the internal Pipeline architecture (RecipeOrchestrator). /// All orchestration logic is encapsulated within the Pipeline, keeping this Recipe simple. /// The CLI remains "dumb" - it creates this recipe and calls Seed(). /// public class OrganizationRecipe( DatabaseContext db, IMapper mapper, IPasswordHasher passwordHasher, IManglerService manglerService) { private readonly RecipeOrchestrator _orchestrator = new(db, mapper); /// /// Seeds an organization from an embedded preset. /// /// Name of the embedded preset (e.g., "dunder-mifflin-full") /// Optional password for all seeded accounts /// The organization ID and summary statistics. public SeedResult Seed(string presetName, string? password = null) { var result = _orchestrator.Execute(presetName, passwordHasher, manglerService, password); return new SeedResult( result.OrganizationId, result.OwnerEmail, result.UsersCount, result.GroupsCount, result.CollectionsCount, result.CiphersCount); } /// /// Seeds an organization from programmatic options (CLI arguments). /// /// Options specifying what to seed. /// The organization ID and summary statistics. public SeedResult Seed(OrganizationVaultOptions options) { var result = _orchestrator.Execute(options, passwordHasher, manglerService); return new SeedResult( result.OrganizationId, result.OwnerEmail, result.UsersCount, result.GroupsCount, result.CollectionsCount, result.CiphersCount); } /// /// Lists all available embedded presets and fixtures. /// /// Available presets grouped by category. public static AvailableSeeds ListAvailable() { var internalResult = RecipeOrchestrator.ListAvailable(); return new AvailableSeeds(internalResult.Presets, internalResult.Fixtures); } } /// /// Result of seeding operation with summary statistics. /// public record SeedResult( Guid OrganizationId, string? OwnerEmail, int UsersCount, int GroupsCount, int CollectionsCount, int CiphersCount); /// /// Available presets and fixtures grouped by category. /// public record AvailableSeeds( IReadOnlyList Presets, IReadOnlyDictionary> Fixtures);