mirror of
https://github.com/bitwarden/server.git
synced 2026-01-31 14:13:18 +08:00
Refactor to correctly implement statics and remove hardcoded organization keys (#6924)
This commit is contained in:
@@ -22,8 +22,6 @@ namespace Bit.Seeder.Factories;
|
||||
/// </remarks>
|
||||
public class CipherSeeder
|
||||
{
|
||||
private readonly RustSdkService _sdkService;
|
||||
|
||||
private static readonly JsonSerializerOptions SdkJsonOptions = new()
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
@@ -36,12 +34,7 @@ public class CipherSeeder
|
||||
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
|
||||
};
|
||||
|
||||
public CipherSeeder(RustSdkService sdkService)
|
||||
{
|
||||
_sdkService = sdkService;
|
||||
}
|
||||
|
||||
public Cipher CreateOrganizationLoginCipher(
|
||||
public static Cipher CreateOrganizationLoginCipher(
|
||||
Guid organizationId,
|
||||
string orgKeyBase64,
|
||||
string name,
|
||||
@@ -67,7 +60,7 @@ public class CipherSeeder
|
||||
return EncryptAndTransform(cipherView, orgKeyBase64, organizationId);
|
||||
}
|
||||
|
||||
public Cipher CreateOrganizationLoginCipherWithFields(
|
||||
public static Cipher CreateOrganizationLoginCipherWithFields(
|
||||
Guid organizationId,
|
||||
string orgKeyBase64,
|
||||
string name,
|
||||
@@ -98,10 +91,10 @@ public class CipherSeeder
|
||||
return EncryptAndTransform(cipherView, orgKeyBase64, organizationId);
|
||||
}
|
||||
|
||||
private Cipher EncryptAndTransform(CipherViewDto cipherView, string keyBase64, Guid organizationId)
|
||||
private static Cipher EncryptAndTransform(CipherViewDto cipherView, string keyBase64, Guid organizationId)
|
||||
{
|
||||
var viewJson = JsonSerializer.Serialize(cipherView, SdkJsonOptions);
|
||||
var encryptedJson = _sdkService.EncryptCipher(viewJson, keyBase64);
|
||||
var encryptedJson = RustSdkService.EncryptCipher(viewJson, keyBase64);
|
||||
|
||||
var encryptedDto = JsonSerializer.Deserialize<EncryptedCipherDto>(encryptedJson, SdkJsonOptions)
|
||||
?? throw new InvalidOperationException("Failed to parse encrypted cipher");
|
||||
|
||||
@@ -3,15 +3,15 @@ using Bit.RustSDK;
|
||||
|
||||
namespace Bit.Seeder.Factories;
|
||||
|
||||
public class CollectionSeeder(RustSdkService sdkService)
|
||||
public class CollectionSeeder
|
||||
{
|
||||
public Collection CreateCollection(Guid organizationId, string orgKey, string name)
|
||||
public static Collection CreateCollection(Guid organizationId, string orgKey, string name)
|
||||
{
|
||||
return new Collection
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
OrganizationId = organizationId,
|
||||
Name = sdkService.EncryptString(name, orgKey),
|
||||
Name = RustSdkService.EncryptString(name, orgKey),
|
||||
CreationDate = DateTime.UtcNow,
|
||||
RevisionDate = DateTime.UtcNow
|
||||
};
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Bit.Seeder.Factories;
|
||||
/// Factory for creating Folder entities with encrypted names.
|
||||
/// Folders are per-user constructs encrypted with the user's symmetric key.
|
||||
/// </summary>
|
||||
internal sealed class FolderSeeder(RustSdkService sdkService)
|
||||
internal sealed class FolderSeeder
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a folder with an encrypted name.
|
||||
@@ -16,13 +16,13 @@ internal sealed class FolderSeeder(RustSdkService sdkService)
|
||||
/// <param name="userId">The user who owns this folder.</param>
|
||||
/// <param name="userKeyBase64">The user's symmetric key (not org key).</param>
|
||||
/// <param name="name">The plaintext folder name to encrypt.</param>
|
||||
public Folder CreateFolder(Guid userId, string userKeyBase64, string name)
|
||||
public static Folder CreateFolder(Guid userId, string userKeyBase64, string name)
|
||||
{
|
||||
return new Folder
|
||||
{
|
||||
Id = CoreHelpers.GenerateComb(),
|
||||
UserId = userId,
|
||||
Name = sdkService.EncryptString(name, userKeyBase64)
|
||||
Name = RustSdkService.EncryptString(name, userKeyBase64)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,9 +7,6 @@ namespace Bit.Seeder.Factories;
|
||||
|
||||
public class OrganizationSeeder
|
||||
{
|
||||
private static readonly string _defaultPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmIJbGMk6eZqVE7UxhZ46Weu2jKciqOiOkSVYtGvs61rfe9AXxtLaaZEKN4d4DmkZcF6dna2eXNxZmb7U4pwlttye8ksqISe6IUAZQox7auBpjopdCEPhKRg3BD/u8ks9UxSxgWe+fpebjt6gd5hsl1/5HOObn7SeU6EEU04cp3/eH7a4OTdXxB8oN62HGV9kM/ubM1goILgjoSJDbihMK0eb7b8hPHwcA/YOgKKiu/N3FighccdSMD5Pk+HfjacsFNZQa2EsqW09IvvSZ+iL6HQeZ1vwc/6TO1J7EOfJZFQcjoEL9LVI693efYoMZSmrPEWziZ4PvwpOOGo6OObyMQIDAQAB";
|
||||
private static readonly string _defaultPrivateKey = "2.6FggyKVyaKQsfohi5yqgbg==|UU2JeafOB41L5UscGmf4kq15JGDf3Bkf67KECiehTODzbWctVLTgyDk0Qco8/6CMN6nZGXjxR2A4r5ExhmwRNsNxd77G+MprkmiJz+7w33ROZ1ouQO5XjD3wbQ3ssqNiTKId6yAUPBvuAZRixVApauTuADc8QWGixqCQcqZzmU7YSBBIPf652/AEYr4Tk64YihoE39pHiK8MRbTLdRt3EF4LSMugPAPM24vCgUv3w1TD3Fj6sDg/6oi3flOV9SJZX4vCiUXbDNEuD/p2aQrEXVbaxweFOHjTe7F4iawjXw3nG3SO8rUBHcxbhDDVx5rjYactbW5QvHWiyla6uLb6o8WHBneg2EjTEwAHOZE/rBjcqmAJb2sVp1E0Kwq8ycGmL69vmqJPC1GqVTohAQvmEkaxIPpfq24Yb9ZPrADA7iEXBKuAQ1FphFUVgJBJGJbd60sOV1Rz1T+gUwS4wCNQ4l3LG1S22+wzUVlEku5DXFnT932tatqTyWEthqPqLCt6dL1+qa94XLpeHagXAx2VGe8n8IlcADtxqS+l8xQ4heT12WO9kC316vqvg1mnsI56faup9hb3eT9ZpKyxSBGYOphlTWfV1Y/v64f5PYvTo4aL0IYHyLY/9Qi72vFmOpPeHBYgD5t3j+H2CsiU1PkYsBggOmD7xW8FDuT6HWVvwhEJqeibVPK0Lhyj6tgvlSIAvFUaSMFPlmwFNmwfj/AHUhr9KuTfsBFTZ10yy9TZVgf+EofwnrxHBaWUgdD40aHoY1VjfG33iEuajb6buxG3pYFyPNhJNzeLZisUKIDRMQpUHrsE22EyrFFran3tZGdtcyIEK4Q1F0ULYzJ6T9iY25/ZgPy3pEAAMZCtqo3s+GjX295fWIHfMcnjMgNUHPjExjWBHa+ggK9iQXkFpBVyYB1ga/+0eiIhiek3PlgtvpDrqF7TsLK+ROiBw2GJ7uaO3EEXOj2GpNBuEJ5CdodhZkwzhwMcSatgDHkUuNVu0iVbF6/MxVdOxWXKO+jCYM6PZk/vAhLYqpPzu2T2Uyz4nkDs2Tiq61ez6FoCrzdHIiyIxVTzUQH8G9FgSmtaZ7GCbqlhnurYgcMciwPzxg0hpAQT+NZw1tVEii9vFSpJJbGJqNhORKfKh/Mu1P/9LOQq7Y0P2FIR3x/eUVEQ7CGv2jVtO5ryGSmKeq/P9Fr54wTPaNiqN2K+leACUznCdUWw8kZo/AsBcrOe4OkRX6k8LC3oeJXy06DEToatxEvPYemUauhxiXRw8nfNMqc4LyJq2bbT0zCgJHoqpozPdNg6AYWcoIobgAGu7ZQGq+oE1MT3GZxotMPe/NUJiAc5YE9Thb5Yf3gyno71pyqPTVl/6IQuh4SUz7rkgwF/aVHEnr4aUYNoc0PEzd2Me0jElsA3GAneq1I/wngutOWgTViTK4Nptr5uIzMVQs9H1rOMJNorP8b02t1NDu010rSsib9GaaJJq4r4iy46laQOxWoU0ex26arYnk+jw4833WSCTVBIprTgizZ+fKjoY0xwXvI2oOvGNEUCtGFvKFORTaQrlaXZIg1toa2BBVNicyONbwnI3KIu3MgGJ2SlCVXJn8oHFppVHFCdwgN1uDzGiKAhjvr0sZTUtXin2f2CszPTbbo=|fUhbVKrr8CSKE7TZJneXpDGraj5YhRrq9ESo206S+BY=";
|
||||
|
||||
public static Organization CreateEnterprise(string name, string domain, int seats, string? publicKey = null, string? privateKey = null)
|
||||
{
|
||||
return new Organization
|
||||
@@ -43,36 +40,14 @@ public class OrganizationSeeder
|
||||
SyncSeats = true,
|
||||
Status = OrganizationStatusType.Created,
|
||||
MaxStorageGb = 10,
|
||||
PublicKey = publicKey ?? _defaultPublicKey,
|
||||
PrivateKey = privateKey ?? _defaultPrivateKey,
|
||||
PublicKey = publicKey,
|
||||
PrivateKey = privateKey
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static class OrganizationExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an OrganizationUser with fields populated based on status.
|
||||
/// For Invited status, only user.Email is used. For other statuses, user.Id is used.
|
||||
/// </summary>
|
||||
public static OrganizationUser CreateOrganizationUser(
|
||||
this Organization organization, User user, OrganizationUserType type, OrganizationUserStatusType status)
|
||||
{
|
||||
var isInvited = status == OrganizationUserStatusType.Invited;
|
||||
var isConfirmed = status == OrganizationUserStatusType.Confirmed || status == OrganizationUserStatusType.Revoked;
|
||||
|
||||
return new OrganizationUser
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
OrganizationId = organization.Id,
|
||||
UserId = isInvited ? null : user.Id,
|
||||
Email = isInvited ? user.Email : null,
|
||||
Key = isConfirmed ? "4.rY01mZFXHOsBAg5Fq4gyXuklWfm6mQASm42DJpx05a+e2mmp+P5W6r54WU2hlREX0uoTxyP91bKKwickSPdCQQ58J45LXHdr9t2uzOYyjVzpzebFcdMw1eElR9W2DW8wEk9+mvtWvKwu7yTebzND+46y1nRMoFydi5zPVLSlJEf81qZZ4Uh1UUMLwXz+NRWfixnGXgq2wRq1bH0n3mqDhayiG4LJKgGdDjWXC8W8MMXDYx24SIJrJu9KiNEMprJE+XVF9nQVNijNAjlWBqkDpsfaWTUfeVLRLctfAqW1blsmIv4RQ91PupYJZDNc8nO9ZTF3TEVM+2KHoxzDJrLs2Q==" : null,
|
||||
Type = type,
|
||||
Status = status
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an OrganizationUser with a dynamically provided encrypted org key.
|
||||
/// The encryptedOrgKey should be generated using sdkService.GenerateUserOrganizationKey().
|
||||
|
||||
@@ -11,7 +11,7 @@ public struct UserData
|
||||
public string Email;
|
||||
}
|
||||
|
||||
public class UserSeeder(RustSdkService sdkService, IPasswordHasher<Bit.Core.Entities.User> passwordHasher, MangleId mangleId)
|
||||
public class UserSeeder(IPasswordHasher<Bit.Core.Entities.User> passwordHasher, MangleId mangleId)
|
||||
{
|
||||
private string MangleEmail(string email)
|
||||
{
|
||||
@@ -21,7 +21,7 @@ public class UserSeeder(RustSdkService sdkService, IPasswordHasher<Bit.Core.Enti
|
||||
public User CreateUser(string email, bool emailVerified = false, bool premium = false)
|
||||
{
|
||||
email = MangleEmail(email);
|
||||
var keys = sdkService.GenerateUserKeys(email, DefaultPassword);
|
||||
var keys = RustSdkService.GenerateUserKeys(email, DefaultPassword);
|
||||
|
||||
var user = new User
|
||||
{
|
||||
@@ -76,10 +76,9 @@ public class UserSeeder(RustSdkService sdkService, IPasswordHasher<Bit.Core.Enti
|
||||
/// </summary>
|
||||
public static User CreateUserWithSdkKeys(
|
||||
string email,
|
||||
RustSdkService sdkService,
|
||||
IPasswordHasher<User> passwordHasher)
|
||||
{
|
||||
var keys = sdkService.GenerateUserKeys(email, DefaultPassword);
|
||||
var keys = RustSdkService.GenerateUserKeys(email, DefaultPassword);
|
||||
return CreateUserFromKeys(email, keys, passwordHasher);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ public class CollectionsRecipe(DatabaseContext db)
|
||||
/// <param name="collections">The number of collections to add.</param>
|
||||
/// <param name="organizationUserIds">The IDs of the users to create relationships with.</param>
|
||||
/// <param name="maxUsersWithRelationships">The maximum number of users to create relationships with.</param>
|
||||
public List<Guid> AddToOrganization(Guid organizationId, int collections, List<Guid> organizationUserIds, int maxUsersWithRelationships = 1000)
|
||||
public List<Guid> Seed(Guid organizationId, int collections, List<Guid> organizationUserIds, int maxUsersWithRelationships = 1000)
|
||||
{
|
||||
var collectionList = CreateAndSaveCollections(organizationId, collections);
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ public class GroupsRecipe(DatabaseContext db)
|
||||
/// <param name="groups">The number of groups to add.</param>
|
||||
/// <param name="organizationUserIds">The IDs of the users to create relationships with.</param>
|
||||
/// <param name="maxUsersWithRelationships">The maximum number of users to create relationships with.</param>
|
||||
public List<Guid> AddToOrganization(Guid organizationId, int groups, List<Guid> organizationUserIds, int maxUsersWithRelationships = 1000)
|
||||
public List<Guid> Seed(Guid organizationId, int groups, List<Guid> organizationUserIds, int maxUsersWithRelationships = 1000)
|
||||
{
|
||||
var groupList = CreateAndSaveGroups(organizationId, groups);
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Bit.Seeder.Recipes;
|
||||
|
||||
public class OrganizationDomainRecipe(DatabaseContext db)
|
||||
{
|
||||
public void AddVerifiedDomainToOrganization(Guid organizationId, string domainName)
|
||||
public void Seed(Guid organizationId, string domainName)
|
||||
{
|
||||
var domain = new OrganizationDomain
|
||||
{
|
||||
|
||||
@@ -1,39 +1,66 @@
|
||||
using Bit.Core.Entities;
|
||||
using AutoMapper;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Infrastructure.EntityFramework.Repositories;
|
||||
using Bit.RustSDK;
|
||||
using Bit.Seeder.Factories;
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using EfOrganization = Bit.Infrastructure.EntityFramework.AdminConsole.Models.Organization;
|
||||
using EfOrganizationUser = Bit.Infrastructure.EntityFramework.Models.OrganizationUser;
|
||||
using EfUser = Bit.Infrastructure.EntityFramework.Models.User;
|
||||
|
||||
namespace Bit.Seeder.Recipes;
|
||||
|
||||
public class OrganizationWithUsersRecipe(DatabaseContext db)
|
||||
public class OrganizationWithUsersRecipe(DatabaseContext db, IMapper mapper, IPasswordHasher<User> passwordHasher)
|
||||
{
|
||||
public Guid Seed(string name, string domain, int users, OrganizationUserStatusType usersStatus = OrganizationUserStatusType.Confirmed)
|
||||
{
|
||||
var seats = Math.Max(users + 1, 1000);
|
||||
var organization = OrganizationSeeder.CreateEnterprise(name, domain, seats);
|
||||
var ownerUser = UserSeeder.CreateUserNoMangle($"owner@{domain}");
|
||||
var ownerOrgUser = organization.CreateOrganizationUser(ownerUser, OrganizationUserType.Owner, OrganizationUserStatusType.Confirmed);
|
||||
|
||||
// Generate organization keys
|
||||
var orgKeys = RustSdkService.GenerateOrganizationKeys();
|
||||
var organization = OrganizationSeeder.CreateEnterprise(
|
||||
name, domain, seats, orgKeys.PublicKey, orgKeys.PrivateKey);
|
||||
|
||||
// Create owner with SDK-generated keys
|
||||
var ownerUser = UserSeeder.CreateUserWithSdkKeys($"owner@{domain}", passwordHasher);
|
||||
var ownerOrgKey = RustSdkService.GenerateUserOrganizationKey(ownerUser.PublicKey!, orgKeys.Key);
|
||||
var ownerOrgUser = organization.CreateOrganizationUserWithKey(
|
||||
ownerUser, OrganizationUserType.Owner, OrganizationUserStatusType.Confirmed, ownerOrgKey);
|
||||
|
||||
var additionalUsers = new List<User>();
|
||||
var additionalOrgUsers = new List<OrganizationUser>();
|
||||
for (var i = 0; i < users; i++)
|
||||
{
|
||||
var additionalUser = UserSeeder.CreateUserNoMangle($"user{i}@{domain}");
|
||||
var additionalUser = UserSeeder.CreateUserWithSdkKeys($"user{i}@{domain}", passwordHasher);
|
||||
additionalUsers.Add(additionalUser);
|
||||
additionalOrgUsers.Add(organization.CreateOrganizationUser(additionalUser, OrganizationUserType.User, usersStatus));
|
||||
|
||||
// Generate org key for confirmed/revoked users
|
||||
var shouldHaveKey = usersStatus == OrganizationUserStatusType.Confirmed
|
||||
|| usersStatus == OrganizationUserStatusType.Revoked;
|
||||
var userOrgKey = shouldHaveKey
|
||||
? RustSdkService.GenerateUserOrganizationKey(additionalUser.PublicKey!, orgKeys.Key)
|
||||
: null;
|
||||
|
||||
additionalOrgUsers.Add(organization.CreateOrganizationUserWithKey(
|
||||
additionalUser, OrganizationUserType.User, usersStatus, userOrgKey));
|
||||
}
|
||||
|
||||
db.Add(organization);
|
||||
db.Add(ownerUser);
|
||||
db.Add(ownerOrgUser);
|
||||
// Map Core entities to EF entities before adding to DbContext
|
||||
db.Add(mapper.Map<EfOrganization>(organization));
|
||||
db.Add(mapper.Map<EfUser>(ownerUser));
|
||||
db.Add(mapper.Map<EfOrganizationUser>(ownerOrgUser));
|
||||
|
||||
// Map and BulkCopy additional users
|
||||
var efAdditionalUsers = additionalUsers.Select(u => mapper.Map<EfUser>(u)).ToList();
|
||||
var efAdditionalOrgUsers = additionalOrgUsers.Select(ou => mapper.Map<EfOrganizationUser>(ou)).ToList();
|
||||
|
||||
db.BulkCopy(efAdditionalUsers);
|
||||
db.BulkCopy(efAdditionalOrgUsers);
|
||||
|
||||
db.SaveChanges();
|
||||
|
||||
// Use LinqToDB's BulkCopy for significant better performance
|
||||
db.BulkCopy(additionalUsers);
|
||||
db.BulkCopy(additionalOrgUsers);
|
||||
|
||||
return organization.Id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,12 +27,8 @@ namespace Bit.Seeder.Recipes;
|
||||
public class OrganizationWithVaultRecipe(
|
||||
DatabaseContext db,
|
||||
IMapper mapper,
|
||||
RustSdkService sdkService,
|
||||
IPasswordHasher<User> passwordHasher)
|
||||
{
|
||||
private readonly CollectionSeeder _collectionSeeder = new(sdkService);
|
||||
private readonly CipherSeeder _cipherSeeder = new(sdkService);
|
||||
private readonly FolderSeeder _folderSeeder = new(sdkService);
|
||||
|
||||
/// <summary>
|
||||
/// Tracks a user with their symmetric key for folder encryption.
|
||||
@@ -47,15 +43,15 @@ public class OrganizationWithVaultRecipe(
|
||||
public Guid Seed(OrganizationVaultOptions options)
|
||||
{
|
||||
var seats = Math.Max(options.Users + 1, 1000);
|
||||
var orgKeys = sdkService.GenerateOrganizationKeys();
|
||||
var orgKeys = RustSdkService.GenerateOrganizationKeys();
|
||||
|
||||
// Create organization via factory
|
||||
var organization = OrganizationSeeder.CreateEnterprise(
|
||||
options.Name, options.Domain, seats, orgKeys.PublicKey, orgKeys.PrivateKey);
|
||||
|
||||
// Create owner user via factory
|
||||
var ownerUser = UserSeeder.CreateUserWithSdkKeys($"owner@{options.Domain}", sdkService, passwordHasher);
|
||||
var ownerOrgKey = sdkService.GenerateUserOrganizationKey(ownerUser.PublicKey!, orgKeys.Key);
|
||||
var ownerUser = UserSeeder.CreateUserWithSdkKeys($"owner@{options.Domain}", passwordHasher);
|
||||
var ownerOrgKey = RustSdkService.GenerateUserOrganizationKey(ownerUser.PublicKey!, orgKeys.Key);
|
||||
var ownerOrgUser = organization.CreateOrganizationUserWithKey(
|
||||
ownerUser, OrganizationUserType.Owner, OrganizationUserStatusType.Confirmed, ownerOrgKey);
|
||||
|
||||
@@ -67,7 +63,7 @@ public class OrganizationWithVaultRecipe(
|
||||
for (var i = 0; i < options.Users; i++)
|
||||
{
|
||||
var email = $"user{i}@{options.Domain}";
|
||||
var userKeys = sdkService.GenerateUserKeys(email, UserSeeder.DefaultPassword);
|
||||
var userKeys = RustSdkService.GenerateUserKeys(email, UserSeeder.DefaultPassword);
|
||||
var memberUser = UserSeeder.CreateUserFromKeys(email, userKeys, passwordHasher);
|
||||
memberUsersWithKeys.Add(new UserWithKey(memberUser, userKeys.Key));
|
||||
|
||||
@@ -77,7 +73,7 @@ public class OrganizationWithVaultRecipe(
|
||||
|
||||
var memberOrgKey = (status == OrganizationUserStatusType.Confirmed ||
|
||||
status == OrganizationUserStatusType.Revoked)
|
||||
? sdkService.GenerateUserOrganizationKey(memberUser.PublicKey!, orgKeys.Key)
|
||||
? RustSdkService.GenerateUserOrganizationKey(memberUser.PublicKey!, orgKeys.Key)
|
||||
: null;
|
||||
|
||||
memberOrgUsers.Add(organization.CreateOrganizationUserWithKey(
|
||||
@@ -124,12 +120,12 @@ public class OrganizationWithVaultRecipe(
|
||||
{
|
||||
var structure = OrgStructures.GetStructure(structureModel.Value);
|
||||
collections = structure.Units
|
||||
.Select(unit => _collectionSeeder.CreateCollection(organizationId, orgKeyBase64, unit.Name))
|
||||
.Select(unit => CollectionSeeder.CreateCollection(organizationId, orgKeyBase64, unit.Name))
|
||||
.ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
collections = [_collectionSeeder.CreateCollection(organizationId, orgKeyBase64, "Default Collection")];
|
||||
collections = [CollectionSeeder.CreateCollection(organizationId, orgKeyBase64, "Default Collection")];
|
||||
}
|
||||
|
||||
db.BulkCopy(collections);
|
||||
@@ -191,7 +187,7 @@ public class OrganizationWithVaultRecipe(
|
||||
.Select(i =>
|
||||
{
|
||||
var company = companies[i % companies.Length];
|
||||
return _cipherSeeder.CreateOrganizationLoginCipher(
|
||||
return CipherSeeder.CreateOrganizationLoginCipher(
|
||||
organizationId,
|
||||
orgKeyBase64,
|
||||
name: $"{company.Name} ({company.Category})",
|
||||
@@ -285,7 +281,7 @@ public class OrganizationWithVaultRecipe(
|
||||
{
|
||||
var folderCount = GetFolderCountForUser(userIndex, usersWithKeys.Count, random);
|
||||
return Enumerable.Range(0, folderCount)
|
||||
.Select(folderIndex => _folderSeeder.CreateFolder(
|
||||
.Select(folderIndex => FolderSeeder.CreateFolder(
|
||||
uwk.User.Id,
|
||||
uwk.SymmetricKey,
|
||||
folderNameGenerator.GetFolderName(userIndex * 15 + folderIndex)));
|
||||
|
||||
Reference in New Issue
Block a user