1
0
mirror of https://github.com/bitwarden/server synced 2026-02-19 02:43:38 +00:00

Add cipher seeding with Rust SDK encryption to enable cryptographically correct test data generation

This commit is contained in:
Mick Letofsky
2026-01-26 15:46:24 +01:00
parent 7fb2822e05
commit c997f87333
34 changed files with 2731 additions and 248 deletions

View File

@@ -1,4 +1,4 @@
using Bit.Infrastructure.EntityFramework.Repositories;
using Bit.Seeder.Data.Enums;
using Bit.Seeder.Recipes;
using CommandDotNet;
using Microsoft.Extensions.DependencyInjection;
@@ -13,27 +13,44 @@ public class Program
.Run(args);
}
[Command("organization", Description = "Seed an organization and organization users")]
[Command("organization", Description = "Seed an organization with users and optional ciphers")]
public void Organization(
[Option('n', "Name", Description = "Name of organization")]
[Option('n', "name", Description = "Name of organization")]
string name,
[Option('u', "users", Description = "Number of users to generate")]
int users,
[Option('d', "domain", Description = "Email domain for users")]
string domain
string domain,
[Option('c', "ciphers", Description = "Number of login ciphers to create")]
int ciphers = 0,
[Option('s', "structure", Description = "Org structure for collections: Traditional, Spotify, or Modern")]
string? structure = null
)
{
// Create service provider with necessary services
var structureModel = ParseStructureModel(structure);
var services = new ServiceCollection();
ServiceCollectionExtension.ConfigureServices(services);
var serviceProvider = services.BuildServiceProvider();
// Get a scoped DB context
using var scope = serviceProvider.CreateScope();
var scopedServices = scope.ServiceProvider;
var db = scopedServices.GetRequiredService<DatabaseContext>();
OrganizationWithUsersRecipe.SeedFromServices(scope.ServiceProvider, name, domain, users, ciphers,
structureModel: structureModel);
}
var recipe = new OrganizationWithUsersRecipe(db);
recipe.Seed(name: name, domain: domain, users: users);
private static OrgStructureModel? ParseStructureModel(string? structure)
{
if (string.IsNullOrEmpty(structure))
{
return null;
}
return structure.ToLowerInvariant() switch
{
"traditional" => OrgStructureModel.Traditional,
"spotify" => OrgStructureModel.Spotify,
"modern" => OrgStructureModel.Modern,
_ => throw new ArgumentException($"Unknown structure '{structure}'. Use: Traditional, Spotify, or Modern")
};
}
}