mirror of
https://github.com/bitwarden/server.git
synced 2025-06-06 11:10:32 -05:00
[PM-22344] - fix Error: Cannot Decrypt when moving a vault item to a collection (#5911)
* use ToCipher instead of casting * return ListResponseModel * fix test * remove ToArray * have ShareManyAsync return CipherDetails * fix test * fix tests * fix test * fix test
This commit is contained in:
parent
812fe94c16
commit
2e14a46cee
@ -1064,7 +1064,7 @@ public class CiphersController : Controller
|
||||
|
||||
[HttpPut("share")]
|
||||
[HttpPost("share")]
|
||||
public async Task<CipherMiniResponseModel[]> PutShareMany([FromBody] CipherBulkShareRequestModel model)
|
||||
public async Task<ListResponseModel<CipherMiniResponseModel>> PutShareMany([FromBody] CipherBulkShareRequestModel model)
|
||||
{
|
||||
var organizationId = new Guid(model.Ciphers.First().OrganizationId);
|
||||
if (!await _currentContext.OrganizationUser(organizationId))
|
||||
@ -1086,7 +1086,7 @@ public class CiphersController : Controller
|
||||
}
|
||||
}
|
||||
|
||||
var shareCiphers = new List<(Cipher, DateTime?)>();
|
||||
var shareCiphers = new List<(CipherDetails, DateTime?)>();
|
||||
foreach (var cipher in model.Ciphers)
|
||||
{
|
||||
if (!ciphersDict.TryGetValue(cipher.Id.Value, out var existingCipher))
|
||||
@ -1096,7 +1096,7 @@ public class CiphersController : Controller
|
||||
|
||||
ValidateClientVersionForFido2CredentialSupport(existingCipher);
|
||||
|
||||
shareCiphers.Add(((Cipher)existingCipher, cipher.LastKnownRevisionDate));
|
||||
shareCiphers.Add((cipher.ToCipherDetails(existingCipher), cipher.LastKnownRevisionDate));
|
||||
}
|
||||
|
||||
var updated = await _cipherService.ShareManyAsync(
|
||||
@ -1106,7 +1106,8 @@ public class CiphersController : Controller
|
||||
userId
|
||||
);
|
||||
|
||||
return updated.Select(c => new CipherMiniResponseModel(c, _globalSettings, false)).ToArray();
|
||||
var response = updated.Select(c => new CipherMiniResponseModel(c, _globalSettings, c.OrganizationUseTotp));
|
||||
return new ListResponseModel<CipherMiniResponseModel>(response);
|
||||
}
|
||||
|
||||
[HttpPost("purge")]
|
||||
|
@ -24,7 +24,7 @@ public interface ICipherService
|
||||
Task DeleteFolderAsync(Folder folder);
|
||||
Task ShareAsync(Cipher originalCipher, Cipher cipher, Guid organizationId, IEnumerable<Guid> collectionIds,
|
||||
Guid userId, DateTime? lastKnownRevisionDate);
|
||||
Task<IEnumerable<Cipher>> ShareManyAsync(IEnumerable<(Cipher cipher, DateTime? lastKnownRevisionDate)> ciphers, Guid organizationId,
|
||||
Task<IEnumerable<CipherDetails>> ShareManyAsync(IEnumerable<(CipherDetails cipher, DateTime? lastKnownRevisionDate)> ciphers, Guid organizationId,
|
||||
IEnumerable<Guid> collectionIds, Guid sharingUserId);
|
||||
Task SaveCollectionsAsync(Cipher cipher, IEnumerable<Guid> collectionIds, Guid savingUserId, bool orgAdmin);
|
||||
Task SoftDeleteAsync(CipherDetails cipherDetails, Guid deletingUserId, bool orgAdmin = false);
|
||||
|
@ -625,7 +625,7 @@ public class CipherService : ICipherService
|
||||
await _pushService.PushSyncCipherUpdateAsync(cipher, collectionIds);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Cipher>> ShareManyAsync(IEnumerable<(Cipher cipher, DateTime? lastKnownRevisionDate)> cipherInfos,
|
||||
public async Task<IEnumerable<CipherDetails>> ShareManyAsync(IEnumerable<(CipherDetails cipher, DateTime? lastKnownRevisionDate)> cipherInfos,
|
||||
Guid organizationId, IEnumerable<Guid> collectionIds, Guid sharingUserId)
|
||||
{
|
||||
var cipherIds = new List<Guid>();
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System.Security.Claims;
|
||||
using System.Text.Json;
|
||||
using Bit.Api.Vault.Controllers;
|
||||
using Bit.Api.Vault.Models;
|
||||
using Bit.Api.Vault.Models.Request;
|
||||
using Bit.Api.Vault.Models.Response;
|
||||
using Bit.Core;
|
||||
@ -1774,16 +1775,16 @@ public class CiphersControllerTests
|
||||
Id = Guid.NewGuid(),
|
||||
UserId = userId,
|
||||
OrganizationId = organizationId,
|
||||
Type = CipherType.SecureNote,
|
||||
Data = JsonSerializer.Serialize(new CipherSecureNoteData()),
|
||||
Type = CipherType.Login,
|
||||
Data = JsonSerializer.Serialize(new CipherLoginData()),
|
||||
RevisionDate = oldDate2
|
||||
};
|
||||
var preloadedDetails = new List<CipherDetails> { detail1, detail2 };
|
||||
|
||||
var newDate1 = oldDate1.AddMinutes(5);
|
||||
var newDate2 = oldDate2.AddMinutes(5);
|
||||
var updatedCipher1 = new Cipher { Id = detail1.Id, RevisionDate = newDate1, Type = detail1.Type, Data = detail1.Data };
|
||||
var updatedCipher2 = new Cipher { Id = detail2.Id, RevisionDate = newDate2, Type = detail2.Type, Data = detail2.Data };
|
||||
var updatedCipher1 = new CipherDetails { Id = detail1.Id, RevisionDate = newDate1, Type = detail1.Type, Data = detail1.Data };
|
||||
var updatedCipher2 = new CipherDetails { Id = detail2.Id, RevisionDate = newDate2, Type = detail2.Type, Data = detail2.Data };
|
||||
|
||||
sutProvider.GetDependency<ICurrentContext>()
|
||||
.OrganizationUser(organizationId)
|
||||
@ -1801,19 +1802,39 @@ public class CiphersControllerTests
|
||||
|
||||
sutProvider.GetDependency<ICipherService>()
|
||||
.ShareManyAsync(
|
||||
Arg.Any<IEnumerable<(Cipher, DateTime?)>>(),
|
||||
Arg.Any<IEnumerable<(CipherDetails, DateTime?)>>(),
|
||||
organizationId,
|
||||
Arg.Any<IEnumerable<Guid>>(),
|
||||
userId
|
||||
)
|
||||
.Returns(Task.FromResult<IEnumerable<Cipher>>(new[] { updatedCipher1, updatedCipher2 }));
|
||||
.Returns(Task.FromResult<IEnumerable<CipherDetails>>(new[] { updatedCipher1, updatedCipher2 }));
|
||||
|
||||
var cipherRequests = preloadedDetails.Select(d => new CipherWithIdRequestModel
|
||||
var cipherRequests = preloadedDetails.Select(d =>
|
||||
{
|
||||
Id = d.Id,
|
||||
OrganizationId = d.OrganizationId!.Value.ToString(),
|
||||
LastKnownRevisionDate = d.RevisionDate,
|
||||
Type = d.Type
|
||||
var m = new CipherWithIdRequestModel
|
||||
{
|
||||
Id = d.Id,
|
||||
OrganizationId = d.OrganizationId!.Value.ToString(),
|
||||
LastKnownRevisionDate = d.RevisionDate,
|
||||
Type = d.Type,
|
||||
};
|
||||
|
||||
if (d.Type == CipherType.Login)
|
||||
{
|
||||
m.Login = new CipherLoginModel
|
||||
{
|
||||
Username = "",
|
||||
Password = "",
|
||||
Uris = [],
|
||||
};
|
||||
m.Name = "";
|
||||
m.Notes = "";
|
||||
m.Fields = Array.Empty<CipherFieldModel>();
|
||||
m.PasswordHistory = Array.Empty<CipherPasswordHistoryModel>();
|
||||
}
|
||||
|
||||
// similar for SecureNote, Card, etc., if you ever hit those branches
|
||||
return m;
|
||||
}).ToList();
|
||||
|
||||
var model = new CipherBulkShareRequestModel
|
||||
@ -1824,15 +1845,15 @@ public class CiphersControllerTests
|
||||
|
||||
var result = await sutProvider.Sut.PutShareMany(model);
|
||||
|
||||
Assert.Equal(2, result.Length);
|
||||
var revisionDates = result.Select(r => r.RevisionDate).ToList();
|
||||
Assert.Equal(2, result.Data.Count());
|
||||
var revisionDates = result.Data.Select(x => x.RevisionDate).ToList();
|
||||
Assert.Contains(newDate1, revisionDates);
|
||||
Assert.Contains(newDate2, revisionDates);
|
||||
|
||||
await sutProvider.GetDependency<ICipherService>()
|
||||
.Received(1)
|
||||
.ShareManyAsync(
|
||||
Arg.Is<IEnumerable<(Cipher, DateTime?)>>(list =>
|
||||
Arg.Is<IEnumerable<(CipherDetails, DateTime?)>>(list =>
|
||||
list.Select(x => x.Item1.Id).OrderBy(id => id)
|
||||
.SequenceEqual(new[] { detail1.Id, detail2.Id }.OrderBy(id => id))
|
||||
),
|
||||
|
@ -72,7 +72,7 @@ public class CipherServiceTests
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task ShareManyAsync_WrongRevisionDate_Throws(SutProvider<CipherService> sutProvider,
|
||||
IEnumerable<Cipher> ciphers, Guid organizationId, List<Guid> collectionIds)
|
||||
IEnumerable<CipherDetails> ciphers, Guid organizationId, List<Guid> collectionIds)
|
||||
{
|
||||
sutProvider.GetDependency<IOrganizationRepository>().GetByIdAsync(organizationId)
|
||||
.Returns(new Organization
|
||||
@ -651,7 +651,7 @@ public class CipherServiceTests
|
||||
[BitAutoData("")]
|
||||
[BitAutoData("Correct Time")]
|
||||
public async Task ShareManyAsync_CorrectRevisionDate_Passes(string revisionDateString,
|
||||
SutProvider<CipherService> sutProvider, IEnumerable<Cipher> ciphers, Organization organization, List<Guid> collectionIds)
|
||||
SutProvider<CipherService> sutProvider, IEnumerable<CipherDetails> ciphers, Organization organization, List<Guid> collectionIds)
|
||||
{
|
||||
sutProvider.GetDependency<IOrganizationRepository>().GetByIdAsync(organization.Id)
|
||||
.Returns(new Organization
|
||||
@ -1173,7 +1173,7 @@ public class CipherServiceTests
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task ShareManyAsync_FreeOrgWithAttachment_Throws(SutProvider<CipherService> sutProvider,
|
||||
IEnumerable<Cipher> ciphers, Guid organizationId, List<Guid> collectionIds)
|
||||
IEnumerable<CipherDetails> ciphers, Guid organizationId, List<Guid> collectionIds)
|
||||
{
|
||||
sutProvider.GetDependency<IOrganizationRepository>().GetByIdAsync(organizationId).Returns(new Organization
|
||||
{
|
||||
@ -1194,7 +1194,7 @@ public class CipherServiceTests
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task ShareManyAsync_PaidOrgWithAttachment_Passes(SutProvider<CipherService> sutProvider,
|
||||
IEnumerable<Cipher> ciphers, Guid organizationId, List<Guid> collectionIds)
|
||||
IEnumerable<CipherDetails> ciphers, Guid organizationId, List<Guid> collectionIds)
|
||||
{
|
||||
sutProvider.GetDependency<IOrganizationRepository>().GetByIdAsync(organizationId)
|
||||
.Returns(new Organization
|
||||
|
Loading…
x
Reference in New Issue
Block a user