diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj
index c2bdbb01d..2d5817788 100644
--- a/src/Core/Core.csproj
+++ b/src/Core/Core.csproj
@@ -22,6 +22,8 @@
+
+
@@ -29,12 +31,10 @@
-
-
diff --git a/src/Core/Services/Implementations/AzureAttachmentStorageService.cs b/src/Core/Services/Implementations/AzureAttachmentStorageService.cs
index c9e836091..82b4e5729 100644
--- a/src/Core/Services/Implementations/AzureAttachmentStorageService.cs
+++ b/src/Core/Services/Implementations/AzureAttachmentStorageService.cs
@@ -2,12 +2,13 @@
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
+using Azure.Storage.Blobs;
+using Azure.Storage.Blobs.Models;
+using Azure.Storage.Sas;
using Bit.Core.Enums;
using Bit.Core.Models.Data;
using Bit.Core.Models.Table;
using Bit.Core.Settings;
-using Microsoft.Azure.Storage;
-using Microsoft.Azure.Storage.Blob;
namespace Bit.Core.Services
{
@@ -18,8 +19,8 @@ namespace Bit.Core.Services
private const string _defaultContainerName = "attachments";
private readonly static string[] _attachmentContainerName = { "attachments", "attachments-v2" };
private static readonly TimeSpan blobLinkLiveTime = TimeSpan.FromMinutes(1);
- private readonly CloudBlobClient _blobClient;
- private readonly Dictionary _attachmentContainers = new Dictionary();
+ private readonly BlobServiceClient _blobServiceClient;
+ private readonly Dictionary _attachmentContainers = new Dictionary();
private string BlobName(Guid cipherId, CipherAttachment.MetaData attachmentData, Guid? organizationId = null, bool temp = false) =>
string.Concat(
temp ? "temp/" : "",
@@ -54,121 +55,122 @@ namespace Bit.Core.Services
public AzureAttachmentStorageService(
GlobalSettings globalSettings)
{
- var storageAccount = CloudStorageAccount.Parse(globalSettings.Attachment.ConnectionString);
- _blobClient = storageAccount.CreateCloudBlobClient();
+ _blobServiceClient = new BlobServiceClient(globalSettings.Attachment.ConnectionString);
}
public async Task GetAttachmentDownloadUrlAsync(Cipher cipher, CipherAttachment.MetaData attachmentData)
{
await InitAsync(attachmentData.ContainerName);
- var blob = _attachmentContainers[attachmentData.ContainerName].GetBlockBlobReference(BlobName(cipher.Id, attachmentData));
- var accessPolicy = new SharedAccessBlobPolicy()
- {
- SharedAccessExpiryTime = DateTime.UtcNow.Add(blobLinkLiveTime),
- Permissions = SharedAccessBlobPermissions.Read
- };
-
- return blob.Uri + blob.GetSharedAccessSignature(accessPolicy);
+ var blobClient = _attachmentContainers[attachmentData.ContainerName].GetBlobClient(BlobName(cipher.Id, attachmentData));
+ var sasUri = blobClient.GenerateSasUri(BlobSasPermissions.Read, DateTime.UtcNow.Add(blobLinkLiveTime));
+ return sasUri.ToString();
}
public async Task GetAttachmentUploadUrlAsync(Cipher cipher, CipherAttachment.MetaData attachmentData)
{
await InitAsync(EventGridEnabledContainerName);
- var blob = _attachmentContainers[EventGridEnabledContainerName].GetBlockBlobReference(BlobName(cipher.Id, attachmentData));
+ var blobClient = _attachmentContainers[EventGridEnabledContainerName].GetBlobClient(BlobName(cipher.Id, attachmentData));
attachmentData.ContainerName = EventGridEnabledContainerName;
- var accessPolicy = new SharedAccessBlobPolicy()
- {
- SharedAccessExpiryTime = DateTime.UtcNow.Add(blobLinkLiveTime),
- Permissions = SharedAccessBlobPermissions.Create | SharedAccessBlobPermissions.Write,
- };
-
- return blob.Uri + blob.GetSharedAccessSignature(accessPolicy);
+ var sasUri = blobClient.GenerateSasUri(BlobSasPermissions.Create | BlobSasPermissions.Write, DateTime.UtcNow.Add(blobLinkLiveTime));
+ return sasUri.ToString();
}
public async Task UploadNewAttachmentAsync(Stream stream, Cipher cipher, CipherAttachment.MetaData attachmentData)
{
attachmentData.ContainerName = _defaultContainerName;
await InitAsync(_defaultContainerName);
- var blob = _attachmentContainers[_defaultContainerName].GetBlockBlobReference(BlobName(cipher.Id, attachmentData));
- blob.Metadata.Add("cipherId", cipher.Id.ToString());
+ var blobClient = _attachmentContainers[_defaultContainerName].GetBlobClient(BlobName(cipher.Id, attachmentData));
+
+ var metadata = new Dictionary();
+ metadata.Add("cipherId", cipher.Id.ToString());
if (cipher.UserId.HasValue)
{
- blob.Metadata.Add("userId", cipher.UserId.Value.ToString());
+ metadata.Add("userId", cipher.UserId.Value.ToString());
}
else
{
- blob.Metadata.Add("organizationId", cipher.OrganizationId.Value.ToString());
+ metadata.Add("organizationId", cipher.OrganizationId.Value.ToString());
}
- blob.Properties.ContentDisposition = $"attachment; filename=\"{attachmentData.AttachmentId}\"";
- await blob.UploadFromStreamAsync(stream);
+
+ var headers = new BlobHttpHeaders
+ {
+ ContentDisposition = $"attachment; filename=\"{attachmentData.AttachmentId}\""
+ };
+ await blobClient.UploadAsync(stream, new BlobUploadOptions { Metadata = metadata, HttpHeaders = headers });
}
public async Task UploadShareAttachmentAsync(Stream stream, Guid cipherId, Guid organizationId, CipherAttachment.MetaData attachmentData)
{
attachmentData.ContainerName = _defaultContainerName;
await InitAsync(_defaultContainerName);
- var blob = _attachmentContainers[_defaultContainerName].GetBlockBlobReference(
+ var blobClient = _attachmentContainers[_defaultContainerName].GetBlobClient(
BlobName(cipherId, attachmentData, organizationId, temp: true));
- blob.Metadata.Add("cipherId", cipherId.ToString());
- blob.Metadata.Add("organizationId", organizationId.ToString());
- blob.Properties.ContentDisposition = $"attachment; filename=\"{attachmentData.AttachmentId}\"";
- await blob.UploadFromStreamAsync(stream);
+
+ var metadata = new Dictionary();
+ metadata.Add("cipherId", cipherId.ToString());
+ metadata.Add("organizationId", organizationId.ToString());
+
+ var headers = new BlobHttpHeaders
+ {
+ ContentDisposition = $"attachment; filename=\"{attachmentData.AttachmentId}\""
+ };
+ await blobClient.UploadAsync(stream, new BlobUploadOptions { Metadata = metadata, HttpHeaders = headers });
}
public async Task StartShareAttachmentAsync(Guid cipherId, Guid organizationId, CipherAttachment.MetaData data)
{
await InitAsync(data.ContainerName);
- var source = _attachmentContainers[data.ContainerName].GetBlockBlobReference(
+ var source = _attachmentContainers[data.ContainerName].GetBlobClient(
BlobName(cipherId, data, organizationId, temp: true));
- if (!(await source.ExistsAsync()))
+ if (!await source.ExistsAsync())
{
return;
}
await InitAsync(_defaultContainerName);
- var dest = _attachmentContainers[_defaultContainerName].GetBlockBlobReference(BlobName(cipherId, data));
- if (!(await dest.ExistsAsync()))
+ var dest = _attachmentContainers[_defaultContainerName].GetBlobClient(BlobName(cipherId, data));
+ if (!await dest.ExistsAsync())
{
return;
}
- var original = _attachmentContainers[_defaultContainerName].GetBlockBlobReference(
+ var original = _attachmentContainers[_defaultContainerName].GetBlobClient(
BlobName(cipherId, data, temp: true));
await original.DeleteIfExistsAsync();
- await original.StartCopyAsync(dest);
+ await original.StartCopyFromUriAsync(dest.Uri);
await dest.DeleteIfExistsAsync();
- await dest.StartCopyAsync(source);
+ await dest.StartCopyFromUriAsync(source.Uri);
}
public async Task RollbackShareAttachmentAsync(Guid cipherId, Guid organizationId, CipherAttachment.MetaData attachmentData, string originalContainer)
{
await InitAsync(attachmentData.ContainerName);
- var source = _attachmentContainers[attachmentData.ContainerName].GetBlockBlobReference(
+ var source = _attachmentContainers[attachmentData.ContainerName].GetBlobClient(
BlobName(cipherId, attachmentData, organizationId, temp: true));
await source.DeleteIfExistsAsync();
await InitAsync(originalContainer);
- var original = _attachmentContainers[originalContainer].GetBlockBlobReference(
+ var original = _attachmentContainers[originalContainer].GetBlobClient(
BlobName(cipherId, attachmentData, temp: true));
- if (!(await original.ExistsAsync()))
+ if (!await original.ExistsAsync())
{
return;
}
- var dest = _attachmentContainers[originalContainer].GetBlockBlobReference(
+ var dest = _attachmentContainers[originalContainer].GetBlobClient(
BlobName(cipherId, attachmentData));
await dest.DeleteIfExistsAsync();
- await dest.StartCopyAsync(original);
+ await dest.StartCopyFromUriAsync(original.Uri);
await original.DeleteIfExistsAsync();
}
public async Task DeleteAttachmentAsync(Guid cipherId, CipherAttachment.MetaData attachmentData)
{
await InitAsync(attachmentData.ContainerName);
- var blob = _attachmentContainers[attachmentData.ContainerName].GetBlockBlobReference(
+ var blobClient = _attachmentContainers[attachmentData.ContainerName].GetBlobClient(
BlobName(cipherId, attachmentData));
- await blob.DeleteIfExistsAsync();
+ await blobClient.DeleteIfExistsAsync();
}
public async Task CleanupAsync(Guid cipherId) => await DeleteAttachmentsForPathAsync($"temp/{cipherId}");
@@ -190,35 +192,42 @@ namespace Bit.Core.Services
{
await InitAsync(attachmentData.ContainerName);
- var blob = _attachmentContainers[attachmentData.ContainerName].GetBlockBlobReference(BlobName(cipher.Id, attachmentData));
+ var blobClient = _attachmentContainers[attachmentData.ContainerName].GetBlobClient(BlobName(cipher.Id, attachmentData));
- if (!blob.Exists())
+ try
+ {
+ var blobProperties = await blobClient.GetPropertiesAsync();
+
+ var metadata = blobProperties.Value.Metadata;
+ metadata["cipherId"] = cipher.Id.ToString();
+ if (cipher.UserId.HasValue)
+ {
+ metadata["userId"] = cipher.UserId.Value.ToString();
+ }
+ else
+ {
+ metadata["organizationId"] = cipher.OrganizationId.Value.ToString();
+ }
+ await blobClient.SetMetadataAsync(metadata);
+
+ var headers = new BlobHttpHeaders
+ {
+ ContentDisposition = $"attachment; filename=\"{attachmentData.AttachmentId}\""
+ };
+ await blobClient.SetHttpHeadersAsync(headers);
+
+ var length = blobProperties.Value.ContentLength;
+ if (length < attachmentData.Size - leeway || length > attachmentData.Size + leeway)
+ {
+ return (false, length);
+ }
+
+ return (true, length);
+ }
+ catch (Exception ex)
{
return (false, null);
}
-
- blob.FetchAttributes();
-
- blob.Metadata["cipherId"] = cipher.Id.ToString();
- if (cipher.UserId.HasValue)
- {
- blob.Metadata["userId"] = cipher.UserId.Value.ToString();
- }
- else
- {
- blob.Metadata["organizationId"] = cipher.OrganizationId.Value.ToString();
- }
- blob.Properties.ContentDisposition = $"attachment; filename=\"{attachmentData.AttachmentId}\"";
- blob.SetMetadata();
- blob.SetProperties();
-
- var length = blob.Properties.Length;
- if (length < attachmentData.Size - leeway || length > attachmentData.Size + leeway)
- {
- return (false, length);
- }
-
- return (true, length);
}
private async Task DeleteAttachmentsForPathAsync(string path)
@@ -226,24 +235,13 @@ namespace Bit.Core.Services
foreach (var container in _attachmentContainerName)
{
await InitAsync(container);
- var segment = await _attachmentContainers[container].ListBlobsSegmentedAsync(path, true, BlobListingDetails.None, 100, null, null, null);
+ var blobContainerClient = _attachmentContainers[container];
- while (true)
+ var blobItems = blobContainerClient.GetBlobsAsync(BlobTraits.None, BlobStates.None, prefix: path);
+ await foreach (var blobItem in blobItems)
{
- foreach (var blob in segment.Results)
- {
- if (blob is CloudBlockBlob blockBlob)
- {
- await blockBlob.DeleteIfExistsAsync();
- }
- }
-
- if (segment.ContinuationToken == null)
- {
- break;
- }
-
- segment = await _attachmentContainers[container].ListBlobsSegmentedAsync(segment.ContinuationToken);
+ BlobClient blobClient = blobContainerClient.GetBlobClient(blobItem.Name);
+ await blobClient.DeleteIfExistsAsync();
}
}
}
@@ -252,14 +250,14 @@ namespace Bit.Core.Services
{
if (!_attachmentContainers.ContainsKey(containerName) || _attachmentContainers[containerName] == null)
{
- _attachmentContainers[containerName] = _blobClient.GetContainerReference(containerName);
+ _attachmentContainers[containerName] = _blobServiceClient.GetBlobContainerClient(containerName);
if (containerName == "attachments")
{
- await _attachmentContainers[containerName].CreateIfNotExistsAsync(BlobContainerPublicAccessType.Blob, null, null);
+ await _attachmentContainers[containerName].CreateIfNotExistsAsync(PublicAccessType.Blob, null, null);
}
else
{
- await _attachmentContainers[containerName].CreateIfNotExistsAsync(BlobContainerPublicAccessType.Off, null, null);
+ await _attachmentContainers[containerName].CreateIfNotExistsAsync(PublicAccessType.None, null, null);
}
}
}
diff --git a/src/Core/Services/Implementations/AzureSendFileStorageService.cs b/src/Core/Services/Implementations/AzureSendFileStorageService.cs
index 9e536503b..dab251070 100644
--- a/src/Core/Services/Implementations/AzureSendFileStorageService.cs
+++ b/src/Core/Services/Implementations/AzureSendFileStorageService.cs
@@ -1,11 +1,14 @@
using System;
+using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
+using Azure;
+using Azure.Storage.Blobs;
+using Azure.Storage.Blobs.Models;
+using Azure.Storage.Sas;
using Bit.Core.Enums;
using Bit.Core.Models.Table;
using Bit.Core.Settings;
-using Microsoft.Azure.Storage;
-using Microsoft.Azure.Storage.Blob;
namespace Bit.Core.Services
{
@@ -13,8 +16,8 @@ namespace Bit.Core.Services
{
public const string FilesContainerName = "sendfiles";
private static readonly TimeSpan _downloadLinkLiveTime = TimeSpan.FromMinutes(1);
- private readonly CloudBlobClient _blobClient;
- private CloudBlobContainer _sendFilesContainer;
+ private readonly BlobServiceClient _blobServiceClient;
+ private BlobContainerClient _sendFilesContainerClient;
public FileUploadType FileUploadType => FileUploadType.Azure;
@@ -24,24 +27,31 @@ namespace Bit.Core.Services
public AzureSendFileStorageService(
GlobalSettings globalSettings)
{
- var storageAccount = CloudStorageAccount.Parse(globalSettings.Send.ConnectionString);
- _blobClient = storageAccount.CreateCloudBlobClient();
+ _blobServiceClient = new BlobServiceClient(globalSettings.Send.ConnectionString);
}
public async Task UploadNewFileAsync(Stream stream, Send send, string fileId)
{
await InitAsync();
- var blob = _sendFilesContainer.GetBlockBlobReference(BlobName(send, fileId));
+
+ var blobClient = _sendFilesContainerClient.GetBlobClient(BlobName(send, fileId));
+
+ var metadata = new Dictionary();
if (send.UserId.HasValue)
{
- blob.Metadata.Add("userId", send.UserId.Value.ToString());
+ metadata.Add("userId", send.UserId.Value.ToString());
}
else
{
- blob.Metadata.Add("organizationId", send.OrganizationId.Value.ToString());
+ metadata.Add("organizationId", send.OrganizationId.Value.ToString());
}
- blob.Properties.ContentDisposition = $"attachment; filename=\"{fileId}\"";
- await blob.UploadFromStreamAsync(stream);
+
+ var headers = new BlobHttpHeaders
+ {
+ ContentDisposition = $"attachment; filename=\"{fileId}\""
+ };
+
+ await blobClient.UploadAsync(stream, new BlobUploadOptions { Metadata = metadata, HttpHeaders = headers });
}
public async Task DeleteFileAsync(Send send, string fileId) => await DeleteBlobAsync(BlobName(send, fileId));
@@ -49,8 +59,8 @@ namespace Bit.Core.Services
public async Task DeleteBlobAsync(string blobName)
{
await InitAsync();
- var blob = _sendFilesContainer.GetBlockBlobReference(blobName);
- await blob.DeleteIfExistsAsync();
+ var blobClient = _sendFilesContainerClient.GetBlobClient(blobName);
+ await blobClient.DeleteIfExistsAsync();
}
public async Task DeleteFilesForOrganizationAsync(Guid organizationId)
@@ -66,70 +76,66 @@ namespace Bit.Core.Services
public async Task GetSendFileDownloadUrlAsync(Send send, string fileId)
{
await InitAsync();
- var blob = _sendFilesContainer.GetBlockBlobReference(BlobName(send, fileId));
- var accessPolicy = new SharedAccessBlobPolicy()
- {
- SharedAccessExpiryTime = DateTime.UtcNow.Add(_downloadLinkLiveTime),
- Permissions = SharedAccessBlobPermissions.Read,
- };
-
- return blob.Uri + blob.GetSharedAccessSignature(accessPolicy);
+ var blobClient = _sendFilesContainerClient.GetBlobClient(BlobName(send, fileId));
+ var sasUri = blobClient.GenerateSasUri(BlobSasPermissions.Read, DateTime.UtcNow.Add(_downloadLinkLiveTime));
+ return sasUri.ToString();
}
public async Task GetSendFileUploadUrlAsync(Send send, string fileId)
{
await InitAsync();
- var blob = _sendFilesContainer.GetBlockBlobReference(BlobName(send, fileId));
-
- var accessPolicy = new SharedAccessBlobPolicy()
- {
- SharedAccessExpiryTime = DateTime.UtcNow.Add(_downloadLinkLiveTime),
- Permissions = SharedAccessBlobPermissions.Create | SharedAccessBlobPermissions.Write,
- };
-
- return blob.Uri + blob.GetSharedAccessSignature(accessPolicy);
+ var blobClient = _sendFilesContainerClient.GetBlobClient(BlobName(send, fileId));
+ var sasUri = blobClient.GenerateSasUri(BlobSasPermissions.Create | BlobSasPermissions.Write, DateTime.UtcNow.Add(_downloadLinkLiveTime));
+ return sasUri.ToString();
}
public async Task<(bool, long?)> ValidateFileAsync(Send send, string fileId, long expectedFileSize, long leeway)
{
await InitAsync();
- var blob = _sendFilesContainer.GetBlockBlobReference(BlobName(send, fileId));
+ var blobClient = _sendFilesContainerClient.GetBlobClient(BlobName(send, fileId));
- if (!blob.Exists())
+ try
+ {
+ var blobProperties = await blobClient.GetPropertiesAsync();
+ var metadata = blobProperties.Value.Metadata;
+
+ if (send.UserId.HasValue)
+ {
+ metadata["userId"] = send.UserId.Value.ToString();
+ }
+ else
+ {
+ metadata["organizationId"] = send.OrganizationId.Value.ToString();
+ }
+ await blobClient.SetMetadataAsync(metadata);
+
+ var headers = new BlobHttpHeaders
+ {
+ ContentDisposition = $"attachment; filename=\"{fileId}\""
+ };
+ await blobClient.SetHttpHeadersAsync(headers);
+
+ var length = blobProperties.Value.ContentLength;
+ if (length < expectedFileSize - leeway || length > expectedFileSize + leeway)
+ {
+ return (false, length);
+ }
+
+ return (true, length);
+ }
+ catch (Exception ex)
{
return (false, null);
}
-
- blob.FetchAttributes();
-
- if (send.UserId.HasValue)
- {
- blob.Metadata["userId"] = send.UserId.Value.ToString();
- }
- else
- {
- blob.Metadata["organizationId"] = send.OrganizationId.Value.ToString();
- }
- blob.Properties.ContentDisposition = $"attachment; filename=\"{fileId}\"";
- blob.SetMetadata();
- blob.SetProperties();
-
- var length = blob.Properties.Length;
- if (length < expectedFileSize - leeway || length > expectedFileSize + leeway)
- {
- return (false, length);
- }
-
- return (true, length);
}
private async Task InitAsync()
{
- if (_sendFilesContainer == null)
+ if (_sendFilesContainerClient == null)
{
- _sendFilesContainer = _blobClient.GetContainerReference(FilesContainerName);
- await _sendFilesContainer.CreateIfNotExistsAsync(BlobContainerPublicAccessType.Off, null, null);
+ _sendFilesContainerClient = _blobServiceClient.GetBlobContainerClient(FilesContainerName);
+ await _sendFilesContainerClient.CreateIfNotExistsAsync(PublicAccessType.None, null, null);
}
}
}
diff --git a/src/Core/Services/Implementations/LicensingService.cs b/src/Core/Services/Implementations/LicensingService.cs
index 6254646ee..ad7ec0988 100644
--- a/src/Core/Services/Implementations/LicensingService.cs
+++ b/src/Core/Services/Implementations/LicensingService.cs
@@ -11,7 +11,6 @@ using Bit.Core.Repositories;
using Bit.Core.Settings;
using Bit.Core.Utilities;
using Microsoft.AspNetCore.Hosting;
-using Microsoft.Azure.Storage;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
@@ -57,8 +56,7 @@ namespace Bit.Core.Services
else if (CoreHelpers.SettingHasValue(_globalSettings.Storage?.ConnectionString) &&
CoreHelpers.SettingHasValue(_globalSettings.LicenseCertificatePassword))
{
- var storageAccount = CloudStorageAccount.Parse(globalSettings.Storage.ConnectionString);
- _certificate = CoreHelpers.GetBlobCertificateAsync(storageAccount, "certificates",
+ _certificate = CoreHelpers.GetBlobCertificateAsync(globalSettings.Storage.ConnectionString, "certificates",
"licensing.pfx", _globalSettings.LicenseCertificatePassword)
.GetAwaiter().GetResult();
}
diff --git a/src/Core/Utilities/CoreHelpers.cs b/src/Core/Utilities/CoreHelpers.cs
index 42202227e..92e237d74 100644
--- a/src/Core/Utilities/CoreHelpers.cs
+++ b/src/Core/Utilities/CoreHelpers.cs
@@ -10,10 +10,11 @@ using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
-using System.Threading;
using System.Threading.Tasks;
using System.Web;
-using Azure.Storage.Queues;
+using Azure;
+using Azure.Storage.Blobs;
+using Azure.Storage.Blobs.Models;
using Azure.Storage.Queues.Models;
using Bit.Core.Context;
using Bit.Core.Enums;
@@ -24,8 +25,6 @@ using Bit.Core.Settings;
using Dapper;
using IdentityModel;
using Microsoft.AspNetCore.DataProtection;
-using Microsoft.Azure.Storage;
-using Microsoft.Azure.Storage.Blob;
using MimeKit;
using Newtonsoft.Json;
@@ -253,22 +252,27 @@ namespace Bit.Core.Utilities
}
}
- public async static Task GetBlobCertificateAsync(CloudStorageAccount cloudStorageAccount,
- string container, string file, string password)
+ public async static Task GetBlobCertificateAsync(string connectionString, string container, string file, string password)
{
- var blobClient = cloudStorageAccount.CreateCloudBlobClient();
- var containerRef = blobClient.GetContainerReference(container);
- if (await containerRef.ExistsAsync().ConfigureAwait(false))
+ try
{
- var blobRef = containerRef.GetBlobReference(file);
- if (await blobRef.ExistsAsync().ConfigureAwait(false))
- {
- var blobBytes = new byte[blobRef.Properties.Length];
- await blobRef.DownloadToByteArrayAsync(blobBytes, 0).ConfigureAwait(false);
- return new X509Certificate2(blobBytes, password);
- }
+ var blobServiceClient = new BlobServiceClient(connectionString);
+ var containerRef2 = blobServiceClient.GetBlobContainerClient(container);
+ var blobRef = containerRef2.GetBlobClient(file);
+
+ using var memStream = new MemoryStream();
+ await blobRef.DownloadToAsync(memStream).ConfigureAwait(false);
+ return new X509Certificate2(memStream.ToArray(), password);
+ }
+ catch (RequestFailedException ex)
+ when (ex.ErrorCode == BlobErrorCode.ContainerNotFound || ex.ErrorCode == BlobErrorCode.BlobNotFound)
+ {
+ return null;
+ }
+ catch (Exception)
+ {
+ return null;
}
- return null;
}
public static long ToEpocMilliseconds(DateTime date)
@@ -756,8 +760,7 @@ namespace Bit.Core.Utilities
SettingHasValue(globalSettings.Storage?.ConnectionString) &&
SettingHasValue(globalSettings.IdentityServer.CertificatePassword))
{
- var storageAccount = CloudStorageAccount.Parse(globalSettings.Storage.ConnectionString);
- return GetBlobCertificateAsync(storageAccount, "certificates",
+ return GetBlobCertificateAsync(globalSettings.Storage.ConnectionString, "certificates",
"identity.pfx", globalSettings.IdentityServer.CertificatePassword).GetAwaiter().GetResult();
}
return null;
diff --git a/src/Core/Utilities/ServiceCollectionExtensions.cs b/src/Core/Utilities/ServiceCollectionExtensions.cs
index c9bf1f8a7..8e28f5a6a 100644
--- a/src/Core/Utilities/ServiceCollectionExtensions.cs
+++ b/src/Core/Utilities/ServiceCollectionExtensions.cs
@@ -28,7 +28,6 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc.Localization;
-using Microsoft.Azure.Storage;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
@@ -471,7 +470,7 @@ namespace Bit.Core.Utilities
public static void AddCustomDataProtectionServices(
this IServiceCollection services, IWebHostEnvironment env, GlobalSettings globalSettings)
{
- var builder = services.AddDataProtection().SetApplicationName("Bitwarden");
+ var builder = services.AddDataProtection(options => options.ApplicationDiscriminator = "Bitwarden");
if (env.IsDevelopment())
{
return;
@@ -484,7 +483,6 @@ namespace Bit.Core.Utilities
if (!globalSettings.SelfHosted && CoreHelpers.SettingHasValue(globalSettings.Storage?.ConnectionString))
{
- var storageAccount = CloudStorageAccount.Parse(globalSettings.Storage.ConnectionString);
X509Certificate2 dataProtectionCert = null;
if (CoreHelpers.SettingHasValue(globalSettings.DataProtection.CertificateThumbprint))
{
@@ -493,12 +491,13 @@ namespace Bit.Core.Utilities
}
else if (CoreHelpers.SettingHasValue(globalSettings.DataProtection.CertificatePassword))
{
- dataProtectionCert = CoreHelpers.GetBlobCertificateAsync(storageAccount, "certificates",
+ dataProtectionCert = CoreHelpers.GetBlobCertificateAsync(globalSettings.Storage.ConnectionString, "certificates",
"dataprotection.pfx", globalSettings.DataProtection.CertificatePassword)
.GetAwaiter().GetResult();
}
+ //TODO djsmith85 Check if this is the correct container name
builder
- .PersistKeysToAzureBlobStorage(storageAccount, "aspnet-dataprotection/keys.xml")
+ .PersistKeysToAzureBlobStorage(globalSettings.Storage.ConnectionString, "aspnet-dataprotection", "keys.xml")
.ProtectKeysWithCertificate(dataProtectionCert);
}
}