Browse Source

Use IHostingEnvironment to determine application identifier

Reverses changes made in #230
Nate McMaster 8 years ago
parent
commit
285b973a5c

+ 2 - 0
src/Microsoft.AspNetCore.DataProtection/DataProtectionServiceCollectionExtensions.cs

@@ -4,6 +4,7 @@
 using System;
 using Microsoft.AspNetCore.Cryptography.Cng;
 using Microsoft.AspNetCore.DataProtection;
+using Microsoft.AspNetCore.DataProtection.Infrastructure;
 using Microsoft.AspNetCore.DataProtection.Internal;
 using Microsoft.AspNetCore.DataProtection.KeyManagement;
 using Microsoft.AspNetCore.DataProtection.KeyManagement.Internal;
@@ -75,6 +76,7 @@ namespace Microsoft.Extensions.DependencyInjection
                 ServiceDescriptor.Transient<IConfigureOptions<DataProtectionOptions>, DataProtectionOptionsSetup>());
 
             services.TryAddSingleton<IKeyManager, XmlKeyManager>();
+            services.TryAddSingleton<IApplicationDiscriminator, HostingApplicationDiscriminator>();
 
             // Internal services
             services.TryAddSingleton<IDefaultKeyResolver, DefaultKeyResolver>();

+ 25 - 0
src/Microsoft.AspNetCore.DataProtection/Internal/HostingApplicationDiscriminator.cs

@@ -0,0 +1,25 @@
+// 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 Microsoft.AspNetCore.DataProtection.Infrastructure;
+using Microsoft.AspNetCore.Hosting;
+
+namespace Microsoft.AspNetCore.DataProtection.Internal
+{
+    internal class HostingApplicationDiscriminator : IApplicationDiscriminator
+    {
+        private readonly IHostingEnvironment _hosting;
+
+        // the optional constructor for when IHostingEnvironment is not available from DI
+        public HostingApplicationDiscriminator()
+        {
+        }
+
+        public HostingApplicationDiscriminator(IHostingEnvironment hosting)
+        {
+            _hosting = hosting;
+        }
+
+        public string Discriminator => _hosting?.ContentRootPath;
+    }
+}

+ 1 - 0
src/Microsoft.AspNetCore.DataProtection/Microsoft.AspNetCore.DataProtection.csproj

@@ -21,6 +21,7 @@
   </ItemGroup>
 
   <ItemGroup>
+    <PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="$(AspNetCoreVersion)" />
     <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="$(AspNetCoreVersion)" />
     <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="$(AspNetCoreVersion)" />
     <PackageReference Include="Microsoft.Extensions.Options" Version="$(AspNetCoreVersion)" />

+ 55 - 6
test/Microsoft.AspNetCore.DataProtection.Test/DataProtectionUtilityExtensionsTests.cs

@@ -3,6 +3,8 @@
 
 using System;
 using Microsoft.AspNetCore.DataProtection.Infrastructure;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.DependencyInjection;
 using Moq;
 using Xunit;
 
@@ -11,22 +13,56 @@ namespace Microsoft.AspNetCore.DataProtection
     public class DataProtectionUtilityExtensionsTests
     {
         [Theory]
+        [InlineData("app-path", "app-path")]
+        [InlineData("app-path ", "app-path")] // normalized trim
+        [InlineData("  ", null)] // normalized whitespace -> null
+        [InlineData(null, null)] // nothing provided at all
+        public void GetApplicationUniqueIdentifierFromHosting(string contentRootPath, string expected)
+        {
+            // Arrange
+            var mockEnvironment = new Mock<IHostingEnvironment>();
+            mockEnvironment.Setup(o => o.ContentRootPath).Returns(contentRootPath);
+
+            var services = new ServiceCollection()
+                .AddSingleton(mockEnvironment.Object)
+                .AddDataProtection()
+                .Services
+                .BuildServiceProvider();
+
+            // Act
+            var actual = services.GetApplicationUniqueIdentifier();
+
+            // Assert
+            Assert.Equal(expected, actual);
+        }
+
+        [Theory]
+        [InlineData(" discriminator ", "discriminator")]
         [InlineData(" discriminator", "discriminator")] // normalized trim
-        [InlineData("", null)] // app discriminator not null -> overrides app base path
+        [InlineData("  ", null)] // normalized whitespace -> null
         [InlineData(null, null)] // nothing provided at all
-        public void GetApplicationUniqueIdentifier(string appDiscriminator, string expected)
+        public void GetApplicationIdentifierFromApplicationDiscriminator(string discriminator, string expected)
         {
             // Arrange
             var mockAppDiscriminator = new Mock<IApplicationDiscriminator>();
-            mockAppDiscriminator.Setup(o => o.Discriminator).Returns(appDiscriminator);
-            var mockServiceProvider = new Mock<IServiceProvider>();
-            mockServiceProvider.Setup(o => o.GetService(typeof(IApplicationDiscriminator))).Returns(mockAppDiscriminator.Object);
+            mockAppDiscriminator.Setup(o => o.Discriminator).Returns(discriminator);
+
+            var mockEnvironment = new Mock<IHostingEnvironment>();
+            mockEnvironment.SetupGet(o => o.ContentRootPath).Throws(new InvalidOperationException("Hosting environment should not be checked"));
+
+            var services = new ServiceCollection()
+                .AddSingleton(mockEnvironment.Object)
+                .AddSingleton(mockAppDiscriminator.Object)
+                .AddDataProtection()
+                .Services
+                .BuildServiceProvider();
 
             // Act
-            string actual = mockServiceProvider.Object.GetApplicationUniqueIdentifier();
+            var actual = services.GetApplicationUniqueIdentifier();
 
             // Assert
             Assert.Equal(expected, actual);
+            mockAppDiscriminator.VerifyAll();
         }
 
         [Fact]
@@ -34,5 +70,18 @@ namespace Microsoft.AspNetCore.DataProtection
         {
             Assert.Null(((IServiceProvider)null).GetApplicationUniqueIdentifier());
         }
+
+        [Fact]
+        public void GetApplicationUniqueIdentifier_NoHostingEnvironment_ReturnsNull()
+        {
+            // arrange
+            var services = new ServiceCollection()
+              .AddDataProtection()
+              .Services
+              .BuildServiceProvider();
+
+            // act & assert
+            Assert.Null(services.GetApplicationUniqueIdentifier());
+        }
     }
 }