Migrated OnlyLocalRequestsAttribute into netcore
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Umbraco.Tests.Common\Umbraco.Tests.Common.csproj" />
|
||||
<ProjectReference Include="..\Umbraco.Web.BackOffice\Umbraco.Web.BackOffice.csproj" />
|
||||
<ProjectReference Include="..\Umbraco.Web.Common\Umbraco.Web.Common.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Abstractions;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.AspNetCore.Mvc.Routing;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Web.BackOffice.Filters;
|
||||
|
||||
namespace Umbraco.Tests.UnitTests.Umbraco.Web.BackOffice.Filters
|
||||
{
|
||||
[TestFixture]
|
||||
public class OnlyLocalRequestsAttributeTests
|
||||
{
|
||||
[Test]
|
||||
public void Does_Not_Set_Result_When_No_Remote_Address()
|
||||
{
|
||||
// Arrange
|
||||
var context = CreateContext();
|
||||
var attribute = new OnlyLocalRequestsAttribute();
|
||||
|
||||
// Act
|
||||
attribute.OnActionExecuting(context);
|
||||
|
||||
// Assert
|
||||
Assert.IsNull(context.Result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Does_Not_Set_Result_When_Remote_Address_Is_Null_Ip_Address()
|
||||
{
|
||||
// Arrange
|
||||
var context = CreateContext(remoteIpAddress: "::1");
|
||||
var attribute = new OnlyLocalRequestsAttribute();
|
||||
|
||||
// Act
|
||||
attribute.OnActionExecuting(context);
|
||||
|
||||
// Assert
|
||||
Assert.IsNull(context.Result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Does_Not_Set_Result_When_Remote_Address_Matches_Local_Address()
|
||||
{
|
||||
// Arrange
|
||||
var context = CreateContext(remoteIpAddress: "100.1.2.3", localIpAddress: "100.1.2.3");
|
||||
var attribute = new OnlyLocalRequestsAttribute();
|
||||
|
||||
// Act
|
||||
attribute.OnActionExecuting(context);
|
||||
|
||||
// Assert
|
||||
Assert.IsNull(context.Result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Returns_Not_Found_When_Remote_Address_Does_Not_Match_Local_Address()
|
||||
{
|
||||
// Arrange
|
||||
var context = CreateContext(remoteIpAddress: "100.1.2.3", localIpAddress: "100.1.2.2");
|
||||
var attribute = new OnlyLocalRequestsAttribute();
|
||||
|
||||
// Act
|
||||
attribute.OnActionExecuting(context);
|
||||
|
||||
// Assert
|
||||
var typedResult = context.Result as NotFoundResult;
|
||||
Assert.IsNotNull(typedResult);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Does_Not_Set_Result_When_Remote_Address_Matches_LoopBack_Address()
|
||||
{
|
||||
// Arrange
|
||||
var context = CreateContext(remoteIpAddress: "127.0.0.1", localIpAddress: "::1");
|
||||
var attribute = new OnlyLocalRequestsAttribute();
|
||||
|
||||
// Act
|
||||
attribute.OnActionExecuting(context);
|
||||
|
||||
// Assert
|
||||
Assert.IsNull(context.Result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Returns_Not_Found_When_Remote_Address_Does_Not_Match_LoopBack_Address()
|
||||
{
|
||||
// Arrange
|
||||
var context = CreateContext(remoteIpAddress: "100.1.2.3", localIpAddress: "::1");
|
||||
var attribute = new OnlyLocalRequestsAttribute();
|
||||
|
||||
// Act
|
||||
attribute.OnActionExecuting(context);
|
||||
|
||||
// Assert
|
||||
var typedResult = context.Result as NotFoundResult;
|
||||
Assert.IsNotNull(typedResult);
|
||||
}
|
||||
|
||||
private static ActionExecutingContext CreateContext(string remoteIpAddress = null, string localIpAddress = null)
|
||||
{
|
||||
var httpContext = new DefaultHttpContext();
|
||||
if (!string.IsNullOrEmpty(remoteIpAddress))
|
||||
{
|
||||
httpContext.Connection.RemoteIpAddress = IPAddress.Parse(remoteIpAddress);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(localIpAddress))
|
||||
{
|
||||
httpContext.Connection.LocalIpAddress = IPAddress.Parse(localIpAddress);
|
||||
}
|
||||
|
||||
var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
|
||||
|
||||
return new ActionExecutingContext(
|
||||
actionContext,
|
||||
new List<IFilterMetadata>(),
|
||||
new Dictionary<string, object>(),
|
||||
new Mock<Controller>().Object);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Web.Common.Extensions;
|
||||
|
||||
namespace Umbraco.Web.BackOffice.Filters
|
||||
{
|
||||
public class OnlyLocalRequestsAttribute : ActionFilterAttribute
|
||||
{
|
||||
public override void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
if (!context.HttpContext.Request.IsLocal())
|
||||
{
|
||||
context.Result = new NotFoundResult();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System.Net;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Umbraco.Web.Common.Extensions
|
||||
{
|
||||
@@ -8,5 +9,34 @@ namespace Umbraco.Web.Common.Extensions
|
||||
{
|
||||
return request.Headers.TryGetValue("X-UMB-CULTURE", out var values) ? values[0] : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if a request is local.
|
||||
/// </summary>
|
||||
/// <returns>True if request is local</returns>
|
||||
/// <remarks>
|
||||
/// Hat-tip: https://stackoverflow.com/a/41242493/489433
|
||||
/// </remarks>
|
||||
public static bool IsLocal(this HttpRequest request)
|
||||
{
|
||||
var connection = request.HttpContext.Connection;
|
||||
if (connection.RemoteIpAddress.IsSet())
|
||||
{
|
||||
// We have a remote address set up
|
||||
return connection.LocalIpAddress.IsSet()
|
||||
// Is local is same as remote, then we are local
|
||||
? connection.RemoteIpAddress.Equals(connection.LocalIpAddress)
|
||||
// else we are remote if the remote IP address is not a loopback address
|
||||
: IPAddress.IsLoopback(connection.RemoteIpAddress);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool IsSet(this IPAddress address)
|
||||
{
|
||||
const string NullIpAddress = "::1";
|
||||
return address != null && address.ToString() != NullIpAddress;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,6 +147,7 @@
|
||||
<Compile Include="Composing\CompositionExtensions\Installer.cs" />
|
||||
<Compile Include="Composing\LightInject\LightInjectContainer.cs" />
|
||||
<Compile Include="Security\IdentityFactoryMiddleware.cs" />
|
||||
<Compile Include="WebApi\Filters\OnlyLocalRequestsAttribute.cs" />
|
||||
<Compile Include="WebAssets\CDF\ClientDependencyRuntimeMinifier.cs" />
|
||||
<Compile Include="Models\NoNodesViewModel.cs" />
|
||||
<Compile Include="Mvc\RenderNoContentController.cs" />
|
||||
@@ -225,7 +226,6 @@
|
||||
<Compile Include="UmbracoDbProviderFactoryCreator.cs" />
|
||||
<Compile Include="ViewDataExtensions.cs" />
|
||||
<Compile Include="WebApi\Filters\AdminUsersAuthorizeAttribute.cs" />
|
||||
<Compile Include="WebApi\Filters\OnlyLocalRequestsAttribute.cs" />
|
||||
<Compile Include="Runtime\WebInitialComposer.cs" />
|
||||
<Compile Include="Security\ActiveDirectoryBackOfficeUserPasswordChecker.cs" />
|
||||
<Compile Include="Security\BackOfficeUserPasswordCheckerResult.cs" />
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Web.Http.Filters;
|
||||
|
||||
namespace Umbraco.Web.WebApi.Filters
|
||||
{
|
||||
// Migrated to .NET Core
|
||||
public class OnlyLocalRequestsAttribute : ActionFilterAttribute
|
||||
{
|
||||
public override void OnActionExecuting(HttpActionContext actionContext)
|
||||
|
||||
Reference in New Issue
Block a user