mirror of
https://github.com/bitwarden/server.git
synced 2024-12-25 17:27:45 +01:00
[PS-2390] Updating and adding items into folder and collection on import (#2717)
* PS-2390 Adding Id to the Collection/Folder RequestModel replacing folder/collection when they already exist instead of creating a new one Adding items to existing collections if the id matches * PS-2390 Improved Folder/Collection RequestModel code design * PS-2390 Removed whitespaces from FolderRequestModel * PS-2390 Verifying if folder/collection belongs to user/organization when updating or creating a new one * PS-2390 - Removed unnecessary null validation for Id on Folder/CollectionRequestModel * PS-2390 - Added bulk methods to get and update folders at import * PS-2390 - Added bulk methods to get and update collections at import org * PS-2390 - Corrected sqlproj path to Folder_ReadByIdsAndUserId * PS-2390 - Improved code readibility * PS-2390 - Added newlines to EOF * PS-2390 Remove logic to update folders/collections at import * PS-2390 - removed unnecessary methods and imports * PS-2390 - Removed unnecessary formatting change * PS-2390 - Removed unused variable
This commit is contained in:
parent
6551d9176b
commit
49f15d8cc1
@ -4,7 +4,7 @@ namespace Bit.Api.Models.Request.Accounts;
|
||||
|
||||
public class ImportCiphersRequestModel
|
||||
{
|
||||
public FolderRequestModel[] Folders { get; set; }
|
||||
public FolderWithIdRequestModel[] Folders { get; set; }
|
||||
public CipherRequestModel[] Ciphers { get; set; }
|
||||
public KeyValuePair<int, int>[] FolderRelationships { get; set; }
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ public class CollectionRequestModel
|
||||
});
|
||||
}
|
||||
|
||||
public Collection ToCollection(Collection existingCollection)
|
||||
public virtual Collection ToCollection(Collection existingCollection)
|
||||
{
|
||||
existingCollection.Name = Name;
|
||||
existingCollection.ExternalId = ExternalId;
|
||||
@ -37,3 +37,14 @@ public class CollectionBulkDeleteRequestModel
|
||||
public IEnumerable<string> Ids { get; set; }
|
||||
public string OrganizationId { get; set; }
|
||||
}
|
||||
|
||||
public class CollectionWithIdRequestModel : CollectionRequestModel
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
|
||||
public override Collection ToCollection(Collection existingCollection)
|
||||
{
|
||||
existingCollection.Id = Id ?? Guid.Empty;
|
||||
return base.ToCollection(existingCollection);
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ namespace Bit.Api.Models.Request.Organizations;
|
||||
|
||||
public class ImportOrganizationCiphersRequestModel
|
||||
{
|
||||
public CollectionRequestModel[] Collections { get; set; }
|
||||
public CollectionWithIdRequestModel[] Collections { get; set; }
|
||||
public CipherRequestModel[] Ciphers { get; set; }
|
||||
public KeyValuePair<int, int>[] CollectionRelationships { get; set; }
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ public class FolderRequestModel
|
||||
});
|
||||
}
|
||||
|
||||
public Folder ToFolder(Folder existingFolder)
|
||||
public virtual Folder ToFolder(Folder existingFolder)
|
||||
{
|
||||
existingFolder.Name = Name;
|
||||
return existingFolder;
|
||||
@ -28,5 +28,11 @@ public class FolderRequestModel
|
||||
|
||||
public class FolderWithIdRequestModel : FolderRequestModel
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid? Id { get; set; }
|
||||
|
||||
public override Folder ToFolder(Folder existingFolder)
|
||||
{
|
||||
existingFolder.Id = Id ?? Guid.Empty;
|
||||
return base.ToFolder(existingFolder);
|
||||
}
|
||||
}
|
||||
|
@ -648,10 +648,18 @@ public class CipherService : ICipherService
|
||||
}
|
||||
}
|
||||
|
||||
// Init. ids for folders
|
||||
var userfoldersIds = (await _folderRepository.GetManyByUserIdAsync(userId ?? Guid.Empty)).Select(f => f.Id).ToList();
|
||||
|
||||
//Assign id to the ones that don't exist in DB
|
||||
//Need to keep the list order to create the relationships
|
||||
List<Folder> newFolders = new List<Folder>();
|
||||
foreach (var folder in folders)
|
||||
{
|
||||
folder.SetNewId();
|
||||
if (!userfoldersIds.Contains(folder.Id))
|
||||
{
|
||||
folder.SetNewId();
|
||||
newFolders.Add(folder);
|
||||
}
|
||||
}
|
||||
|
||||
// Create the folder associations based on the newly created folder ids
|
||||
@ -670,7 +678,7 @@ public class CipherService : ICipherService
|
||||
}
|
||||
|
||||
// Create it all
|
||||
await _cipherRepository.CreateAsync(ciphers, folders);
|
||||
await _cipherRepository.CreateAsync(ciphers, newFolders);
|
||||
|
||||
// push
|
||||
if (userId.HasValue)
|
||||
@ -705,10 +713,19 @@ public class CipherService : ICipherService
|
||||
cipher.SetNewId();
|
||||
}
|
||||
|
||||
// Init. ids for collections
|
||||
var userCollectionsIds = (await _collectionRepository.GetManyByOrganizationIdAsync(org.Id)).Select(c => c.Id).ToList();
|
||||
|
||||
//Assign id to the ones that don't exist in DB
|
||||
//Need to keep the list order to create the relationships
|
||||
List<Collection> newCollections = new List<Collection>();
|
||||
|
||||
foreach (var collection in collections)
|
||||
{
|
||||
collection.SetNewId();
|
||||
if (!userCollectionsIds.Contains(collection.Id))
|
||||
{
|
||||
collection.SetNewId();
|
||||
newCollections.Add(collection);
|
||||
}
|
||||
}
|
||||
|
||||
// Create associations based on the newly assigned ids
|
||||
@ -731,7 +748,7 @@ public class CipherService : ICipherService
|
||||
}
|
||||
|
||||
// Create it all
|
||||
await _cipherRepository.CreateAsync(ciphers, collections, collectionCiphers);
|
||||
await _cipherRepository.CreateAsync(ciphers, newCollections, collectionCiphers);
|
||||
|
||||
// push
|
||||
await _pushService.PushSyncVaultAsync(importingUserId);
|
||||
|
@ -616,15 +616,15 @@ public class CipherRepository : Repository<Cipher, Guid>, ICipherRepository
|
||||
var dataTable = BuildCollectionsTable(bulkCopy, collections);
|
||||
bulkCopy.WriteToServer(dataTable);
|
||||
}
|
||||
}
|
||||
|
||||
if (collectionCiphers.Any())
|
||||
if (collectionCiphers.Any())
|
||||
{
|
||||
using (var bulkCopy = new SqlBulkCopy(connection, SqlBulkCopyOptions.KeepIdentity, transaction))
|
||||
{
|
||||
using (var bulkCopy = new SqlBulkCopy(connection, SqlBulkCopyOptions.KeepIdentity, transaction))
|
||||
{
|
||||
bulkCopy.DestinationTableName = "[dbo].[CollectionCipher]";
|
||||
var dataTable = BuildCollectionCiphersTable(bulkCopy, collectionCiphers);
|
||||
bulkCopy.WriteToServer(dataTable);
|
||||
}
|
||||
bulkCopy.DestinationTableName = "[dbo].[CollectionCipher]";
|
||||
var dataTable = BuildCollectionCiphersTable(bulkCopy, collectionCiphers);
|
||||
bulkCopy.WriteToServer(dataTable);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -168,16 +168,17 @@ public class CipherRepository : Repository<Core.Vault.Entities.Cipher, Cipher, G
|
||||
var dbContext = GetDatabaseContext(scope);
|
||||
var cipherEntities = Mapper.Map<List<Cipher>>(ciphers);
|
||||
await dbContext.BulkCopyAsync(base.DefaultBulkCopyOptions, cipherEntities);
|
||||
|
||||
if (collections.Any())
|
||||
{
|
||||
var collectionEntities = Mapper.Map<List<Collection>>(collections);
|
||||
await dbContext.BulkCopyAsync(base.DefaultBulkCopyOptions, collectionEntities);
|
||||
}
|
||||
|
||||
if (collectionCiphers.Any())
|
||||
{
|
||||
var collectionCipherEntities = Mapper.Map<List<CollectionCipher>>(collectionCiphers);
|
||||
await dbContext.BulkCopyAsync(base.DefaultBulkCopyOptions, collectionCipherEntities);
|
||||
}
|
||||
if (collectionCiphers.Any())
|
||||
{
|
||||
var collectionCipherEntities = Mapper.Map<List<CollectionCipher>>(collectionCiphers);
|
||||
await dbContext.BulkCopyAsync(base.DefaultBulkCopyOptions, collectionCipherEntities);
|
||||
}
|
||||
await dbContext.UserBumpAccountRevisionDateByOrganizationIdAsync(ciphers.First().OrganizationId.Value);
|
||||
await dbContext.SaveChangesAsync();
|
||||
|
Loading…
Reference in New Issue
Block a user