Browse Source

Fix user context on importing into individual vaults (#5465)

Pass in the current userId instead of trying to infer it from the folders or ciphers passed into the ImportCiphersCommand

Kudos go to @MJebran who pointed this out on https://github.com/bitwarden/server/pull/4896

Co-authored-by: Daniel James Smith <djsmith85@users.noreply.github.com>
pull/5478/head
Daniel James Smith 10 months ago committed by GitHub
parent
commit
34358acf61
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      src/Api/Tools/Controllers/ImportCiphersController.cs
  2. 14
      src/Core/Tools/ImportFeatures/ImportCiphersCommand.cs
  3. 2
      src/Core/Tools/ImportFeatures/Interfaces/IImportCiphersCommand.cs
  4. 3
      test/Api.Test/Tools/Controllers/ImportCiphersControllerTests.cs
  5. 4
      test/Core.Test/Tools/ImportFeatures/ImportCiphersAsyncCommandTests.cs

2
src/Api/Tools/Controllers/ImportCiphersController.cs

@ -56,7 +56,7 @@ public class ImportCiphersController : Controller
var userId = _userService.GetProperUserId(User).Value; var userId = _userService.GetProperUserId(User).Value;
var folders = model.Folders.Select(f => f.ToFolder(userId)).ToList(); var folders = model.Folders.Select(f => f.ToFolder(userId)).ToList();
var ciphers = model.Ciphers.Select(c => c.ToCipherDetails(userId, false)).ToList(); var ciphers = model.Ciphers.Select(c => c.ToCipherDetails(userId, false)).ToList();
await _importCiphersCommand.ImportIntoIndividualVaultAsync(folders, ciphers, model.FolderRelationships); await _importCiphersCommand.ImportIntoIndividualVaultAsync(folders, ciphers, model.FolderRelationships, userId);
} }
[HttpPost("import-organization")] [HttpPost("import-organization")]

14
src/Core/Tools/ImportFeatures/ImportCiphersCommand.cs

@ -54,12 +54,11 @@ public class ImportCiphersCommand : IImportCiphersCommand
public async Task ImportIntoIndividualVaultAsync( public async Task ImportIntoIndividualVaultAsync(
List<Folder> folders, List<Folder> folders,
List<CipherDetails> ciphers, List<CipherDetails> ciphers,
IEnumerable<KeyValuePair<int, int>> folderRelationships) IEnumerable<KeyValuePair<int, int>> folderRelationships,
Guid importingUserId)
{ {
var userId = folders.FirstOrDefault()?.UserId ?? ciphers.FirstOrDefault()?.UserId;
// Make sure the user can save new ciphers to their personal vault // Make sure the user can save new ciphers to their personal vault
var anyPersonalOwnershipPolicies = await _policyService.AnyPoliciesApplicableToUserAsync(userId.Value, PolicyType.PersonalOwnership); var anyPersonalOwnershipPolicies = await _policyService.AnyPoliciesApplicableToUserAsync(importingUserId, PolicyType.PersonalOwnership);
if (anyPersonalOwnershipPolicies) if (anyPersonalOwnershipPolicies)
{ {
throw new BadRequestException("You cannot import items into your personal vault because you are " + throw new BadRequestException("You cannot import items into your personal vault because you are " +
@ -76,7 +75,7 @@ public class ImportCiphersCommand : IImportCiphersCommand
} }
} }
var userfoldersIds = (await _folderRepository.GetManyByUserIdAsync(userId ?? Guid.Empty)).Select(f => f.Id).ToList(); var userfoldersIds = (await _folderRepository.GetManyByUserIdAsync(importingUserId)).Select(f => f.Id).ToList();
//Assign id to the ones that don't exist in DB //Assign id to the ones that don't exist in DB
//Need to keep the list order to create the relationships //Need to keep the list order to create the relationships
@ -109,10 +108,7 @@ public class ImportCiphersCommand : IImportCiphersCommand
await _cipherRepository.CreateAsync(ciphers, newFolders); await _cipherRepository.CreateAsync(ciphers, newFolders);
// push // push
if (userId.HasValue) await _pushService.PushSyncVaultAsync(importingUserId);
{
await _pushService.PushSyncVaultAsync(userId.Value);
}
} }
public async Task ImportIntoOrganizationalVaultAsync( public async Task ImportIntoOrganizationalVaultAsync(

2
src/Core/Tools/ImportFeatures/Interfaces/IImportCiphersCommand.cs

@ -7,7 +7,7 @@ namespace Bit.Core.Tools.ImportFeatures.Interfaces;
public interface IImportCiphersCommand public interface IImportCiphersCommand
{ {
Task ImportIntoIndividualVaultAsync(List<Folder> folders, List<CipherDetails> ciphers, Task ImportIntoIndividualVaultAsync(List<Folder> folders, List<CipherDetails> ciphers,
IEnumerable<KeyValuePair<int, int>> folderRelationships); IEnumerable<KeyValuePair<int, int>> folderRelationships, Guid importingUserId);
Task ImportIntoOrganizationalVaultAsync(List<Collection> collections, List<CipherDetails> ciphers, Task ImportIntoOrganizationalVaultAsync(List<Collection> collections, List<CipherDetails> ciphers,
IEnumerable<KeyValuePair<int, int>> collectionRelationships, Guid importingUserId); IEnumerable<KeyValuePair<int, int>> collectionRelationships, Guid importingUserId);

3
test/Api.Test/Tools/Controllers/ImportCiphersControllerTests.cs

@ -79,7 +79,8 @@ public class ImportCiphersControllerTests
.ImportIntoIndividualVaultAsync( .ImportIntoIndividualVaultAsync(
Arg.Any<List<Folder>>(), Arg.Any<List<Folder>>(),
Arg.Any<List<CipherDetails>>(), Arg.Any<List<CipherDetails>>(),
Arg.Any<IEnumerable<KeyValuePair<int, int>>>() Arg.Any<IEnumerable<KeyValuePair<int, int>>>(),
user.Id
); );
} }

4
test/Core.Test/Tools/ImportFeatures/ImportCiphersAsyncCommandTests.cs

@ -44,7 +44,7 @@ public class ImportCiphersAsyncCommandTests
var folderRelationships = new List<KeyValuePair<int, int>>(); var folderRelationships = new List<KeyValuePair<int, int>>();
// Act // Act
await sutProvider.Sut.ImportIntoIndividualVaultAsync(folders, ciphers, folderRelationships); await sutProvider.Sut.ImportIntoIndividualVaultAsync(folders, ciphers, folderRelationships, importingUserId);
// Assert // Assert
await sutProvider.GetDependency<ICipherRepository>().Received(1).CreateAsync(ciphers, Arg.Any<List<Folder>>()); await sutProvider.GetDependency<ICipherRepository>().Received(1).CreateAsync(ciphers, Arg.Any<List<Folder>>());
@ -68,7 +68,7 @@ public class ImportCiphersAsyncCommandTests
var folderRelationships = new List<KeyValuePair<int, int>>(); var folderRelationships = new List<KeyValuePair<int, int>>();
var exception = await Assert.ThrowsAsync<BadRequestException>(() => var exception = await Assert.ThrowsAsync<BadRequestException>(() =>
sutProvider.Sut.ImportIntoIndividualVaultAsync(folders, ciphers, folderRelationships)); sutProvider.Sut.ImportIntoIndividualVaultAsync(folders, ciphers, folderRelationships, userId));
Assert.Equal("You cannot import items into your personal vault because you are a member of an organization which forbids it.", exception.Message); Assert.Equal("You cannot import items into your personal vault because you are a member of an organization which forbids it.", exception.Message);
} }

Loading…
Cancel
Save