mirror of
https://github.com/bitwarden/server.git
synced 2025-07-02 08:32:50 -05:00
[PM-2682] Fix v0 attachments migration on share cipher with org (#3051)
* PM-2682 Fix v0 attachments migration on share cipher with org * PM-2682 Fix format * PM-2682 Fix tests recursion * Update src/Core/Vault/Models/Data/CipherAttachment.cs Co-authored-by: Matt Gibson <mgibson@bitwarden.com> --------- Co-authored-by: Matt Gibson <mgibson@bitwarden.com>
This commit is contained in:

committed by
GitHub

parent
a61290a3c8
commit
10782d55f3
@ -14,6 +14,10 @@ public class MetaData : ICustomization
|
||||
public void Customize(IFixture fixture)
|
||||
{
|
||||
fixture.Customize<CipherAttachment.MetaData>(composer => ComposerAction(fixture, composer));
|
||||
fixture.Behaviors.OfType<ThrowingRecursionBehavior>()
|
||||
.ToList()
|
||||
.ForEach(b => fixture.Behaviors.Remove(b));
|
||||
fixture.Behaviors.Add(new OmitOnRecursionBehavior(1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Test.AutoFixture.CipherFixtures;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.Core.Vault.Entities;
|
||||
using Bit.Core.Vault.Models.Data;
|
||||
using Bit.Core.Vault.Repositories;
|
||||
@ -44,7 +46,12 @@ public class CipherServiceTests
|
||||
Organization organization, List<Guid> collectionIds)
|
||||
{
|
||||
sutProvider.GetDependency<IOrganizationRepository>().GetByIdAsync(organization.Id).Returns(organization);
|
||||
|
||||
var lastKnownRevisionDate = cipher.RevisionDate.AddDays(-1);
|
||||
cipher.SetAttachments(new Dictionary<string, CipherAttachment.MetaData>
|
||||
{
|
||||
[Guid.NewGuid().ToString()] = new CipherAttachment.MetaData { }
|
||||
});
|
||||
|
||||
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
||||
() => sutProvider.Sut.ShareAsync(cipher, cipher, organization.Id, collectionIds, cipher.UserId.Value,
|
||||
@ -105,11 +112,438 @@ public class CipherServiceTests
|
||||
cipherRepository.ReplaceAsync(cipher, collectionIds).Returns(true);
|
||||
sutProvider.GetDependency<IOrganizationRepository>().GetByIdAsync(organization.Id).Returns(organization);
|
||||
|
||||
cipher.SetAttachments(new Dictionary<string, CipherAttachment.MetaData>
|
||||
{
|
||||
[Guid.NewGuid().ToString()] = new CipherAttachment.MetaData { }
|
||||
});
|
||||
await sutProvider.Sut.ShareAsync(cipher, cipher, organization.Id, collectionIds, cipher.UserId.Value,
|
||||
lastKnownRevisionDate);
|
||||
await cipherRepository.Received(1).ReplaceAsync(cipher, collectionIds);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData("Correct Time")]
|
||||
public async Task ShareAsync_FailReplace_Throws(string revisionDateString,
|
||||
SutProvider<CipherService> sutProvider, Cipher cipher, Organization organization, List<Guid> collectionIds)
|
||||
{
|
||||
var lastKnownRevisionDate = string.IsNullOrEmpty(revisionDateString) ? (DateTime?)null : cipher.RevisionDate;
|
||||
var cipherRepository = sutProvider.GetDependency<ICipherRepository>();
|
||||
cipherRepository.ReplaceAsync(cipher, collectionIds).Returns(false);
|
||||
sutProvider.GetDependency<IOrganizationRepository>().GetByIdAsync(organization.Id).Returns(organization);
|
||||
|
||||
cipher.SetAttachments(new Dictionary<string, CipherAttachment.MetaData>
|
||||
{
|
||||
[Guid.NewGuid().ToString()] = new CipherAttachment.MetaData { }
|
||||
});
|
||||
|
||||
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
||||
() => sutProvider.Sut.ShareAsync(cipher, cipher, organization.Id, collectionIds, cipher.UserId.Value,
|
||||
lastKnownRevisionDate));
|
||||
Assert.Contains("Unable to save", exception.Message);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData("Correct Time")]
|
||||
public async Task ShareAsync_HasV0Attachments_ReplaceAttachmentMetadataWithNewOneBeforeSavingCipher(string revisionDateString,
|
||||
SutProvider<CipherService> sutProvider, Cipher cipher, Organization organization, List<Guid> collectionIds)
|
||||
{
|
||||
var lastKnownRevisionDate = string.IsNullOrEmpty(revisionDateString) ? (DateTime?)null : cipher.RevisionDate;
|
||||
var originalCipher = CoreHelpers.CloneObject(cipher);
|
||||
var cipherRepository = sutProvider.GetDependency<ICipherRepository>();
|
||||
cipherRepository.ReplaceAsync(cipher, collectionIds).Returns(true);
|
||||
sutProvider.GetDependency<IOrganizationRepository>().GetByIdAsync(organization.Id).Returns(organization);
|
||||
var pushNotificationService = sutProvider.GetDependency<IPushNotificationService>();
|
||||
|
||||
var v0AttachmentId = Guid.NewGuid().ToString();
|
||||
var anotherAttachmentId = Guid.NewGuid().ToString();
|
||||
cipher.SetAttachments(new Dictionary<string, CipherAttachment.MetaData>
|
||||
{
|
||||
[v0AttachmentId] = new CipherAttachment.MetaData
|
||||
{
|
||||
AttachmentId = v0AttachmentId,
|
||||
ContainerName = "attachments",
|
||||
FileName = "AFileNameEncrypted"
|
||||
},
|
||||
[anotherAttachmentId] = new CipherAttachment.MetaData
|
||||
{
|
||||
AttachmentId = anotherAttachmentId,
|
||||
Key = "AwesomeKey",
|
||||
FileName = "AnotherFilename",
|
||||
ContainerName = "attachments",
|
||||
Size = 300,
|
||||
Validated = true
|
||||
}
|
||||
});
|
||||
|
||||
originalCipher.SetAttachments(new Dictionary<string, CipherAttachment.MetaData>
|
||||
{
|
||||
[v0AttachmentId] = new CipherAttachment.MetaData
|
||||
{
|
||||
AttachmentId = v0AttachmentId,
|
||||
ContainerName = "attachments",
|
||||
FileName = "AFileNameEncrypted",
|
||||
TempMetadata = new CipherAttachment.MetaData
|
||||
{
|
||||
AttachmentId = v0AttachmentId,
|
||||
ContainerName = "attachments",
|
||||
FileName = "AFileNameRe-EncryptedWithOrgKey",
|
||||
Key = "NewAttachmentKey"
|
||||
}
|
||||
},
|
||||
[anotherAttachmentId] = new CipherAttachment.MetaData
|
||||
{
|
||||
AttachmentId = anotherAttachmentId,
|
||||
Key = "AwesomeKey",
|
||||
FileName = "AnotherFilename",
|
||||
ContainerName = "attachments",
|
||||
Size = 300,
|
||||
Validated = true
|
||||
}
|
||||
});
|
||||
|
||||
await sutProvider.Sut.ShareAsync(originalCipher, cipher, organization.Id, collectionIds, cipher.UserId.Value,
|
||||
lastKnownRevisionDate);
|
||||
|
||||
await cipherRepository.Received().ReplaceAsync(Arg.Is<Cipher>(c =>
|
||||
c.GetAttachments()[v0AttachmentId].Key == "NewAttachmentKey"
|
||||
&&
|
||||
c.GetAttachments()[v0AttachmentId].FileName == "AFileNameRe-EncryptedWithOrgKey")
|
||||
, collectionIds);
|
||||
|
||||
await pushNotificationService.Received(1).PushSyncCipherUpdateAsync(cipher, collectionIds);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData("Correct Time")]
|
||||
public async Task ShareAsync_HasV0Attachments_StartSharingThoseAttachments(string revisionDateString,
|
||||
SutProvider<CipherService> sutProvider, Cipher cipher, Organization organization, List<Guid> collectionIds)
|
||||
{
|
||||
var lastKnownRevisionDate = string.IsNullOrEmpty(revisionDateString) ? (DateTime?)null : cipher.RevisionDate;
|
||||
var originalCipher = CoreHelpers.CloneObject(cipher);
|
||||
var cipherRepository = sutProvider.GetDependency<ICipherRepository>();
|
||||
cipherRepository.ReplaceAsync(cipher, collectionIds).Returns(true);
|
||||
sutProvider.GetDependency<IOrganizationRepository>().GetByIdAsync(organization.Id).Returns(organization);
|
||||
var attachmentStorageService = sutProvider.GetDependency<IAttachmentStorageService>();
|
||||
|
||||
var v0AttachmentId = Guid.NewGuid().ToString();
|
||||
var anotherAttachmentId = Guid.NewGuid().ToString();
|
||||
cipher.SetAttachments(new Dictionary<string, CipherAttachment.MetaData>
|
||||
{
|
||||
[v0AttachmentId] = new CipherAttachment.MetaData
|
||||
{
|
||||
AttachmentId = v0AttachmentId,
|
||||
ContainerName = "attachments",
|
||||
FileName = "AFileNameEncrypted",
|
||||
TempMetadata = new CipherAttachment.MetaData
|
||||
{
|
||||
AttachmentId = v0AttachmentId,
|
||||
ContainerName = "attachments",
|
||||
FileName = "AFileNameRe-EncryptedWithOrgKey",
|
||||
Key = "NewAttachmentKey"
|
||||
}
|
||||
},
|
||||
[anotherAttachmentId] = new CipherAttachment.MetaData
|
||||
{
|
||||
AttachmentId = anotherAttachmentId,
|
||||
Key = "AwesomeKey",
|
||||
FileName = "AnotherFilename",
|
||||
ContainerName = "attachments",
|
||||
Size = 300,
|
||||
Validated = true
|
||||
}
|
||||
});
|
||||
|
||||
originalCipher.SetAttachments(new Dictionary<string, CipherAttachment.MetaData>
|
||||
{
|
||||
[v0AttachmentId] = new CipherAttachment.MetaData
|
||||
{
|
||||
AttachmentId = v0AttachmentId,
|
||||
ContainerName = "attachments",
|
||||
FileName = "AFileNameEncrypted",
|
||||
TempMetadata = new CipherAttachment.MetaData
|
||||
{
|
||||
AttachmentId = v0AttachmentId,
|
||||
ContainerName = "attachments",
|
||||
FileName = "AFileNameRe-EncryptedWithOrgKey",
|
||||
Key = "NewAttachmentKey"
|
||||
}
|
||||
},
|
||||
[anotherAttachmentId] = new CipherAttachment.MetaData
|
||||
{
|
||||
AttachmentId = anotherAttachmentId,
|
||||
Key = "AwesomeKey",
|
||||
FileName = "AnotherFilename",
|
||||
ContainerName = "attachments",
|
||||
Size = 300,
|
||||
Validated = true
|
||||
}
|
||||
});
|
||||
|
||||
await sutProvider.Sut.ShareAsync(originalCipher, cipher, organization.Id, collectionIds, cipher.UserId.Value,
|
||||
lastKnownRevisionDate);
|
||||
|
||||
await attachmentStorageService.Received().StartShareAttachmentAsync(cipher.Id,
|
||||
organization.Id,
|
||||
Arg.Is<CipherAttachment.MetaData>(m => m.Key == "NewAttachmentKey" && m.FileName == "AFileNameRe-EncryptedWithOrgKey"));
|
||||
|
||||
await attachmentStorageService.Received(0).StartShareAttachmentAsync(cipher.Id,
|
||||
organization.Id,
|
||||
Arg.Is<CipherAttachment.MetaData>(m => m.Key == "AwesomeKey" && m.FileName == "AnotherFilename"));
|
||||
|
||||
await attachmentStorageService.Received().CleanupAsync(cipher.Id);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData("Correct Time")]
|
||||
public async Task ShareAsync_HasV0Attachments_StartShareThrows_PerformsRollback_Rethrows(string revisionDateString,
|
||||
SutProvider<CipherService> sutProvider, Cipher cipher, Organization organization, List<Guid> collectionIds)
|
||||
{
|
||||
var lastKnownRevisionDate = string.IsNullOrEmpty(revisionDateString) ? (DateTime?)null : cipher.RevisionDate;
|
||||
var originalCipher = CoreHelpers.CloneObject(cipher);
|
||||
var cipherRepository = sutProvider.GetDependency<ICipherRepository>();
|
||||
cipherRepository.ReplaceAsync(cipher, collectionIds).Returns(true);
|
||||
sutProvider.GetDependency<IOrganizationRepository>().GetByIdAsync(organization.Id).Returns(organization);
|
||||
var attachmentStorageService = sutProvider.GetDependency<IAttachmentStorageService>();
|
||||
var collectionCipherRepository = sutProvider.GetDependency<ICollectionCipherRepository>();
|
||||
collectionCipherRepository.GetManyByUserIdCipherIdAsync(cipher.UserId.Value, cipher.Id).Returns(
|
||||
Task.FromResult((ICollection<CollectionCipher>)new List<CollectionCipher>
|
||||
{
|
||||
new CollectionCipher
|
||||
{
|
||||
CipherId = cipher.Id,
|
||||
CollectionId = collectionIds[0]
|
||||
},
|
||||
new CollectionCipher
|
||||
{
|
||||
CipherId = cipher.Id,
|
||||
CollectionId = Guid.NewGuid()
|
||||
}
|
||||
}));
|
||||
|
||||
var v0AttachmentId = Guid.NewGuid().ToString();
|
||||
var anotherAttachmentId = Guid.NewGuid().ToString();
|
||||
cipher.SetAttachments(new Dictionary<string, CipherAttachment.MetaData>
|
||||
{
|
||||
[v0AttachmentId] = new CipherAttachment.MetaData
|
||||
{
|
||||
AttachmentId = v0AttachmentId,
|
||||
ContainerName = "attachments",
|
||||
FileName = "AFileNameEncrypted",
|
||||
TempMetadata = new CipherAttachment.MetaData
|
||||
{
|
||||
AttachmentId = v0AttachmentId,
|
||||
ContainerName = "attachments",
|
||||
FileName = "AFileNameRe-EncryptedWithOrgKey",
|
||||
Key = "NewAttachmentKey"
|
||||
}
|
||||
},
|
||||
[anotherAttachmentId] = new CipherAttachment.MetaData
|
||||
{
|
||||
AttachmentId = anotherAttachmentId,
|
||||
Key = "AwesomeKey",
|
||||
FileName = "AnotherFilename",
|
||||
ContainerName = "attachments",
|
||||
Size = 300,
|
||||
Validated = true
|
||||
}
|
||||
});
|
||||
|
||||
originalCipher.SetAttachments(new Dictionary<string, CipherAttachment.MetaData>
|
||||
{
|
||||
[v0AttachmentId] = new CipherAttachment.MetaData
|
||||
{
|
||||
AttachmentId = v0AttachmentId,
|
||||
ContainerName = "attachments",
|
||||
FileName = "AFileNameEncrypted",
|
||||
TempMetadata = new CipherAttachment.MetaData
|
||||
{
|
||||
AttachmentId = v0AttachmentId,
|
||||
ContainerName = "attachments",
|
||||
FileName = "AFileNameRe-EncryptedWithOrgKey",
|
||||
Key = "NewAttachmentKey"
|
||||
}
|
||||
},
|
||||
[anotherAttachmentId] = new CipherAttachment.MetaData
|
||||
{
|
||||
AttachmentId = anotherAttachmentId,
|
||||
Key = "AwesomeKey",
|
||||
FileName = "AnotherFilename",
|
||||
ContainerName = "attachments",
|
||||
Size = 300,
|
||||
Validated = true
|
||||
}
|
||||
});
|
||||
|
||||
attachmentStorageService.StartShareAttachmentAsync(cipher.Id,
|
||||
organization.Id,
|
||||
Arg.Is<CipherAttachment.MetaData>(m => m.AttachmentId == v0AttachmentId))
|
||||
.Returns(Task.FromException(new InvalidOperationException("ex from StartShareAttachmentAsync")));
|
||||
|
||||
var exception = await Assert.ThrowsAsync<InvalidOperationException>(
|
||||
() => sutProvider.Sut.ShareAsync(cipher, cipher, organization.Id, collectionIds, cipher.UserId.Value,
|
||||
lastKnownRevisionDate));
|
||||
Assert.Contains("ex from StartShareAttachmentAsync", exception.Message);
|
||||
|
||||
await collectionCipherRepository.Received().UpdateCollectionsAsync(cipher.Id, cipher.UserId.Value,
|
||||
Arg.Is<List<Guid>>(ids => ids.Count == 1 && ids[0] != collectionIds[0]));
|
||||
|
||||
await cipherRepository.Received().ReplaceAsync(Arg.Is<Cipher>(c =>
|
||||
c.GetAttachments()[v0AttachmentId].Key == null
|
||||
&&
|
||||
c.GetAttachments()[v0AttachmentId].FileName == "AFileNameEncrypted"
|
||||
&&
|
||||
c.GetAttachments()[v0AttachmentId].TempMetadata == null)
|
||||
);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData("Correct Time")]
|
||||
public async Task ShareAsync_HasSeveralV0Attachments_StartShareThrowsOnSecondOne_PerformsRollback_Rethrows(string revisionDateString,
|
||||
SutProvider<CipherService> sutProvider, Cipher cipher, Organization organization, List<Guid> collectionIds)
|
||||
{
|
||||
var lastKnownRevisionDate = string.IsNullOrEmpty(revisionDateString) ? (DateTime?)null : cipher.RevisionDate;
|
||||
var originalCipher = CoreHelpers.CloneObject(cipher);
|
||||
var cipherRepository = sutProvider.GetDependency<ICipherRepository>();
|
||||
cipherRepository.ReplaceAsync(cipher, collectionIds).Returns(true);
|
||||
var organizationRepository = sutProvider.GetDependency<IOrganizationRepository>();
|
||||
organizationRepository.GetByIdAsync(organization.Id).Returns(organization);
|
||||
var attachmentStorageService = sutProvider.GetDependency<IAttachmentStorageService>();
|
||||
var userRepository = sutProvider.GetDependency<IUserRepository>();
|
||||
var collectionCipherRepository = sutProvider.GetDependency<ICollectionCipherRepository>();
|
||||
collectionCipherRepository.GetManyByUserIdCipherIdAsync(cipher.UserId.Value, cipher.Id).Returns(
|
||||
Task.FromResult((ICollection<CollectionCipher>)new List<CollectionCipher>
|
||||
{
|
||||
new CollectionCipher
|
||||
{
|
||||
CipherId = cipher.Id,
|
||||
CollectionId = collectionIds[0]
|
||||
},
|
||||
new CollectionCipher
|
||||
{
|
||||
CipherId = cipher.Id,
|
||||
CollectionId = Guid.NewGuid()
|
||||
}
|
||||
}));
|
||||
|
||||
var v0AttachmentId1 = Guid.NewGuid().ToString();
|
||||
var v0AttachmentId2 = Guid.NewGuid().ToString();
|
||||
var anotherAttachmentId = Guid.NewGuid().ToString();
|
||||
cipher.SetAttachments(new Dictionary<string, CipherAttachment.MetaData>
|
||||
{
|
||||
[v0AttachmentId1] = new CipherAttachment.MetaData
|
||||
{
|
||||
AttachmentId = v0AttachmentId1,
|
||||
ContainerName = "attachments",
|
||||
FileName = "AFileNameEncrypted",
|
||||
TempMetadata = new CipherAttachment.MetaData
|
||||
{
|
||||
AttachmentId = v0AttachmentId1,
|
||||
ContainerName = "attachments",
|
||||
FileName = "AFileNameRe-EncryptedWithOrgKey",
|
||||
Key = "NewAttachmentKey"
|
||||
}
|
||||
},
|
||||
[v0AttachmentId2] = new CipherAttachment.MetaData
|
||||
{
|
||||
AttachmentId = v0AttachmentId2,
|
||||
ContainerName = "attachments",
|
||||
FileName = "AFileNameEncrypted2",
|
||||
TempMetadata = new CipherAttachment.MetaData
|
||||
{
|
||||
AttachmentId = v0AttachmentId2,
|
||||
ContainerName = "attachments",
|
||||
FileName = "AFileNameRe-EncryptedWithOrgKey2",
|
||||
Key = "NewAttachmentKey2"
|
||||
}
|
||||
},
|
||||
[anotherAttachmentId] = new CipherAttachment.MetaData
|
||||
{
|
||||
AttachmentId = anotherAttachmentId,
|
||||
Key = "AwesomeKey",
|
||||
FileName = "AnotherFilename",
|
||||
ContainerName = "attachments",
|
||||
Size = 300,
|
||||
Validated = true
|
||||
}
|
||||
});
|
||||
|
||||
originalCipher.SetAttachments(new Dictionary<string, CipherAttachment.MetaData>
|
||||
{
|
||||
[v0AttachmentId1] = new CipherAttachment.MetaData
|
||||
{
|
||||
AttachmentId = v0AttachmentId1,
|
||||
ContainerName = "attachments",
|
||||
FileName = "AFileNameEncrypted",
|
||||
TempMetadata = new CipherAttachment.MetaData
|
||||
{
|
||||
AttachmentId = v0AttachmentId1,
|
||||
ContainerName = "attachments",
|
||||
FileName = "AFileNameRe-EncryptedWithOrgKey",
|
||||
Key = "NewAttachmentKey"
|
||||
}
|
||||
},
|
||||
[v0AttachmentId2] = new CipherAttachment.MetaData
|
||||
{
|
||||
AttachmentId = v0AttachmentId2,
|
||||
ContainerName = "attachments",
|
||||
FileName = "AFileNameEncrypted2",
|
||||
TempMetadata = new CipherAttachment.MetaData
|
||||
{
|
||||
AttachmentId = v0AttachmentId2,
|
||||
ContainerName = "attachments",
|
||||
FileName = "AFileNameRe-EncryptedWithOrgKey2",
|
||||
Key = "NewAttachmentKey2"
|
||||
}
|
||||
},
|
||||
[anotherAttachmentId] = new CipherAttachment.MetaData
|
||||
{
|
||||
AttachmentId = anotherAttachmentId,
|
||||
Key = "AwesomeKey",
|
||||
FileName = "AnotherFilename",
|
||||
ContainerName = "attachments",
|
||||
Size = 300,
|
||||
Validated = true
|
||||
}
|
||||
});
|
||||
|
||||
attachmentStorageService.StartShareAttachmentAsync(cipher.Id,
|
||||
organization.Id,
|
||||
Arg.Is<CipherAttachment.MetaData>(m => m.AttachmentId == v0AttachmentId2))
|
||||
.Returns(Task.FromException(new InvalidOperationException("ex from StartShareAttachmentAsync")));
|
||||
|
||||
var exception = await Assert.ThrowsAsync<InvalidOperationException>(
|
||||
() => sutProvider.Sut.ShareAsync(cipher, cipher, organization.Id, collectionIds, cipher.UserId.Value,
|
||||
lastKnownRevisionDate));
|
||||
Assert.Contains("ex from StartShareAttachmentAsync", exception.Message);
|
||||
|
||||
await collectionCipherRepository.Received().UpdateCollectionsAsync(cipher.Id, cipher.UserId.Value,
|
||||
Arg.Is<List<Guid>>(ids => ids.Count == 1 && ids[0] != collectionIds[0]));
|
||||
|
||||
await cipherRepository.Received().ReplaceAsync(Arg.Is<Cipher>(c =>
|
||||
c.GetAttachments()[v0AttachmentId1].Key == null
|
||||
&&
|
||||
c.GetAttachments()[v0AttachmentId1].FileName == "AFileNameEncrypted"
|
||||
&&
|
||||
c.GetAttachments()[v0AttachmentId1].TempMetadata == null)
|
||||
);
|
||||
|
||||
await cipherRepository.Received().ReplaceAsync(Arg.Is<Cipher>(c =>
|
||||
c.GetAttachments()[v0AttachmentId2].Key == null
|
||||
&&
|
||||
c.GetAttachments()[v0AttachmentId2].FileName == "AFileNameEncrypted2"
|
||||
&&
|
||||
c.GetAttachments()[v0AttachmentId2].TempMetadata == null)
|
||||
);
|
||||
|
||||
await userRepository.UpdateStorageAsync(cipher.UserId.Value);
|
||||
await organizationRepository.UpdateStorageAsync(organization.Id);
|
||||
|
||||
await attachmentStorageService.Received().RollbackShareAttachmentAsync(cipher.Id, organization.Id,
|
||||
Arg.Is<CipherAttachment.MetaData>(m => m.AttachmentId == v0AttachmentId1), Arg.Any<string>());
|
||||
|
||||
await attachmentStorageService.Received().CleanupAsync(cipher.Id);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData("")]
|
||||
[BitAutoData("Correct Time")]
|
||||
|
Reference in New Issue
Block a user