From de8b2de8e6d2d8fd82dfb812b8d9f703b0ef497c Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Mon, 10 Jul 2017 20:48:06 -0400 Subject: [PATCH] attachment cleanup --- .../Services/IAttachmentStorageService.cs | 5 +- .../AzureAttachmentStorageService.cs | 46 +++++++++---------- .../Services/Implementations/CipherService.cs | 13 ++---- .../NoopAttachmentStorageService.cs | 17 ++++++- 4 files changed, 45 insertions(+), 36 deletions(-) diff --git a/src/Core/Services/IAttachmentStorageService.cs b/src/Core/Services/IAttachmentStorageService.cs index 611449058..cd5183b8e 100644 --- a/src/Core/Services/IAttachmentStorageService.cs +++ b/src/Core/Services/IAttachmentStorageService.cs @@ -10,8 +10,11 @@ namespace Bit.Core.Services Task UploadNewAttachmentAsync(Stream stream, Cipher cipher, string attachmentId); Task UploadShareAttachmentAsync(Stream stream, Guid cipherId, Guid organizationId, string attachmentId); Task StartShareAttachmentAsync(Guid cipherId, Guid organizationId, string attachmentId); - Task CommitShareAttachmentAsync(Guid cipherId, Guid organizationId, string attachmentId); Task RollbackShareAttachmentAsync(Guid cipherId, Guid organizationId, string attachmentId); + Task CleanupAsync(Guid cipherId); Task DeleteAttachmentAsync(Guid cipherId, string attachmentId); + Task DeleteAttachmentsForCipherAsync(Guid cipherId); + Task DeleteAttachmentsForOrganizationAsync(Guid organizationId); + Task DeleteAttachmentsForUserAsync(Guid userId); } } diff --git a/src/Core/Services/Implementations/AzureAttachmentStorageService.cs b/src/Core/Services/Implementations/AzureAttachmentStorageService.cs index b528b7f91..7887840f7 100644 --- a/src/Core/Services/Implementations/AzureAttachmentStorageService.cs +++ b/src/Core/Services/Implementations/AzureAttachmentStorageService.cs @@ -21,7 +21,7 @@ namespace Bit.Core.Services _blobClient = storageAccount.CreateCloudBlobClient(); } - public async Task UploadUserAttachmentAsync(Stream stream, Cipher cipher, string attachmentId) + public async Task UploadNewAttachmentAsync(Stream stream, Cipher cipher, string attachmentId) { await InitAsync(); var blob = _attachmentsContainer.GetBlockBlobReference($"{cipher.Id}/{attachmentId}"); @@ -40,7 +40,7 @@ namespace Bit.Core.Services public async Task UploadShareAttachmentAsync(Stream stream, Guid cipherId, Guid organizationId, string attachmentId) { await InitAsync(); - var blob = _attachmentsContainer.GetBlockBlobReference($"{cipherId}/temp/{organizationId}/{attachmentId}"); + var blob = _attachmentsContainer.GetBlockBlobReference($"temp/{cipherId}/{organizationId}/{attachmentId}"); blob.Metadata.Add("cipherId", cipherId.ToString()); blob.Metadata.Add("organizationId", organizationId.ToString()); await blob.UploadFromStreamAsync(stream); @@ -49,7 +49,7 @@ namespace Bit.Core.Services public async Task StartShareAttachmentAsync(Guid cipherId, Guid organizationId, string attachmentId) { await InitAsync(); - var source = _attachmentsContainer.GetBlockBlobReference($"{cipherId}/temp/{organizationId}/{attachmentId}"); + var source = _attachmentsContainer.GetBlockBlobReference($"temp/{cipherId}/{organizationId}/{attachmentId}"); if(!(await source.ExistsAsync())) { return; @@ -61,7 +61,7 @@ namespace Bit.Core.Services return; } - var original = _attachmentsContainer.GetBlockBlobReference($"{cipherId}/temp/{attachmentId}"); + var original = _attachmentsContainer.GetBlockBlobReference($"temp/{cipherId}/{attachmentId}"); await original.DeleteIfExistsAsync(); await original.StartCopyAsync(dest); @@ -69,22 +69,13 @@ namespace Bit.Core.Services await dest.StartCopyAsync(source); } - public async Task CommitShareAttachmentAsync(Guid cipherId, Guid organizationId, string attachmentId) - { - await InitAsync(); - var source = _attachmentsContainer.GetBlockBlobReference($"{cipherId}/temp/{organizationId}/{attachmentId}"); - var original = _attachmentsContainer.GetBlockBlobReference($"{cipherId}/temp/{attachmentId}"); - await original.DeleteIfExistsAsync(); - await source.DeleteIfExistsAsync(); - } - public async Task RollbackShareAttachmentAsync(Guid cipherId, Guid organizationId, string attachmentId) { await InitAsync(); - var source = _attachmentsContainer.GetBlockBlobReference($"{cipherId}/temp/{organizationId}/{attachmentId}"); + var source = _attachmentsContainer.GetBlockBlobReference($"temp/{cipherId}/{organizationId}/{attachmentId}"); await source.DeleteIfExistsAsync(); - var original = _attachmentsContainer.GetBlockBlobReference($"{cipherId}/temp/{attachmentId}"); + var original = _attachmentsContainer.GetBlockBlobReference($"temp/{cipherId}/{attachmentId}"); if(!(await original.ExistsAsync())) { return; @@ -104,33 +95,38 @@ namespace Bit.Core.Services await blob.DeleteIfExistsAsync(); } - public async Task DeleteAttachmentsAsync(Cipher cipher) + public async Task CleanupAsync(Guid cipherId) { await InitAsync(); - var attachments = cipher.GetAttachments(); - if(attachments == null) + foreach(var blob in _attachmentsContainer.ListBlobs($"temp/{cipherId}", true)) { - return; + if(blob is CloudBlockBlob blockBlob) + { + await blockBlob.DeleteIfExistsAsync(); + } } + } - foreach(var attachment in attachments) + public async Task DeleteAttachmentsForCipherAsync(Guid cipherId) + { + await InitAsync(); + foreach(var blob in _attachmentsContainer.ListBlobs(cipherId.ToString(), true)) { - var blobName = $"{cipher.Id}/{attachment.Key}"; - var blob = _attachmentsContainer.GetBlockBlobReference(blobName); - await blob.DeleteIfExistsAsync(); + if(blob is CloudBlockBlob blockBlob) + { + await blockBlob.DeleteIfExistsAsync(); + } } } public async Task DeleteAttachmentsForOrganizationAsync(Guid organizationId) { await InitAsync(); - } public async Task DeleteAttachmentsForUserAsync(Guid userId) { await InitAsync(); - } private async Task InitAsync() diff --git a/src/Core/Services/Implementations/CipherService.cs b/src/Core/Services/Implementations/CipherService.cs index e094d99fe..08f2b0f32 100644 --- a/src/Core/Services/Implementations/CipherService.cs +++ b/src/Core/Services/Implementations/CipherService.cs @@ -208,11 +208,7 @@ namespace Bit.Core.Services } catch { - foreach(var attachment in cipher.GetAttachments()) - { - await _attachmentStorageService.RollbackShareAttachmentAsync(cipher.Id, organizationId, attachment.Key); - } - + await _attachmentStorageService.CleanupAsync(cipher.Id); throw; } } @@ -225,6 +221,7 @@ namespace Bit.Core.Services } await _cipherRepository.DeleteAsync(cipher); + await _attachmentStorageService.DeleteAttachmentsForCipherAsync(cipher.Id); // push await _pushService.PushSyncCipherDeleteAsync(cipher); @@ -379,14 +376,12 @@ namespace Bit.Core.Services await _attachmentStorageService.RollbackShareAttachmentAsync(cipher.Id, organizationId, attachment.Key); } + await _attachmentStorageService.CleanupAsync(cipher.Id); throw; } // commit attachment migration - foreach(var attachment in attachments) - { - await _attachmentStorageService.CommitShareAttachmentAsync(cipher.Id, organizationId, attachment.Key); - } + await _attachmentStorageService.CleanupAsync(cipher.Id); // push await _pushService.PushSyncCipherUpdateAsync(cipher); diff --git a/src/Core/Services/NoopImplementations/NoopAttachmentStorageService.cs b/src/Core/Services/NoopImplementations/NoopAttachmentStorageService.cs index 59318d8be..29f781979 100644 --- a/src/Core/Services/NoopImplementations/NoopAttachmentStorageService.cs +++ b/src/Core/Services/NoopImplementations/NoopAttachmentStorageService.cs @@ -7,7 +7,7 @@ namespace Bit.Core.Services { public class NoopAttachmentStorageService : IAttachmentStorageService { - public Task CommitShareAttachmentAsync(Guid cipherId, Guid organizationId, string attachmentId) + public Task CleanupAsync(Guid cipherId) { return Task.FromResult(0); } @@ -17,6 +17,21 @@ namespace Bit.Core.Services return Task.FromResult(0); } + public Task DeleteAttachmentsForCipherAsync(Guid cipherId) + { + return Task.FromResult(0); + } + + public Task DeleteAttachmentsForOrganizationAsync(Guid organizationId) + { + return Task.FromResult(0); + } + + public Task DeleteAttachmentsForUserAsync(Guid userId) + { + return Task.FromResult(0); + } + public Task RollbackShareAttachmentAsync(Guid cipherId, Guid organizationId, string attachmentId) { return Task.FromResult(0);