using Bit.Core.Vault.Entities;
using Bit.Core.Vault.Enums;
using Bit.Seeder.Data.Distributions;
using Bit.Seeder.Data.Enums;
using Bit.Seeder.Data.Static;
using Bit.Seeder.Factories;
using Bit.Seeder.Pipeline;
namespace Bit.Seeder.Steps;
///
/// Creates N personal cipher entities per user, encrypted with each user's symmetric key.
///
///
/// Iterates over and creates ciphers with
/// UserId set and OrganizationId null. Personal ciphers are not assigned
/// to collections.
///
internal sealed class GeneratePersonalCiphersStep(
int countPerUser,
Distribution? typeDist = null,
Distribution? pwDist = null) : IStep
{
public void Execute(SeederContext context)
{
if (countPerUser == 0)
{
return;
}
var generator = context.RequireGenerator();
var userDigests = context.Registry.UserDigests;
var typeDistribution = typeDist ?? CipherTypeDistributions.Realistic;
var passwordDistribution = pwDist ?? PasswordDistributions.Realistic;
var companies = Companies.All;
var ciphers = new List(userDigests.Count * countPerUser);
var cipherIds = new List(userDigests.Count * countPerUser);
var globalIndex = 0;
foreach (var userDigest in userDigests)
{
for (var i = 0; i < countPerUser; i++)
{
var cipherType = typeDistribution.Select(globalIndex, userDigests.Count * countPerUser);
var cipher = CipherComposer.Compose(globalIndex, cipherType, userDigest.SymmetricKey, companies, generator, passwordDistribution, userId: userDigest.UserId);
CipherComposer.AssignFolder(cipher, userDigest.UserId, i, context.Registry.UserFolderIds);
ciphers.Add(cipher);
cipherIds.Add(cipher.Id);
globalIndex++;
}
}
context.Ciphers.AddRange(ciphers);
context.Registry.CipherIds.AddRange(cipherIds);
}
}