mirror of
https://github.com/bitwarden/server
synced 2025-12-27 05:33:17 +00:00
Add bulk default collection creation method (#6075)
This commit is contained in:
@@ -2,9 +2,11 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text.Json;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Settings;
|
||||
using Bit.Infrastructure.Dapper.AdminConsole.Helpers;
|
||||
using Dapper;
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
@@ -222,6 +224,8 @@ public class CollectionRepository : Repository<Collection, Guid>, ICollectionRep
|
||||
public async Task CreateAsync(Collection obj, IEnumerable<CollectionAccessSelection>? groups, IEnumerable<CollectionAccessSelection>? users)
|
||||
{
|
||||
obj.SetNewId();
|
||||
|
||||
|
||||
var objWithGroupsAndUsers = JsonSerializer.Deserialize<CollectionWithGroupsAndUsers>(JsonSerializer.Serialize(obj))!;
|
||||
|
||||
objWithGroupsAndUsers.Groups = groups != null ? groups.ToArrayTVP() : Enumerable.Empty<CollectionAccessSelection>().ToArrayTVP();
|
||||
@@ -322,6 +326,100 @@ public class CollectionRepository : Repository<Collection, Guid>, ICollectionRep
|
||||
}
|
||||
}
|
||||
|
||||
public async Task CreateDefaultCollectionsAsync(Guid organizationId, IEnumerable<Guid> affectedOrgUserIds, string defaultCollectionName)
|
||||
{
|
||||
if (!affectedOrgUserIds.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await using var connection = new SqlConnection(ConnectionString);
|
||||
connection.Open();
|
||||
await using var transaction = connection.BeginTransaction();
|
||||
try
|
||||
{
|
||||
var orgUserIdWithDefaultCollection = await GetOrgUserIdsWithDefaultCollectionAsync(connection, transaction, organizationId);
|
||||
|
||||
var missingDefaultCollectionUserIds = affectedOrgUserIds.Except(orgUserIdWithDefaultCollection);
|
||||
|
||||
var (collectionUsers, collections) = BuildDefaultCollectionForUsers(organizationId, missingDefaultCollectionUserIds, defaultCollectionName);
|
||||
|
||||
if (!collectionUsers.Any() || !collections.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await BulkResourceCreationService.CreateCollectionsAsync(connection, transaction, collections);
|
||||
await BulkResourceCreationService.CreateCollectionsUsersAsync(connection, transaction, collectionUsers);
|
||||
|
||||
transaction.Commit();
|
||||
}
|
||||
catch
|
||||
{
|
||||
transaction.Rollback();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<HashSet<Guid>> GetOrgUserIdsWithDefaultCollectionAsync(SqlConnection connection, SqlTransaction transaction, Guid organizationId)
|
||||
{
|
||||
const string sql = @"
|
||||
SELECT
|
||||
ou.Id AS OrganizationUserId
|
||||
FROM
|
||||
OrganizationUser ou
|
||||
INNER JOIN
|
||||
CollectionUser cu ON cu.OrganizationUserId = ou.Id
|
||||
INNER JOIN
|
||||
Collection c ON c.Id = cu.CollectionId
|
||||
WHERE
|
||||
ou.OrganizationId = @OrganizationId
|
||||
AND c.Type = @CollectionType;
|
||||
";
|
||||
|
||||
var organizationUserIds = await connection.QueryAsync<Guid>(
|
||||
sql,
|
||||
new { OrganizationId = organizationId, CollectionType = CollectionType.DefaultUserCollection },
|
||||
transaction: transaction
|
||||
);
|
||||
|
||||
return organizationUserIds.ToHashSet();
|
||||
}
|
||||
|
||||
private (List<CollectionUser> collectionUser, List<Collection> collection) BuildDefaultCollectionForUsers(Guid organizationId, IEnumerable<Guid> missingDefaultCollectionUserIds, string defaultCollectionName)
|
||||
{
|
||||
var collectionUsers = new List<CollectionUser>();
|
||||
var collections = new List<Collection>();
|
||||
|
||||
foreach (var orgUserId in missingDefaultCollectionUserIds)
|
||||
{
|
||||
var collectionId = Guid.NewGuid();
|
||||
|
||||
collections.Add(new Collection
|
||||
{
|
||||
Id = collectionId,
|
||||
OrganizationId = organizationId,
|
||||
Name = defaultCollectionName,
|
||||
CreationDate = DateTime.UtcNow,
|
||||
RevisionDate = DateTime.UtcNow,
|
||||
Type = CollectionType.DefaultUserCollection,
|
||||
DefaultUserCollectionEmail = null
|
||||
|
||||
});
|
||||
|
||||
collectionUsers.Add(new CollectionUser
|
||||
{
|
||||
CollectionId = collectionId,
|
||||
OrganizationUserId = orgUserId,
|
||||
ReadOnly = false,
|
||||
HidePasswords = false,
|
||||
Manage = true,
|
||||
});
|
||||
}
|
||||
|
||||
return (collectionUsers, collections);
|
||||
}
|
||||
|
||||
public class CollectionWithGroupsAndUsers : Collection
|
||||
{
|
||||
[DisallowNull]
|
||||
|
||||
Reference in New Issue
Block a user