Files
server/src/Core/Services/Implementations/AzureAttachmentStorageService.cs

170 lines
6.1 KiB
C#
Raw Normal View History

using System.Threading.Tasks;
2020-01-10 08:33:13 -05:00
using Microsoft.Azure.Storage;
using Microsoft.Azure.Storage.Blob;
using System.IO;
2017-07-10 14:30:12 -04:00
using System;
2017-07-10 17:08:50 -04:00
using Bit.Core.Models.Table;
namespace Bit.Core.Services
{
public class AzureAttachmentStorageService : IAttachmentStorageService
{
private const string AttchmentContainerName = "attachments";
private readonly CloudBlobClient _blobClient;
private CloudBlobContainer _attachmentsContainer;
public AzureAttachmentStorageService(
GlobalSettings globalSettings)
{
2017-06-30 23:01:41 -04:00
var storageAccount = CloudStorageAccount.Parse(globalSettings.Attachment.ConnectionString);
_blobClient = storageAccount.CreateCloudBlobClient();
}
2017-07-10 20:48:06 -04:00
public async Task UploadNewAttachmentAsync(Stream stream, Cipher cipher, string attachmentId)
2017-07-10 14:30:12 -04:00
{
2017-07-10 17:08:50 -04:00
await InitAsync();
var blob = _attachmentsContainer.GetBlockBlobReference($"{cipher.Id}/{attachmentId}");
blob.Metadata.Add("cipherId", cipher.Id.ToString());
if(cipher.UserId.HasValue)
{
blob.Metadata.Add("userId", cipher.UserId.Value.ToString());
}
else
{
blob.Metadata.Add("organizationId", cipher.OrganizationId.Value.ToString());
}
2018-11-06 21:43:34 -05:00
blob.Properties.ContentDisposition = $"attachment; filename=\"{attachmentId}\"";
2017-07-10 17:08:50 -04:00
await blob.UploadFromStreamAsync(stream);
2017-07-10 14:30:12 -04:00
}
public async Task UploadShareAttachmentAsync(Stream stream, Guid cipherId, Guid organizationId, string attachmentId)
{
2017-07-10 17:08:50 -04:00
await InitAsync();
2017-07-10 20:48:06 -04:00
var blob = _attachmentsContainer.GetBlockBlobReference($"temp/{cipherId}/{organizationId}/{attachmentId}");
2017-07-10 17:08:50 -04:00
blob.Metadata.Add("cipherId", cipherId.ToString());
blob.Metadata.Add("organizationId", organizationId.ToString());
2018-11-06 21:43:34 -05:00
blob.Properties.ContentDisposition = $"attachment; filename=\"{attachmentId}\"";
2017-07-10 17:08:50 -04:00
await blob.UploadFromStreamAsync(stream);
2017-07-10 14:30:12 -04:00
}
public async Task StartShareAttachmentAsync(Guid cipherId, Guid organizationId, string attachmentId)
{
await InitAsync();
2017-07-10 20:48:06 -04:00
var source = _attachmentsContainer.GetBlockBlobReference($"temp/{cipherId}/{organizationId}/{attachmentId}");
2017-07-10 16:21:18 -04:00
if(!(await source.ExistsAsync()))
2017-07-10 14:30:12 -04:00
{
return;
}
var dest = _attachmentsContainer.GetBlockBlobReference($"{cipherId}/{attachmentId}");
2017-07-10 16:21:18 -04:00
if(!(await dest.ExistsAsync()))
2017-07-10 14:30:12 -04:00
{
return;
}
2017-07-10 20:48:06 -04:00
var original = _attachmentsContainer.GetBlockBlobReference($"temp/{cipherId}/{attachmentId}");
2017-07-10 14:30:12 -04:00
await original.DeleteIfExistsAsync();
await original.StartCopyAsync(dest);
await dest.DeleteIfExistsAsync();
await dest.StartCopyAsync(source);
}
public async Task RollbackShareAttachmentAsync(Guid cipherId, Guid organizationId, string attachmentId)
{
await InitAsync();
2017-07-10 20:48:06 -04:00
var source = _attachmentsContainer.GetBlockBlobReference($"temp/{cipherId}/{organizationId}/{attachmentId}");
2017-07-10 16:21:18 -04:00
await source.DeleteIfExistsAsync();
2017-07-10 20:48:06 -04:00
var original = _attachmentsContainer.GetBlockBlobReference($"temp/{cipherId}/{attachmentId}");
2017-07-10 16:21:18 -04:00
if(!(await original.ExistsAsync()))
2017-07-10 14:30:12 -04:00
{
return;
}
2017-07-10 16:21:18 -04:00
var dest = _attachmentsContainer.GetBlockBlobReference($"{cipherId}/{attachmentId}");
2017-07-10 14:30:12 -04:00
await dest.DeleteIfExistsAsync();
await dest.StartCopyAsync(original);
await original.DeleteIfExistsAsync();
}
public async Task DeleteAttachmentAsync(Guid cipherId, string attachmentId)
{
await InitAsync();
var blobName = $"{cipherId}/{attachmentId}";
var blob = _attachmentsContainer.GetBlockBlobReference(blobName);
await blob.DeleteIfExistsAsync();
}
2017-07-10 20:48:06 -04:00
public async Task CleanupAsync(Guid cipherId)
2017-07-10 14:30:12 -04:00
{
await InitAsync();
var segment = await _attachmentsContainer.ListBlobsSegmentedAsync($"temp/{cipherId}", true,
BlobListingDetails.None, 100, null, null, null);
while(true)
2017-07-10 17:08:50 -04:00
{
foreach(var blob in segment.Results)
2017-07-10 20:48:06 -04:00
{
if(blob is CloudBlockBlob blockBlob)
{
await blockBlob.DeleteIfExistsAsync();
}
2017-07-10 20:48:06 -04:00
}
if(segment.ContinuationToken == null)
{
break;
}
segment = await _attachmentsContainer.ListBlobsSegmentedAsync(segment.ContinuationToken);
2017-07-10 17:08:50 -04:00
}
2017-07-10 20:48:06 -04:00
}
2017-07-10 17:08:50 -04:00
2017-07-10 20:48:06 -04:00
public async Task DeleteAttachmentsForCipherAsync(Guid cipherId)
{
await InitAsync();
var segment = await _attachmentsContainer.ListBlobsSegmentedAsync(cipherId.ToString(), true,
BlobListingDetails.None, 100, null, null, null);
while(true)
2017-07-10 17:08:50 -04:00
{
foreach(var blob in segment.Results)
2017-07-10 20:48:06 -04:00
{
if(blob is CloudBlockBlob blockBlob)
{
await blockBlob.DeleteIfExistsAsync();
}
2017-07-10 20:48:06 -04:00
}
if(segment.ContinuationToken == null)
{
break;
}
segment = await _attachmentsContainer.ListBlobsSegmentedAsync(segment.ContinuationToken);
2017-07-10 17:08:50 -04:00
}
}
public async Task DeleteAttachmentsForOrganizationAsync(Guid organizationId)
{
await InitAsync();
}
public async Task DeleteAttachmentsForUserAsync(Guid userId)
{
await InitAsync();
2017-07-10 14:30:12 -04:00
}
private async Task InitAsync()
{
if(_attachmentsContainer == null)
{
_attachmentsContainer = _blobClient.GetContainerReference(AttchmentContainerName);
2017-06-30 23:01:41 -04:00
await _attachmentsContainer.CreateIfNotExistsAsync(BlobContainerPublicAccessType.Blob, null, null);
}
}
}
}