From 23034681cc0da03719ef357b865e8a24cf2dc105 Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Thu, 29 Jan 2026 17:01:45 +0000 Subject: [PATCH] Add BuildCreateDefaultCollectionAction method to ICollectionRepository and implementations in CollectionRepository classes - Introduced a new method in ICollectionRepository to build an action for creating a default collection with user access. - Implemented the method in both Dapper and Entity Framework CollectionRepository classes to handle collection creation and user access assignments. - Enhanced the functionality to support transaction execution for database operations. --- .../Repositories/ICollectionRepository.cs | 8 ++++++ .../Repositories/CollectionRepository.cs | 18 ++++++++++++ .../Repositories/CollectionRepository.cs | 28 +++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/src/Core/Repositories/ICollectionRepository.cs b/src/Core/Repositories/ICollectionRepository.cs index 3f3b71d2d5..427684af5c 100644 --- a/src/Core/Repositories/ICollectionRepository.cs +++ b/src/Core/Repositories/ICollectionRepository.cs @@ -1,5 +1,6 @@ using Bit.Core.Entities; using Bit.Core.Models.Data; +using Bit.Core.OrganizationFeatures.OrganizationUsers.Interfaces; #nullable enable @@ -82,4 +83,11 @@ public interface ICollectionRepository : IRepository /// The encrypted string to use as the default collection name. Task CreateDefaultCollectionsBulkAsync(Guid organizationId, IEnumerable organizationUserIds, string defaultCollectionName); + /// + /// Builds an action that creates a default collection with user access. + /// + /// The collection entity to create + /// Collection access selections for users + /// An action that can be executed within a transaction + OrganizationInitializationUpdateAction BuildCreateDefaultCollectionAction(Collection collection, IEnumerable users); } diff --git a/src/Infrastructure.Dapper/Repositories/CollectionRepository.cs b/src/Infrastructure.Dapper/Repositories/CollectionRepository.cs index 1531703427..c1bb0b6fc6 100644 --- a/src/Infrastructure.Dapper/Repositories/CollectionRepository.cs +++ b/src/Infrastructure.Dapper/Repositories/CollectionRepository.cs @@ -5,6 +5,7 @@ using Bit.Core.AdminConsole.OrganizationFeatures.Collections; using Bit.Core.Entities; using Bit.Core.Enums; using Bit.Core.Models.Data; +using Bit.Core.OrganizationFeatures.OrganizationUsers.Interfaces; using Bit.Core.Repositories; using Bit.Core.Settings; using Bit.Core.Utilities; @@ -529,4 +530,21 @@ public class CollectionRepository : Repository, ICollectionRep [DisallowNull] public DataTable? Users { get; set; } } + + public OrganizationInitializationUpdateAction BuildCreateDefaultCollectionAction(Collection collection, IEnumerable users) + { + return async (SqlConnection? connection, SqlTransaction? transaction, object? context) => + { + var collectionWithAccess = new CollectionWithGroupsAndUsers( + collection, + Enumerable.Empty(), + users); + + await connection!.ExecuteAsync( + "[dbo].[Collection_CreateWithGroupsAndUsers]", + collectionWithAccess, + commandType: CommandType.StoredProcedure, + transaction: transaction); + }; + } } diff --git a/src/Infrastructure.EntityFramework/Repositories/CollectionRepository.cs b/src/Infrastructure.EntityFramework/Repositories/CollectionRepository.cs index 74150246b1..66adc7c61a 100644 --- a/src/Infrastructure.EntityFramework/Repositories/CollectionRepository.cs +++ b/src/Infrastructure.EntityFramework/Repositories/CollectionRepository.cs @@ -2,9 +2,11 @@ using Bit.Core.AdminConsole.OrganizationFeatures.Collections; using Bit.Core.Enums; using Bit.Core.Models.Data; +using Bit.Core.OrganizationFeatures.OrganizationUsers.Interfaces; using Bit.Core.Repositories; using Bit.Infrastructure.EntityFramework.Models; using Bit.Infrastructure.EntityFramework.Repositories.Queries; +using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; @@ -846,4 +848,30 @@ public class CollectionRepository : Repository organizationUserIds, string defaultCollectionName) => CreateDefaultCollectionsAsync(organizationId, organizationUserIds, defaultCollectionName); + + public OrganizationInitializationUpdateAction BuildCreateDefaultCollectionAction(Core.Entities.Collection collection, IEnumerable users) + { + return async (SqlConnection? _, SqlTransaction? _, object? context) => + { + var dbContext = (DatabaseContext)context!; + + var efCollection = Mapper.Map(collection); + await dbContext.Collections.AddAsync(efCollection); + + foreach (var user in users) + { + var collectionUser = new CollectionUser + { + CollectionId = collection.Id, + OrganizationUserId = user.Id, + HidePasswords = user.HidePasswords, + ReadOnly = user.ReadOnly, + Manage = user.Manage + }; + await dbContext.CollectionUsers.AddAsync(collectionUser); + } + + await dbContext.SaveChangesAsync(); + }; + } }