diff --git a/eng/Dependencies.props b/eng/Dependencies.props index 6e8e7b9a8b..ecee11a86f 100644 --- a/eng/Dependencies.props +++ b/eng/Dependencies.props @@ -162,10 +162,6 @@ and are generated based on the last package release. - - - - diff --git a/eng/ProjectReferences.props b/eng/ProjectReferences.props index f71e3d1d72..d5180da8df 100644 --- a/eng/ProjectReferences.props +++ b/eng/ProjectReferences.props @@ -6,8 +6,6 @@ - - diff --git a/eng/Versions.props b/eng/Versions.props index 3142e4c0ba..ab943e029e 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -189,8 +189,6 @@ 5.2.6 3.1.1-preview4.19614.4 - 2.3.2 - 10.0.1 1.0.0 15.8.166 1.2.0 @@ -200,8 +198,6 @@ 3.0.0 3.0.0 3.0.0 - 5.8.4 - 5.8.4 3.19.8 5.5.0 5.5.0 diff --git a/eng/scripts/RunHelix.ps1 b/eng/scripts/RunHelix.ps1 index 177580d3ea..9e1bc513a2 100644 --- a/eng/scripts/RunHelix.ps1 +++ b/eng/scripts/RunHelix.ps1 @@ -25,6 +25,7 @@ param( [Parameter(Mandatory=$true)] [string]$Project, [string]$HelixQueues = "Windows.10.Amd64.Open", + [string]$TargetArchitecture = "", [bool]$RunQuarantinedTests = $false ) $ErrorActionPreference = 'Stop' @@ -38,4 +39,4 @@ $env:BUILD_REPOSITORY_NAME="aspnetcore" $env:SYSTEM_TEAMPROJECT="aspnetcore" $HelixQueues = $HelixQueues -replace ";", "%3B" -dotnet msbuild $Project /t:Helix /p:IsRequiredCheck=true /p:IsHelixDaily=true /p:HelixTargetQueues=$HelixQueues /p:RunQuarantinedTests=$RunQuarantinedTests /p:_UseHelixOpenQueues=true \ No newline at end of file +dotnet msbuild $Project /t:Helix /p:TargetArchitecture="$TargetArchitecture" /p:IsRequiredCheck=true /p:IsHelixDaily=true /p:HelixTargetQueues=$HelixQueues /p:RunQuarantinedTests=$RunQuarantinedTests /p:_UseHelixOpenQueues=true \ No newline at end of file diff --git a/src/DataProtection/AzureKeyVault/src/AzureDataProtectionBuilderExtensions.cs b/src/DataProtection/AzureKeyVault/src/AzureDataProtectionBuilderExtensions.cs deleted file mode 100644 index 0701220b4b..0000000000 --- a/src/DataProtection/AzureKeyVault/src/AzureDataProtectionBuilderExtensions.cs +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Security.Cryptography.X509Certificates; -using System.Threading.Tasks; -using Microsoft.AspNetCore.DataProtection.AzureKeyVault; -using Microsoft.AspNetCore.DataProtection.KeyManagement; -using Microsoft.Azure.KeyVault; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.IdentityModel.Clients.ActiveDirectory; - -namespace Microsoft.AspNetCore.DataProtection -{ - /// - /// Contains Azure KeyVault-specific extension methods for modifying a . - /// - public static class AzureDataProtectionBuilderExtensions - { - /// - /// Configures the data protection system to protect keys with specified key in Azure KeyVault. - /// - /// The builder instance to modify. - /// The Azure KeyVault key identifier used for key encryption. - /// The application client id. - /// - /// The value . - public static IDataProtectionBuilder ProtectKeysWithAzureKeyVault(this IDataProtectionBuilder builder, string keyIdentifier, string clientId, X509Certificate2 certificate) - { - if (string.IsNullOrEmpty(clientId)) - { - throw new ArgumentException(nameof(clientId)); - } - if (certificate == null) - { - throw new ArgumentNullException(nameof(certificate)); - } - - KeyVaultClient.AuthenticationCallback callback = - (authority, resource, scope) => GetTokenFromClientCertificate(authority, resource, clientId, certificate); - - return ProtectKeysWithAzureKeyVault(builder, new KeyVaultClient(callback), keyIdentifier); - } - - private static async Task GetTokenFromClientCertificate(string authority, string resource, string clientId, X509Certificate2 certificate) - { - var authContext = new AuthenticationContext(authority); - var result = await authContext.AcquireTokenAsync(resource, new ClientAssertionCertificate(clientId, certificate)); - return result.AccessToken; - } - - /// - /// Configures the data protection system to protect keys with specified key in Azure KeyVault. - /// - /// The builder instance to modify. - /// The Azure KeyVault key identifier used for key encryption. - /// The application client id. - /// The client secret to use for authentication. - /// The value . - public static IDataProtectionBuilder ProtectKeysWithAzureKeyVault(this IDataProtectionBuilder builder, string keyIdentifier, string clientId, string clientSecret) - { - if (string.IsNullOrEmpty(clientId)) - { - throw new ArgumentNullException(nameof(clientId)); - } - if (string.IsNullOrEmpty(clientSecret)) - { - throw new ArgumentNullException(nameof(clientSecret)); - } - - KeyVaultClient.AuthenticationCallback callback = - (authority, resource, scope) => GetTokenFromClientSecret(authority, resource, clientId, clientSecret); - - return ProtectKeysWithAzureKeyVault(builder, new KeyVaultClient(callback), keyIdentifier); - } - - private static async Task GetTokenFromClientSecret(string authority, string resource, string clientId, string clientSecret) - { - var authContext = new AuthenticationContext(authority); - var clientCred = new ClientCredential(clientId, clientSecret); - var result = await authContext.AcquireTokenAsync(resource, clientCred); - return result.AccessToken; - } - - /// - /// Configures the data protection system to protect keys with specified key in Azure KeyVault. - /// - /// The builder instance to modify. - /// The to use for KeyVault access. - /// The Azure KeyVault key identifier used for key encryption. - /// The value . - public static IDataProtectionBuilder ProtectKeysWithAzureKeyVault(this IDataProtectionBuilder builder, KeyVaultClient client, string keyIdentifier) - { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } - if (client == null) - { - throw new ArgumentNullException(nameof(client)); - } - if (string.IsNullOrEmpty(keyIdentifier)) - { - throw new ArgumentException(nameof(keyIdentifier)); - } - - var vaultClientWrapper = new KeyVaultClientWrapper(client); - - builder.Services.AddSingleton(vaultClientWrapper); - builder.Services.Configure(options => - { - options.XmlEncryptor = new AzureKeyVaultXmlEncryptor(vaultClientWrapper, keyIdentifier); - }); - - return builder; - } - } -} \ No newline at end of file diff --git a/src/DataProtection/AzureKeyVault/src/AzureKeyVaultXmlDecryptor.cs b/src/DataProtection/AzureKeyVault/src/AzureKeyVaultXmlDecryptor.cs deleted file mode 100644 index b9942fa84f..0000000000 --- a/src/DataProtection/AzureKeyVault/src/AzureKeyVaultXmlDecryptor.cs +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using System.Threading.Tasks; -using System.Xml.Linq; -using Microsoft.AspNetCore.DataProtection.XmlEncryption; -using Microsoft.Extensions.DependencyInjection; - -namespace Microsoft.AspNetCore.DataProtection.AzureKeyVault -{ - internal class AzureKeyVaultXmlDecryptor: IXmlDecryptor - { - private readonly IKeyVaultWrappingClient _client; - - public AzureKeyVaultXmlDecryptor(IServiceProvider serviceProvider) - { - _client = serviceProvider.GetService(); - } - - public XElement Decrypt(XElement encryptedElement) - { - return DecryptAsync(encryptedElement).GetAwaiter().GetResult(); - } - - private async Task DecryptAsync(XElement encryptedElement) - { - var kid = (string)encryptedElement.Element("kid"); - var symmetricKey = Convert.FromBase64String((string)encryptedElement.Element("key")); - var symmetricIV = Convert.FromBase64String((string)encryptedElement.Element("iv")); - - var encryptedValue = Convert.FromBase64String((string)encryptedElement.Element("value")); - - var result = await _client.UnwrapKeyAsync(kid, AzureKeyVaultXmlEncryptor.DefaultKeyEncryption, symmetricKey); - - byte[] decryptedValue; - using (var symmetricAlgorithm = AzureKeyVaultXmlEncryptor.DefaultSymmetricAlgorithmFactory()) - { - using (var decryptor = symmetricAlgorithm.CreateDecryptor(result.Result, symmetricIV)) - { - decryptedValue = decryptor.TransformFinalBlock(encryptedValue, 0, encryptedValue.Length); - } - } - - using (var memoryStream = new MemoryStream(decryptedValue)) - { - return XElement.Load(memoryStream); - } - } - } -} \ No newline at end of file diff --git a/src/DataProtection/AzureKeyVault/src/AzureKeyVaultXmlEncryptor.cs b/src/DataProtection/AzureKeyVault/src/AzureKeyVaultXmlEncryptor.cs deleted file mode 100644 index 3451c3ded2..0000000000 --- a/src/DataProtection/AzureKeyVault/src/AzureKeyVaultXmlEncryptor.cs +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using System.Security.Cryptography; -using System.Threading.Tasks; -using System.Xml.Linq; -using Microsoft.AspNetCore.DataProtection.XmlEncryption; -using Microsoft.Azure.KeyVault.WebKey; - -namespace Microsoft.AspNetCore.DataProtection.AzureKeyVault -{ - internal class AzureKeyVaultXmlEncryptor : IXmlEncryptor - { - internal static string DefaultKeyEncryption = JsonWebKeyEncryptionAlgorithm.RSAOAEP; - internal static Func DefaultSymmetricAlgorithmFactory = Aes.Create; - - private readonly RandomNumberGenerator _randomNumberGenerator; - private readonly IKeyVaultWrappingClient _client; - private readonly string _keyId; - - public AzureKeyVaultXmlEncryptor(IKeyVaultWrappingClient client, string keyId) - : this(client, keyId, RandomNumberGenerator.Create()) - { - } - - internal AzureKeyVaultXmlEncryptor(IKeyVaultWrappingClient client, string keyId, RandomNumberGenerator randomNumberGenerator) - { - _client = client; - _keyId = keyId; - _randomNumberGenerator = randomNumberGenerator; - } - - public EncryptedXmlInfo Encrypt(XElement plaintextElement) - { - return EncryptAsync(plaintextElement).GetAwaiter().GetResult(); - } - - private async Task EncryptAsync(XElement plaintextElement) - { - byte[] value; - using (var memoryStream = new MemoryStream()) - { - plaintextElement.Save(memoryStream, SaveOptions.DisableFormatting); - value = memoryStream.ToArray(); - } - - using (var symmetricAlgorithm = DefaultSymmetricAlgorithmFactory()) - { - var symmetricBlockSize = symmetricAlgorithm.BlockSize / 8; - var symmetricKey = new byte[symmetricBlockSize]; - var symmetricIV = new byte[symmetricBlockSize]; - _randomNumberGenerator.GetBytes(symmetricKey); - _randomNumberGenerator.GetBytes(symmetricIV); - - byte[] encryptedValue; - using (var encryptor = symmetricAlgorithm.CreateEncryptor(symmetricKey, symmetricIV)) - { - encryptedValue = encryptor.TransformFinalBlock(value, 0, value.Length); - } - - var wrappedKey = await _client.WrapKeyAsync(_keyId, DefaultKeyEncryption, symmetricKey); - - var element = new XElement("encryptedKey", - new XComment(" This key is encrypted with Azure KeyVault. "), - new XElement("kid", wrappedKey.Kid), - new XElement("key", Convert.ToBase64String(wrappedKey.Result)), - new XElement("iv", Convert.ToBase64String(symmetricIV)), - new XElement("value", Convert.ToBase64String(encryptedValue))); - - return new EncryptedXmlInfo(element, typeof(AzureKeyVaultXmlDecryptor)); - } - - } - } -} diff --git a/src/DataProtection/AzureKeyVault/src/IKeyVaultWrappingClient.cs b/src/DataProtection/AzureKeyVault/src/IKeyVaultWrappingClient.cs deleted file mode 100644 index 2347460dc3..0000000000 --- a/src/DataProtection/AzureKeyVault/src/IKeyVaultWrappingClient.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Threading.Tasks; -using Microsoft.Azure.KeyVault.Models; - -namespace Microsoft.AspNetCore.DataProtection.AzureKeyVault -{ - internal interface IKeyVaultWrappingClient - { - Task UnwrapKeyAsync(string keyIdentifier, string algorithm, byte[] cipherText); - Task WrapKeyAsync(string keyIdentifier, string algorithm, byte[] cipherText); - } -} \ No newline at end of file diff --git a/src/DataProtection/AzureKeyVault/src/KeyVaultClientWrapper.cs b/src/DataProtection/AzureKeyVault/src/KeyVaultClientWrapper.cs deleted file mode 100644 index 82fe0649e2..0000000000 --- a/src/DataProtection/AzureKeyVault/src/KeyVaultClientWrapper.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Threading.Tasks; -using Microsoft.Azure.KeyVault; -using Microsoft.Azure.KeyVault.Models; - -namespace Microsoft.AspNetCore.DataProtection.AzureKeyVault -{ - internal class KeyVaultClientWrapper : IKeyVaultWrappingClient - { - private readonly KeyVaultClient _client; - - public KeyVaultClientWrapper(KeyVaultClient client) - { - _client = client; - } - - public Task UnwrapKeyAsync(string keyIdentifier, string algorithm, byte[] cipherText) - { - return _client.UnwrapKeyAsync(keyIdentifier, algorithm, cipherText); - } - - public Task WrapKeyAsync(string keyIdentifier, string algorithm, byte[] cipherText) - { - return _client.WrapKeyAsync(keyIdentifier, algorithm, cipherText); - } - } -} \ No newline at end of file diff --git a/src/DataProtection/AzureKeyVault/src/Microsoft.AspNetCore.DataProtection.AzureKeyVault.csproj b/src/DataProtection/AzureKeyVault/src/Microsoft.AspNetCore.DataProtection.AzureKeyVault.csproj deleted file mode 100644 index f395c32300..0000000000 --- a/src/DataProtection/AzureKeyVault/src/Microsoft.AspNetCore.DataProtection.AzureKeyVault.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - Microsoft Azure KeyVault key encryption support. - netstandard2.0 - true - aspnetcore;dataprotection;azure;keyvault - true - - - - - - - - - diff --git a/src/DataProtection/AzureKeyVault/src/Properties/AssemblyInfo.cs b/src/DataProtection/AzureKeyVault/src/Properties/AssemblyInfo.cs deleted file mode 100644 index 2b54a5854a..0000000000 --- a/src/DataProtection/AzureKeyVault/src/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Reflection; -using System.Resources; -using System.Runtime.CompilerServices; - -[assembly: InternalsVisibleTo("Microsoft.AspNetCore.DataProtection.AzureKeyVault.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] -[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] diff --git a/src/DataProtection/AzureKeyVault/test/AzureKeyVaultXmlEncryptorTests.cs b/src/DataProtection/AzureKeyVault/test/AzureKeyVaultXmlEncryptorTests.cs deleted file mode 100644 index faa9bd1c96..0000000000 --- a/src/DataProtection/AzureKeyVault/test/AzureKeyVaultXmlEncryptorTests.cs +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Linq; -using System.Security.Cryptography; -using System.Threading.Tasks; -using System.Xml.Linq; -using Microsoft.Azure.KeyVault.Models; -using Microsoft.Azure.KeyVault.WebKey; -using Microsoft.Extensions.DependencyInjection; -using Moq; -using Xunit; - -namespace Microsoft.AspNetCore.DataProtection.AzureKeyVault.Test -{ - public class AzureKeyVaultXmlEncryptorTests - { - [Fact] - public void UsesKeyVaultToEncryptKey() - { - var mock = new Mock(); - mock.Setup(client => client.WrapKeyAsync("key", JsonWebKeyEncryptionAlgorithm.RSAOAEP, It.IsAny())) - .Returns((_, __, data) => Task.FromResult(new KeyOperationResult("KeyId", data.Reverse().ToArray()))); - - var encryptor = new AzureKeyVaultXmlEncryptor(mock.Object, "key", new MockNumberGenerator()); - var result = encryptor.Encrypt(new XElement("Element")); - - var encryptedElement = result.EncryptedElement; - var value = encryptedElement.Element("value"); - - mock.VerifyAll(); - Assert.NotNull(result); - Assert.NotNull(value); - Assert.Equal(typeof(AzureKeyVaultXmlDecryptor), result.DecryptorType); - Assert.Equal("VfLYL2prdymawfucH3Goso0zkPbQ4/GKqUsj2TRtLzsBPz7p7cL1SQaY6I29xSlsPQf6IjxHSz4sDJ427GvlLQ==", encryptedElement.Element("value").Value); - Assert.Equal("AAECAwQFBgcICQoLDA0ODw==", encryptedElement.Element("iv").Value); - Assert.Equal("Dw4NDAsKCQgHBgUEAwIBAA==", encryptedElement.Element("key").Value); - Assert.Equal("KeyId", encryptedElement.Element("kid").Value); - } - - [Fact] - public void UsesKeyVaultToDecryptKey() - { - var mock = new Mock(); - mock.Setup(client => client.UnwrapKeyAsync("KeyId", JsonWebKeyEncryptionAlgorithm.RSAOAEP, It.IsAny())) - .Returns((_, __, data) => Task.FromResult(new KeyOperationResult(null, data.Reverse().ToArray()))) - .Verifiable(); - - var serviceCollection = new ServiceCollection(); - serviceCollection.AddSingleton(mock.Object); - - var encryptor = new AzureKeyVaultXmlDecryptor(serviceCollection.BuildServiceProvider()); - - var result = encryptor.Decrypt(XElement.Parse( - @" - KeyId - Dw4NDAsKCQgHBgUEAwIBAA== - AAECAwQFBgcICQoLDA0ODw== - VfLYL2prdymawfucH3Goso0zkPbQ4/GKqUsj2TRtLzsBPz7p7cL1SQaY6I29xSlsPQf6IjxHSz4sDJ427GvlLQ== - ")); - - mock.VerifyAll(); - Assert.NotNull(result); - Assert.Equal("", result.ToString()); - } - - private class MockNumberGenerator : RandomNumberGenerator - { - public override void GetBytes(byte[] data) - { - for (int i = 0; i < data.Length; i++) - { - data[i] = (byte)i; - } - } - } - } -} diff --git a/src/DataProtection/AzureKeyVault/test/Microsoft.AspNetCore.DataProtection.AzureKeyVault.Tests.csproj b/src/DataProtection/AzureKeyVault/test/Microsoft.AspNetCore.DataProtection.AzureKeyVault.Tests.csproj deleted file mode 100644 index 22a1aaa64a..0000000000 --- a/src/DataProtection/AzureKeyVault/test/Microsoft.AspNetCore.DataProtection.AzureKeyVault.Tests.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - $(DefaultNetCoreTargetFramework) - true - - false - - - - - - - - - - - diff --git a/src/DataProtection/AzureStorage/src/AzureBlobXmlRepository.cs b/src/DataProtection/AzureStorage/src/AzureBlobXmlRepository.cs deleted file mode 100644 index 4467235c2e..0000000000 --- a/src/DataProtection/AzureStorage/src/AzureBlobXmlRepository.cs +++ /dev/null @@ -1,292 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.IO; -using System.Linq; -using System.Runtime.ExceptionServices; -using System.Threading; -using System.Threading.Tasks; -using System.Xml; -using System.Xml.Linq; -using Microsoft.AspNetCore.DataProtection.Repositories; -using Microsoft.Azure.Storage; -using Microsoft.Azure.Storage.Blob; - -namespace Microsoft.AspNetCore.DataProtection.AzureStorage -{ - /// - /// An which is backed by Azure Blob Storage. - /// - /// - /// Instances of this type are thread-safe. - /// - public sealed class AzureBlobXmlRepository : IXmlRepository - { - private const int ConflictMaxRetries = 5; - private static readonly TimeSpan ConflictBackoffPeriod = TimeSpan.FromMilliseconds(200); - - private static readonly XName RepositoryElementName = "repository"; - - private readonly Func _blobRefFactory; - private readonly Random _random; - private BlobData _cachedBlobData; - - /// - /// Creates a new instance of the . - /// - /// A factory which can create - /// instances. The factory must be thread-safe for invocation by multiple - /// concurrent threads, and each invocation must return a new object. - public AzureBlobXmlRepository(Func blobRefFactory) - { - _blobRefFactory = blobRefFactory ?? throw new ArgumentNullException(nameof(blobRefFactory)); - _random = new Random(); - } - - /// - public IReadOnlyCollection GetAllElements() - { - var blobRef = CreateFreshBlobRef(); - - // Shunt the work onto a ThreadPool thread so that it's independent of any - // existing sync context or other potentially deadlock-causing items. - - var elements = Task.Run(() => GetAllElementsAsync(blobRef)).GetAwaiter().GetResult(); - return new ReadOnlyCollection(elements); - } - - /// - public void StoreElement(XElement element, string friendlyName) - { - if (element == null) - { - throw new ArgumentNullException(nameof(element)); - } - - var blobRef = CreateFreshBlobRef(); - - // Shunt the work onto a ThreadPool thread so that it's independent of any - // existing sync context or other potentially deadlock-causing items. - - Task.Run(() => StoreElementAsync(blobRef, element)).GetAwaiter().GetResult(); - } - - private XDocument CreateDocumentFromBlob(byte[] blob) - { - using (var memoryStream = new MemoryStream(blob)) - { - var xmlReaderSettings = new XmlReaderSettings() - { - DtdProcessing = DtdProcessing.Prohibit, IgnoreProcessingInstructions = true - }; - - using (var xmlReader = XmlReader.Create(memoryStream, xmlReaderSettings)) - { - return XDocument.Load(xmlReader); - } - } - } - - private ICloudBlob CreateFreshBlobRef() - { - // ICloudBlob instances aren't thread-safe, so we need to make sure we're working - // with a fresh instance that won't be mutated by another thread. - - var blobRef = _blobRefFactory(); - if (blobRef == null) - { - throw new InvalidOperationException("The ICloudBlob factory method returned null."); - } - - return blobRef; - } - - private async Task> GetAllElementsAsync(ICloudBlob blobRef) - { - var data = await GetLatestDataAsync(blobRef); - - if (data == null) - { - // no data in blob storage - return new XElement[0]; - } - - // The document will look like this: - // - // - // - // - // ... - // - // - // We want to return the first-level child elements to our caller. - - var doc = CreateDocumentFromBlob(data.BlobContents); - return doc.Root.Elements().ToList(); - } - - private async Task GetLatestDataAsync(ICloudBlob blobRef) - { - // Set the appropriate AccessCondition based on what we believe the latest - // file contents to be, then make the request. - - var latestCachedData = Volatile.Read(ref _cachedBlobData); // local ref so field isn't mutated under our feet - var accessCondition = (latestCachedData != null) - ? AccessCondition.GenerateIfNoneMatchCondition(latestCachedData.ETag) - : null; - - try - { - using (var memoryStream = new MemoryStream()) - { - await blobRef.DownloadToStreamAsync( - target: memoryStream, - accessCondition: accessCondition, - options: null, - operationContext: null); - - // At this point, our original cache either didn't exist or was outdated. - // We'll update it now and return the updated value; - - latestCachedData = new BlobData() - { - BlobContents = memoryStream.ToArray(), - ETag = blobRef.Properties.ETag - }; - - } - Volatile.Write(ref _cachedBlobData, latestCachedData); - } - catch (StorageException ex) when (ex.RequestInformation.HttpStatusCode == 304) - { - // 304 Not Modified - // Thrown when we already have the latest cached data. - // This isn't an error; we'll return our cached copy of the data. - } - catch (StorageException ex) when (ex.RequestInformation.HttpStatusCode == 404) - { - // 404 Not Found - // Thrown when no file exists in storage. - // This isn't an error; we'll delete our cached copy of data. - - latestCachedData = null; - Volatile.Write(ref _cachedBlobData, latestCachedData); - } - - return latestCachedData; - } - - private int GetRandomizedBackoffPeriod() - { - // returns a TimeSpan in the range [0.8, 1.0) * ConflictBackoffPeriod - // not used for crypto purposes - var multiplier = 0.8 + (_random.NextDouble() * 0.2); - return (int) (multiplier * ConflictBackoffPeriod.Ticks); - } - - private async Task StoreElementAsync(ICloudBlob blobRef, XElement element) - { - // holds the last error in case we need to rethrow it - ExceptionDispatchInfo lastError = null; - - for (var i = 0; i < ConflictMaxRetries; i++) - { - if (i > 1) - { - // If multiple conflicts occurred, wait a small period of time before retrying - // the operation so that other writers can make forward progress. - await Task.Delay(GetRandomizedBackoffPeriod()); - } - - if (i > 0) - { - // If at least one conflict occurred, make sure we have an up-to-date - // view of the blob contents. - await GetLatestDataAsync(blobRef); - } - - // Merge the new element into the document. If no document exists, - // create a new default document and inject this element into it. - - var latestData = Volatile.Read(ref _cachedBlobData); - var doc = (latestData != null) - ? CreateDocumentFromBlob(latestData.BlobContents) - : new XDocument(new XElement(RepositoryElementName)); - doc.Root.Add(element); - - // Turn this document back into a byte[]. - - var serializedDoc = new MemoryStream(); - doc.Save(serializedDoc, SaveOptions.DisableFormatting); - - // Generate the appropriate precondition header based on whether or not - // we believe data already exists in storage. - - AccessCondition accessCondition; - if (latestData != null) - { - accessCondition = AccessCondition.GenerateIfMatchCondition(blobRef.Properties.ETag); - } - else - { - accessCondition = AccessCondition.GenerateIfNotExistsCondition(); - blobRef.Properties.ContentType = "application/xml; charset=utf-8"; // set content type on first write - } - - try - { - // Send the request up to the server. - - var serializedDocAsByteArray = serializedDoc.ToArray(); - - await blobRef.UploadFromByteArrayAsync( - buffer: serializedDocAsByteArray, - index: 0, - count: serializedDocAsByteArray.Length, - accessCondition: accessCondition, - options: null, - operationContext: null); - - // If we got this far, success! - // We can update the cached view of the remote contents. - - Volatile.Write(ref _cachedBlobData, new BlobData() - { - BlobContents = serializedDocAsByteArray, - ETag = blobRef.Properties.ETag // was updated by Upload routine - }); - - return; - } - catch (StorageException ex) - when (ex.RequestInformation.HttpStatusCode == 409 || ex.RequestInformation.HttpStatusCode == 412) - { - // 409 Conflict - // This error is rare but can be thrown in very special circumstances, - // such as if the blob in the process of being created. We treat it - // as equivalent to 412 for the purposes of retry logic. - - // 412 Precondition Failed - // We'll get this error if another writer updated the repository and we - // have an outdated view of its contents. If this occurs, we'll just - // refresh our view of the remote contents and try again up to the max - // retry limit. - - lastError = ExceptionDispatchInfo.Capture(ex); - } - } - - // if we got this far, something went awry - lastError.Throw(); - } - - private sealed class BlobData - { - internal byte[] BlobContents; - internal string ETag; - } - } -} diff --git a/src/DataProtection/AzureStorage/src/AzureDataProtectionBuilderExtensions.cs b/src/DataProtection/AzureStorage/src/AzureDataProtectionBuilderExtensions.cs deleted file mode 100644 index 34bb3edf08..0000000000 --- a/src/DataProtection/AzureStorage/src/AzureDataProtectionBuilderExtensions.cs +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using Microsoft.AspNetCore.DataProtection.AzureStorage; -using Microsoft.AspNetCore.DataProtection.KeyManagement; -using Microsoft.Azure.Storage; -using Microsoft.Azure.Storage.Auth; -using Microsoft.Azure.Storage.Blob; -using Microsoft.Extensions.DependencyInjection; - -namespace Microsoft.AspNetCore.DataProtection -{ - /// - /// Contains Azure-specific extension methods for modifying a - /// . - /// - public static class AzureDataProtectionBuilderExtensions - { - /// - /// Configures the data protection system to persist keys to the specified path - /// in Azure Blob Storage. - /// - /// The builder instance to modify. - /// The which - /// should be utilized. - /// A relative path where the key file should be - /// stored, generally specified as "/containerName/[subDir/]keys.xml". - /// The value . - /// - /// The container referenced by must already exist. - /// - public static IDataProtectionBuilder PersistKeysToAzureBlobStorage(this IDataProtectionBuilder builder, CloudStorageAccount storageAccount, string relativePath) - { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } - if (storageAccount == null) - { - throw new ArgumentNullException(nameof(storageAccount)); - } - if (relativePath == null) - { - throw new ArgumentNullException(nameof(relativePath)); - } - - // Simply concatenate the root storage endpoint with the relative path, - // which includes the container name and blob name. - - var uriBuilder = new UriBuilder(storageAccount.BlobEndpoint); - uriBuilder.Path = uriBuilder.Path.TrimEnd('/') + "/" + relativePath.TrimStart('/'); - - // We can create a CloudBlockBlob from the storage URI and the creds. - - var blobAbsoluteUri = uriBuilder.Uri; - var credentials = storageAccount.Credentials; - - return PersistKeystoAzureBlobStorageInternal(builder, () => new CloudBlockBlob(blobAbsoluteUri, credentials)); - } - - /// - /// Configures the data protection system to persist keys to the specified path - /// in Azure Blob Storage. - /// - /// The builder instance to modify. - /// The full URI where the key file should be stored. - /// The URI must contain the SAS token as a query string parameter. - /// The value . - /// - /// The container referenced by must already exist. - /// - public static IDataProtectionBuilder PersistKeysToAzureBlobStorage(this IDataProtectionBuilder builder, Uri blobUri) - { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } - if (blobUri == null) - { - throw new ArgumentNullException(nameof(blobUri)); - } - - var uriBuilder = new UriBuilder(blobUri); - - // The SAS token is present in the query string. - - if (string.IsNullOrEmpty(uriBuilder.Query)) - { - throw new ArgumentException( - message: "URI does not have a SAS token in the query string.", - paramName: nameof(blobUri)); - } - - var credentials = new StorageCredentials(uriBuilder.Query); - uriBuilder.Query = null; // no longer needed - var blobAbsoluteUri = uriBuilder.Uri; - - return PersistKeystoAzureBlobStorageInternal(builder, () => new CloudBlockBlob(blobAbsoluteUri, credentials)); - } - - /// - /// Configures the data protection system to persist keys to the specified path - /// in Azure Blob Storage. - /// - /// The builder instance to modify. - /// The where the - /// key file should be stored. - /// The value . - /// - /// The container referenced by must already exist. - /// - public static IDataProtectionBuilder PersistKeysToAzureBlobStorage(this IDataProtectionBuilder builder, CloudBlockBlob blobReference) - { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } - if (blobReference == null) - { - throw new ArgumentNullException(nameof(blobReference)); - } - - // We're basically just going to make a copy of this blob. - // Use (container, blobName) instead of (storageuri, creds) since the container - // is tied to an existing service client, which contains user-settable defaults - // like retry policy and secondary connection URIs. - - var container = blobReference.Container; - var blobName = blobReference.Name; - - return PersistKeystoAzureBlobStorageInternal(builder, () => container.GetBlockBlobReference(blobName)); - } - - /// - /// Configures the data protection system to persist keys to the specified path - /// in Azure Blob Storage. - /// - /// The builder instance to modify. - /// The in which the - /// key file should be stored. - /// The name of the key file, generally specified - /// as "[subdir/]keys.xml" - /// The value . - /// - /// The container referenced by must already exist. - /// - public static IDataProtectionBuilder PersistKeysToAzureBlobStorage(this IDataProtectionBuilder builder, CloudBlobContainer container, string blobName) - { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } - if (container == null) - { - throw new ArgumentNullException(nameof(container)); - } - if (blobName == null) - { - throw new ArgumentNullException(nameof(blobName)); - } - return PersistKeystoAzureBlobStorageInternal(builder, () => container.GetBlockBlobReference(blobName)); - } - - // important: the Func passed into this method must return a new instance with each call - private static IDataProtectionBuilder PersistKeystoAzureBlobStorageInternal(IDataProtectionBuilder builder, Func blobRefFactory) - { - builder.Services.Configure(options => - { - options.XmlRepository = new AzureBlobXmlRepository(blobRefFactory); - }); - return builder; - } - } -} diff --git a/src/DataProtection/AzureStorage/src/Microsoft.AspNetCore.DataProtection.AzureStorage.csproj b/src/DataProtection/AzureStorage/src/Microsoft.AspNetCore.DataProtection.AzureStorage.csproj deleted file mode 100644 index abf1a2d5de..0000000000 --- a/src/DataProtection/AzureStorage/src/Microsoft.AspNetCore.DataProtection.AzureStorage.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - - Microsoft Azure Blob storage support as key store. - netstandard2.0 - true - true - aspnetcore;dataprotection;azure;blob - true - true - - - - - - - - - - - - - - diff --git a/src/DataProtection/AzureStorage/test/AzureBlobXmlRepositoryTests.cs b/src/DataProtection/AzureStorage/test/AzureBlobXmlRepositoryTests.cs deleted file mode 100644 index 868e08b758..0000000000 --- a/src/DataProtection/AzureStorage/test/AzureBlobXmlRepositoryTests.cs +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Xml.Linq; -using Microsoft.Azure.Storage; -using Microsoft.Azure.Storage.Blob; -using Moq; -using Xunit; - -namespace Microsoft.AspNetCore.DataProtection.AzureStorage.Test -{ - public class AzureBlobXmlRepositoryTests - { - [Fact] - public void StoreCreatesBlobWhenNotExist() - { - AccessCondition downloadCondition = null; - AccessCondition uploadCondition = null; - byte[] bytes = null; - BlobProperties properties = new BlobProperties(); - - var mock = new Mock(); - mock.SetupGet(c => c.Properties).Returns(properties); - mock.Setup(c => c.UploadFromByteArrayAsync( - It.IsAny(), - It.IsAny(), - It.IsAny(), - It.IsAny(), - It.IsAny(), - It.IsAny())) - .Returns(async (byte[] buffer, int index, int count, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) => - { - bytes = buffer.Skip(index).Take(count).ToArray(); - uploadCondition = accessCondition; - await Task.Yield(); - }); - - var repository = new AzureBlobXmlRepository(() => mock.Object); - repository.StoreElement(new XElement("Element"), null); - - Assert.Null(downloadCondition); - Assert.Equal("*", uploadCondition.IfNoneMatchETag); - Assert.Equal("application/xml; charset=utf-8", properties.ContentType); - var element = ""; - - Assert.Equal(bytes, GetEnvelopedContent(element)); - } - - [Fact] - public void StoreUpdatesWhenExistsAndNewerExists() - { - AccessCondition downloadCondition = null; - byte[] bytes = null; - BlobProperties properties = new BlobProperties(); - - var mock = new Mock(); - mock.SetupGet(c => c.Properties).Returns(properties); - mock.Setup(c => c.DownloadToStreamAsync( - It.IsAny(), - It.IsAny(), - null, - null)) - .Returns(async (Stream target, AccessCondition condition, BlobRequestOptions options, OperationContext context) => - { - var data = GetEnvelopedContent(""); - await target.WriteAsync(data, 0, data.Length); - }) - .Verifiable(); - - mock.Setup(c => c.UploadFromByteArrayAsync( - It.IsAny(), - It.IsAny(), - It.IsAny(), - It.Is((AccessCondition cond) => cond.IfNoneMatchETag == "*"), - It.IsAny(), - It.IsAny())) - .Throws(new StorageException(new RequestResult { HttpStatusCode = 412 }, null, null)) - .Verifiable(); - - mock.Setup(c => c.UploadFromByteArrayAsync( - It.IsAny(), - It.IsAny(), - It.IsAny(), - It.Is((AccessCondition cond) => cond.IfNoneMatchETag != "*"), - It.IsAny(), - It.IsAny())) - .Returns(async (byte[] buffer, int index, int count, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) => - { - bytes = buffer.Skip(index).Take(count).ToArray(); - await Task.Yield(); - }) - .Verifiable(); - - var repository = new AzureBlobXmlRepository(() => mock.Object); - repository.StoreElement(new XElement("Element2"), null); - - mock.Verify(); - Assert.Null(downloadCondition); - Assert.Equal(bytes, GetEnvelopedContent("")); - } - - private static byte[] GetEnvelopedContent(string element) - { - return Encoding.UTF8.GetBytes($"{element}"); - } - } -} diff --git a/src/DataProtection/AzureStorage/test/AzureDataProtectionBuilderExtensionsTest.cs b/src/DataProtection/AzureStorage/test/AzureDataProtectionBuilderExtensionsTest.cs deleted file mode 100644 index 88e673d980..0000000000 --- a/src/DataProtection/AzureStorage/test/AzureDataProtectionBuilderExtensionsTest.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using Microsoft.AspNetCore.DataProtection.KeyManagement; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; -using Microsoft.Azure.Storage.Blob; -using Xunit; - -namespace Microsoft.AspNetCore.DataProtection.AzureStorage -{ - public class AzureDataProtectionBuilderExtensionsTest - { - [Fact] - public void PersistKeysToAzureBlobStorage_UsesAzureBlobXmlRepository() - { - // Arrange - var container = new CloudBlobContainer(new Uri("http://www.example.com")); - var serviceCollection = new ServiceCollection(); - var builder = serviceCollection.AddDataProtection(); - - // Act - builder.PersistKeysToAzureBlobStorage(container, "keys.xml"); - var services = serviceCollection.BuildServiceProvider(); - - // Assert - var options = services.GetRequiredService>(); - Assert.IsType(options.Value.XmlRepository); - } - } -} diff --git a/src/DataProtection/AzureStorage/test/Microsoft.AspNetCore.DataProtection.AzureStorage.Tests.csproj b/src/DataProtection/AzureStorage/test/Microsoft.AspNetCore.DataProtection.AzureStorage.Tests.csproj deleted file mode 100644 index 54bfce3543..0000000000 --- a/src/DataProtection/AzureStorage/test/Microsoft.AspNetCore.DataProtection.AzureStorage.Tests.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - $(DefaultNetCoreTargetFramework) - true - true - - false - - - - - - - - - - - - - diff --git a/src/DataProtection/DataProtection.sln b/src/DataProtection/DataProtection.sln index 6726d0ab6d..05dd4cf0e0 100644 --- a/src/DataProtection/DataProtection.sln +++ b/src/DataProtection/DataProtection.sln @@ -9,18 +9,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.DataPr EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.DataProtection.Abstractions.Tests", "Abstractions\test\Microsoft.AspNetCore.DataProtection.Abstractions.Tests.csproj", "{CEDC6CD0-0276-4C45-9B57-C222516840B9}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AzureKeyVault", "AzureKeyVault", "{695602EE-F2FD-4B9B-AF84-9208AE552B9E}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.DataProtection.AzureKeyVault", "AzureKeyVault\src\Microsoft.AspNetCore.DataProtection.AzureKeyVault.csproj", "{DDA72406-95B8-4A67-A994-F1E5F2506126}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.DataProtection.AzureKeyVault.Tests", "AzureKeyVault\test\Microsoft.AspNetCore.DataProtection.AzureKeyVault.Tests.csproj", "{0C2EE847-D78B-46FD-AB73-EAB8200C9138}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AzureStorage", "AzureStorage", "{5CD76E65-363F-4CD5-B01D-2DF5DC16CB64}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.DataProtection.AzureStorage", "AzureStorage\src\Microsoft.AspNetCore.DataProtection.AzureStorage.csproj", "{22860B07-A42B-4757-9208-7D6BDB2B48F3}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.DataProtection.AzureStorage.Tests", "AzureStorage\test\Microsoft.AspNetCore.DataProtection.AzureStorage.Tests.csproj", "{C36DAB08-F641-4C5A-86C0-3CC39FC779D9}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Cryptography.Internal", "Cryptography.Internal", "{A5DE8834-6C9B-47A6-9CDC-AAB83C776F19}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Cryptography.Internal", "Cryptography.Internal\src\Microsoft.AspNetCore.Cryptography.Internal.csproj", "{93B3396D-0234-4D4E-A85B-4A391E0C6FE0}" @@ -53,10 +41,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.DataPr EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{9DF098B3-C8ED-471C-AE03-52E3196C1811}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzureBlob", "samples\AzureBlob\AzureBlob.csproj", "{BB197CC9-04B8-4BC7-BB2E-703798B82FD4}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzureKeyVault", "samples\AzureKeyVault\AzureKeyVault.csproj", "{D8E4ED57-3D14-4453-A2FE-D36C97AE4273}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CustomEncryptorSample", "samples\CustomEncryptorSample\CustomEncryptorSample.csproj", "{9824655A-4BBF-418E-A7D9-3DA52D98D16D}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KeyManagementSample", "samples\KeyManagementSample\KeyManagementSample.csproj", "{03406538-75CB-4655-B210-643FE11A2B00}" @@ -107,54 +91,6 @@ Global {CEDC6CD0-0276-4C45-9B57-C222516840B9}.Release|x64.Build.0 = Release|Any CPU {CEDC6CD0-0276-4C45-9B57-C222516840B9}.Release|x86.ActiveCfg = Release|Any CPU {CEDC6CD0-0276-4C45-9B57-C222516840B9}.Release|x86.Build.0 = Release|Any CPU - {DDA72406-95B8-4A67-A994-F1E5F2506126}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DDA72406-95B8-4A67-A994-F1E5F2506126}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DDA72406-95B8-4A67-A994-F1E5F2506126}.Debug|x64.ActiveCfg = Debug|Any CPU - {DDA72406-95B8-4A67-A994-F1E5F2506126}.Debug|x64.Build.0 = Debug|Any CPU - {DDA72406-95B8-4A67-A994-F1E5F2506126}.Debug|x86.ActiveCfg = Debug|Any CPU - {DDA72406-95B8-4A67-A994-F1E5F2506126}.Debug|x86.Build.0 = Debug|Any CPU - {DDA72406-95B8-4A67-A994-F1E5F2506126}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DDA72406-95B8-4A67-A994-F1E5F2506126}.Release|Any CPU.Build.0 = Release|Any CPU - {DDA72406-95B8-4A67-A994-F1E5F2506126}.Release|x64.ActiveCfg = Release|Any CPU - {DDA72406-95B8-4A67-A994-F1E5F2506126}.Release|x64.Build.0 = Release|Any CPU - {DDA72406-95B8-4A67-A994-F1E5F2506126}.Release|x86.ActiveCfg = Release|Any CPU - {DDA72406-95B8-4A67-A994-F1E5F2506126}.Release|x86.Build.0 = Release|Any CPU - {0C2EE847-D78B-46FD-AB73-EAB8200C9138}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0C2EE847-D78B-46FD-AB73-EAB8200C9138}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0C2EE847-D78B-46FD-AB73-EAB8200C9138}.Debug|x64.ActiveCfg = Debug|Any CPU - {0C2EE847-D78B-46FD-AB73-EAB8200C9138}.Debug|x64.Build.0 = Debug|Any CPU - {0C2EE847-D78B-46FD-AB73-EAB8200C9138}.Debug|x86.ActiveCfg = Debug|Any CPU - {0C2EE847-D78B-46FD-AB73-EAB8200C9138}.Debug|x86.Build.0 = Debug|Any CPU - {0C2EE847-D78B-46FD-AB73-EAB8200C9138}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0C2EE847-D78B-46FD-AB73-EAB8200C9138}.Release|Any CPU.Build.0 = Release|Any CPU - {0C2EE847-D78B-46FD-AB73-EAB8200C9138}.Release|x64.ActiveCfg = Release|Any CPU - {0C2EE847-D78B-46FD-AB73-EAB8200C9138}.Release|x64.Build.0 = Release|Any CPU - {0C2EE847-D78B-46FD-AB73-EAB8200C9138}.Release|x86.ActiveCfg = Release|Any CPU - {0C2EE847-D78B-46FD-AB73-EAB8200C9138}.Release|x86.Build.0 = Release|Any CPU - {22860B07-A42B-4757-9208-7D6BDB2B48F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {22860B07-A42B-4757-9208-7D6BDB2B48F3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {22860B07-A42B-4757-9208-7D6BDB2B48F3}.Debug|x64.ActiveCfg = Debug|Any CPU - {22860B07-A42B-4757-9208-7D6BDB2B48F3}.Debug|x64.Build.0 = Debug|Any CPU - {22860B07-A42B-4757-9208-7D6BDB2B48F3}.Debug|x86.ActiveCfg = Debug|Any CPU - {22860B07-A42B-4757-9208-7D6BDB2B48F3}.Debug|x86.Build.0 = Debug|Any CPU - {22860B07-A42B-4757-9208-7D6BDB2B48F3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {22860B07-A42B-4757-9208-7D6BDB2B48F3}.Release|Any CPU.Build.0 = Release|Any CPU - {22860B07-A42B-4757-9208-7D6BDB2B48F3}.Release|x64.ActiveCfg = Release|Any CPU - {22860B07-A42B-4757-9208-7D6BDB2B48F3}.Release|x64.Build.0 = Release|Any CPU - {22860B07-A42B-4757-9208-7D6BDB2B48F3}.Release|x86.ActiveCfg = Release|Any CPU - {22860B07-A42B-4757-9208-7D6BDB2B48F3}.Release|x86.Build.0 = Release|Any CPU - {C36DAB08-F641-4C5A-86C0-3CC39FC779D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C36DAB08-F641-4C5A-86C0-3CC39FC779D9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C36DAB08-F641-4C5A-86C0-3CC39FC779D9}.Debug|x64.ActiveCfg = Debug|Any CPU - {C36DAB08-F641-4C5A-86C0-3CC39FC779D9}.Debug|x64.Build.0 = Debug|Any CPU - {C36DAB08-F641-4C5A-86C0-3CC39FC779D9}.Debug|x86.ActiveCfg = Debug|Any CPU - {C36DAB08-F641-4C5A-86C0-3CC39FC779D9}.Debug|x86.Build.0 = Debug|Any CPU - {C36DAB08-F641-4C5A-86C0-3CC39FC779D9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C36DAB08-F641-4C5A-86C0-3CC39FC779D9}.Release|Any CPU.Build.0 = Release|Any CPU - {C36DAB08-F641-4C5A-86C0-3CC39FC779D9}.Release|x64.ActiveCfg = Release|Any CPU - {C36DAB08-F641-4C5A-86C0-3CC39FC779D9}.Release|x64.Build.0 = Release|Any CPU - {C36DAB08-F641-4C5A-86C0-3CC39FC779D9}.Release|x86.ActiveCfg = Release|Any CPU - {C36DAB08-F641-4C5A-86C0-3CC39FC779D9}.Release|x86.Build.0 = Release|Any CPU {93B3396D-0234-4D4E-A85B-4A391E0C6FE0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {93B3396D-0234-4D4E-A85B-4A391E0C6FE0}.Debug|Any CPU.Build.0 = Debug|Any CPU {93B3396D-0234-4D4E-A85B-4A391E0C6FE0}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -275,30 +211,6 @@ Global {8A71D3B4-D617-4960-8616-A196FBF351FE}.Release|x64.Build.0 = Release|Any CPU {8A71D3B4-D617-4960-8616-A196FBF351FE}.Release|x86.ActiveCfg = Release|Any CPU {8A71D3B4-D617-4960-8616-A196FBF351FE}.Release|x86.Build.0 = Release|Any CPU - {BB197CC9-04B8-4BC7-BB2E-703798B82FD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BB197CC9-04B8-4BC7-BB2E-703798B82FD4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BB197CC9-04B8-4BC7-BB2E-703798B82FD4}.Debug|x64.ActiveCfg = Debug|Any CPU - {BB197CC9-04B8-4BC7-BB2E-703798B82FD4}.Debug|x64.Build.0 = Debug|Any CPU - {BB197CC9-04B8-4BC7-BB2E-703798B82FD4}.Debug|x86.ActiveCfg = Debug|Any CPU - {BB197CC9-04B8-4BC7-BB2E-703798B82FD4}.Debug|x86.Build.0 = Debug|Any CPU - {BB197CC9-04B8-4BC7-BB2E-703798B82FD4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BB197CC9-04B8-4BC7-BB2E-703798B82FD4}.Release|Any CPU.Build.0 = Release|Any CPU - {BB197CC9-04B8-4BC7-BB2E-703798B82FD4}.Release|x64.ActiveCfg = Release|Any CPU - {BB197CC9-04B8-4BC7-BB2E-703798B82FD4}.Release|x64.Build.0 = Release|Any CPU - {BB197CC9-04B8-4BC7-BB2E-703798B82FD4}.Release|x86.ActiveCfg = Release|Any CPU - {BB197CC9-04B8-4BC7-BB2E-703798B82FD4}.Release|x86.Build.0 = Release|Any CPU - {D8E4ED57-3D14-4453-A2FE-D36C97AE4273}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D8E4ED57-3D14-4453-A2FE-D36C97AE4273}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D8E4ED57-3D14-4453-A2FE-D36C97AE4273}.Debug|x64.ActiveCfg = Debug|Any CPU - {D8E4ED57-3D14-4453-A2FE-D36C97AE4273}.Debug|x64.Build.0 = Debug|Any CPU - {D8E4ED57-3D14-4453-A2FE-D36C97AE4273}.Debug|x86.ActiveCfg = Debug|Any CPU - {D8E4ED57-3D14-4453-A2FE-D36C97AE4273}.Debug|x86.Build.0 = Debug|Any CPU - {D8E4ED57-3D14-4453-A2FE-D36C97AE4273}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D8E4ED57-3D14-4453-A2FE-D36C97AE4273}.Release|Any CPU.Build.0 = Release|Any CPU - {D8E4ED57-3D14-4453-A2FE-D36C97AE4273}.Release|x64.ActiveCfg = Release|Any CPU - {D8E4ED57-3D14-4453-A2FE-D36C97AE4273}.Release|x64.Build.0 = Release|Any CPU - {D8E4ED57-3D14-4453-A2FE-D36C97AE4273}.Release|x86.ActiveCfg = Release|Any CPU - {D8E4ED57-3D14-4453-A2FE-D36C97AE4273}.Release|x86.Build.0 = Release|Any CPU {9824655A-4BBF-418E-A7D9-3DA52D98D16D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9824655A-4BBF-418E-A7D9-3DA52D98D16D}.Debug|Any CPU.Build.0 = Debug|Any CPU {9824655A-4BBF-418E-A7D9-3DA52D98D16D}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -390,10 +302,6 @@ Global GlobalSection(NestedProjects) = preSolution {18BE6FD1-1EB1-44AD-A3AE-398C990060F5} = {ABD364B3-09A1-4CFE-8D26-FF6417DDEC84} {CEDC6CD0-0276-4C45-9B57-C222516840B9} = {ABD364B3-09A1-4CFE-8D26-FF6417DDEC84} - {DDA72406-95B8-4A67-A994-F1E5F2506126} = {695602EE-F2FD-4B9B-AF84-9208AE552B9E} - {0C2EE847-D78B-46FD-AB73-EAB8200C9138} = {695602EE-F2FD-4B9B-AF84-9208AE552B9E} - {22860B07-A42B-4757-9208-7D6BDB2B48F3} = {5CD76E65-363F-4CD5-B01D-2DF5DC16CB64} - {C36DAB08-F641-4C5A-86C0-3CC39FC779D9} = {5CD76E65-363F-4CD5-B01D-2DF5DC16CB64} {93B3396D-0234-4D4E-A85B-4A391E0C6FE0} = {A5DE8834-6C9B-47A6-9CDC-AAB83C776F19} {14FD172E-4134-4712-AE77-524208FFEA1C} = {A5DE8834-6C9B-47A6-9CDC-AAB83C776F19} {A82BAE81-24E3-48DF-96BA-C8A6FEDD274A} = {EFADD18C-A0D7-4F51-AEAB-9E3346A208BF} @@ -404,8 +312,6 @@ Global {DC6D371D-200A-40D9-B4BE-C9202C27A863} = {361B9ACA-DCA4-4C1B-A071-906348E849C0} {0FEAE8C5-4EAF-4E87-9A07-69FCE19B31D7} = {1A2E71DA-8DFE-4DDA-B713-14B5F2B8EBAE} {8A71D3B4-D617-4960-8616-A196FBF351FE} = {1A2E71DA-8DFE-4DDA-B713-14B5F2B8EBAE} - {BB197CC9-04B8-4BC7-BB2E-703798B82FD4} = {9DF098B3-C8ED-471C-AE03-52E3196C1811} - {D8E4ED57-3D14-4453-A2FE-D36C97AE4273} = {9DF098B3-C8ED-471C-AE03-52E3196C1811} {9824655A-4BBF-418E-A7D9-3DA52D98D16D} = {9DF098B3-C8ED-471C-AE03-52E3196C1811} {03406538-75CB-4655-B210-643FE11A2B00} = {9DF098B3-C8ED-471C-AE03-52E3196C1811} {C5C425C8-5626-409B-9A81-4DC496CE41F4} = {9DF098B3-C8ED-471C-AE03-52E3196C1811} diff --git a/src/DataProtection/samples/AzureBlob/AzureBlob.csproj b/src/DataProtection/samples/AzureBlob/AzureBlob.csproj deleted file mode 100644 index 14daf0f2db..0000000000 --- a/src/DataProtection/samples/AzureBlob/AzureBlob.csproj +++ /dev/null @@ -1,20 +0,0 @@ - - - - $(DefaultNetCoreTargetFramework) - exe - - false - - - - - - - - - - - - - diff --git a/src/DataProtection/samples/AzureBlob/Program.cs b/src/DataProtection/samples/AzureBlob/Program.cs deleted file mode 100644 index 2adc7c0aa9..0000000000 --- a/src/DataProtection/samples/AzureBlob/Program.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using Microsoft.AspNetCore.DataProtection; -using Microsoft.Azure.Storage; -using Microsoft.Azure.Storage.Blob; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using LogLevel = Microsoft.Extensions.Logging.LogLevel; - -namespace AzureBlob -{ - public class Program - { - public static void Main(string[] args) - { - var storageAccount = CloudStorageAccount.DevelopmentStorageAccount; - var client = storageAccount.CreateCloudBlobClient(); - var container = client.GetContainerReference("key-container"); - - // The container must exist before calling the DataProtection APIs. - // The specific file within the container does not have to exist, - // as it will be created on-demand. - - container.CreateIfNotExistsAsync().GetAwaiter().GetResult(); - - // Configure - using (var services = new ServiceCollection() - .AddLogging(o => o.AddConsole().SetMinimumLevel(LogLevel.Debug)) - .AddDataProtection() - .PersistKeysToAzureBlobStorage(container, "keys.xml") - .Services - .BuildServiceProvider()) - { - // Run a sample payload - - var protector = services.GetDataProtector("sample-purpose"); - var protectedData = protector.Protect("Hello world!"); - Console.WriteLine(protectedData); - } - } - } -} diff --git a/src/DataProtection/samples/AzureKeyVault/AzureKeyVault.csproj b/src/DataProtection/samples/AzureKeyVault/AzureKeyVault.csproj deleted file mode 100644 index a8b80ac42a..0000000000 --- a/src/DataProtection/samples/AzureKeyVault/AzureKeyVault.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - $(DefaultNetCoreTargetFramework) - exe - - false - - - - - - - - - - - - - - diff --git a/src/DataProtection/samples/AzureKeyVault/Program.cs b/src/DataProtection/samples/AzureKeyVault/Program.cs deleted file mode 100644 index 7da515fa95..0000000000 --- a/src/DataProtection/samples/AzureKeyVault/Program.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using System.Linq; -using System.Security.Cryptography.X509Certificates; -using Microsoft.AspNetCore.DataProtection; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; - -namespace ConsoleApplication -{ - public class Program - { - public static void Main(string[] args) - { - var builder = new ConfigurationBuilder(); - builder.SetBasePath(Directory.GetCurrentDirectory()); - builder.AddJsonFile("settings.json"); - var config = builder.Build(); - - var store = new X509Store(StoreLocation.CurrentUser); - store.Open(OpenFlags.ReadOnly); - var cert = store.Certificates.Find(X509FindType.FindByThumbprint, config["CertificateThumbprint"], false); - - var serviceCollection = new ServiceCollection(); - serviceCollection.AddLogging(loggingBuilder => loggingBuilder.AddConsole()); - serviceCollection.AddDataProtection() - .PersistKeysToFileSystem(new DirectoryInfo(".")) - .ProtectKeysWithAzureKeyVault(config["KeyId"], config["ClientId"], cert.OfType().Single()); - - var serviceProvider = serviceCollection.BuildServiceProvider(); - - var loggerFactory = serviceProvider.GetService(); - - var protector = serviceProvider.GetDataProtector("Test"); - - Console.WriteLine(protector.Protect("Hello world")); - } - } -} diff --git a/src/DataProtection/samples/AzureKeyVault/settings.json b/src/DataProtection/samples/AzureKeyVault/settings.json deleted file mode 100644 index ef7d4d81b8..0000000000 --- a/src/DataProtection/samples/AzureKeyVault/settings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "CertificateThumbprint": "", - "KeyId": "", - "ClientId": "" -} \ No newline at end of file diff --git a/src/ProjectTemplates/test/GrpcTemplateTest.cs b/src/ProjectTemplates/test/GrpcTemplateTest.cs index eda3fb44ef..7f64f4b29d 100644 --- a/src/ProjectTemplates/test/GrpcTemplateTest.cs +++ b/src/ProjectTemplates/test/GrpcTemplateTest.cs @@ -26,6 +26,7 @@ namespace Templates.Test [ConditionalFact] [SkipOnHelix("Not supported queues", Queues = "Windows.7.Amd64;Windows.7.Amd64.Open;OSX.1014.Amd64;OSX.1014.Amd64.Open")] + [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/19716")] public async Task GrpcTemplate() { Project = await ProjectFactory.GetOrCreateProject("grpc", Output); diff --git a/src/ProjectTemplates/test/IdentityUIPackageTest.cs b/src/ProjectTemplates/test/IdentityUIPackageTest.cs index f6974eceb2..b89c19b61a 100644 --- a/src/ProjectTemplates/test/IdentityUIPackageTest.cs +++ b/src/ProjectTemplates/test/IdentityUIPackageTest.cs @@ -121,6 +121,7 @@ namespace Templates.Test [ConditionalTheory] [MemberData(nameof(MSBuildIdentityUIPackageOptions))] [SkipOnHelix("cert failure", Queues = "OSX.1014.Amd64;OSX.1014.Amd64.Open")] + [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/19716")] public async Task IdentityUIPackage_WorksWithDifferentOptions(IDictionary packageOptions, string versionValidator, string[] expectedFiles) { Project = await ProjectFactory.GetOrCreateProject("identityuipackage" + string.Concat(packageOptions.Values), Output); diff --git a/src/ProjectTemplates/test/MvcTemplateTest.cs b/src/ProjectTemplates/test/MvcTemplateTest.cs index 3bcb51416a..ff60a16bd8 100644 --- a/src/ProjectTemplates/test/MvcTemplateTest.cs +++ b/src/ProjectTemplates/test/MvcTemplateTest.cs @@ -108,6 +108,7 @@ namespace Templates.Test [InlineData(true)] [InlineData(false)] [SkipOnHelix("cert failure", Queues = "OSX.1014.Amd64;OSX.1014.Amd64.Open")] + [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/19716")] public async Task MvcTemplate_IndividualAuth(bool useLocalDB) { Project = await ProjectFactory.GetOrCreateProject("mvcindividual" + (useLocalDB ? "uld" : ""), Output); @@ -223,6 +224,7 @@ namespace Templates.Test } [Fact] + [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/19716")] public async Task MvcTemplate_RazorRuntimeCompilation_BuildsAndPublishes() { Project = await ProjectFactory.GetOrCreateProject("mvc_rc", Output); diff --git a/src/ProjectTemplates/test/RazorClassLibraryTemplateTest.cs b/src/ProjectTemplates/test/RazorClassLibraryTemplateTest.cs index 0d02a56f8f..b16f8fa345 100644 --- a/src/ProjectTemplates/test/RazorClassLibraryTemplateTest.cs +++ b/src/ProjectTemplates/test/RazorClassLibraryTemplateTest.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Threading.Tasks; +using Microsoft.AspNetCore.Testing; using Templates.Test.Helpers; using Xunit; using Xunit.Abstractions; @@ -41,6 +42,7 @@ namespace Templates.Test } [Fact] + [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/19716")] public async Task RazorClassLibraryTemplateAsync() { Project = await ProjectFactory.GetOrCreateProject("razorclasslib", Output); diff --git a/src/ProjectTemplates/test/RazorPagesTemplateTest.cs b/src/ProjectTemplates/test/RazorPagesTemplateTest.cs index 4e7b924492..10370a3573 100644 --- a/src/ProjectTemplates/test/RazorPagesTemplateTest.cs +++ b/src/ProjectTemplates/test/RazorPagesTemplateTest.cs @@ -97,7 +97,8 @@ namespace Templates.Test [ConditionalTheory] [InlineData(false)] [InlineData(true)] - [SkipOnHelix("cert failure", Queues = "OSX.1014.Amd64;OSX.1014.Amd64.Open")] + [SkipOnHelix("cert failure", Queues = "OSX.1014.Amd64;OSX.1014.Amd64.Open")] + [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/19716")] public async Task RazorPagesTemplate_IndividualAuth(bool useLocalDB) { Project = await ProjectFactory.GetOrCreateProject("razorpagesindividual" + (useLocalDB ? "uld" : ""), Output); @@ -213,6 +214,7 @@ namespace Templates.Test } [Fact] + [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/19716")] public async Task RazorPagesTemplate_RazorRuntimeCompilation_BuildsAndPublishes() { Project = await ProjectFactory.GetOrCreateProject("razorpages_rc", Output); diff --git a/src/ProjectTemplates/test/WorkerTemplateTest.cs b/src/ProjectTemplates/test/WorkerTemplateTest.cs index 0a3bca6568..1bc2d8d5b3 100644 --- a/src/ProjectTemplates/test/WorkerTemplateTest.cs +++ b/src/ProjectTemplates/test/WorkerTemplateTest.cs @@ -22,6 +22,7 @@ namespace Templates.Test public ITestOutputHelper Output { get; } [Fact] + [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/19716")] public async Task WorkerTemplateAsync() { Project = await ProjectFactory.GetOrCreateProject("worker", Output); diff --git a/src/Servers/Kestrel/test/Interop.FunctionalTests/Interop.FunctionalTests.csproj b/src/Servers/Kestrel/test/Interop.FunctionalTests/Interop.FunctionalTests.csproj index ca861ff26b..9fff0431d9 100644 --- a/src/Servers/Kestrel/test/Interop.FunctionalTests/Interop.FunctionalTests.csproj +++ b/src/Servers/Kestrel/test/Interop.FunctionalTests/Interop.FunctionalTests.csproj @@ -6,6 +6,7 @@ Interop.FunctionalTests false + false