Migrated AppendUserModifiedHeaderAttribute into netcore
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Abstractions;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Web.BackOffice.Filters;
|
||||
using Umbraco.Web.Security;
|
||||
|
||||
namespace Umbraco.Tests.UnitTests.Umbraco.Web.BackOffice.Filters
|
||||
{
|
||||
[TestFixture]
|
||||
public class AppendUserModifiedHeaderAttributeTests
|
||||
{
|
||||
[Test]
|
||||
public void Appends_Header_When_No_User_Parameter_Provider()
|
||||
{
|
||||
// Arrange
|
||||
var context = CreateContext();
|
||||
var attribute = new AppendUserModifiedHeaderAttribute();
|
||||
|
||||
// Act
|
||||
attribute.OnActionExecuting(context);
|
||||
|
||||
// Assert
|
||||
context.HttpContext.Response.Headers.TryGetValue("X-Umb-User-Modified", out var headerValue);
|
||||
Assert.AreEqual("1", headerValue[0]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Does_Not_Append_Header_If_Already_Exists()
|
||||
{
|
||||
// Arrange
|
||||
var context = CreateContext(headerValue: "0");
|
||||
var attribute = new AppendUserModifiedHeaderAttribute();
|
||||
|
||||
// Act
|
||||
attribute.OnActionExecuting(context);
|
||||
|
||||
// Assert
|
||||
context.HttpContext.Response.Headers.TryGetValue("X-Umb-User-Modified", out var headerValue);
|
||||
Assert.AreEqual("0", headerValue[0]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Does_Not_Append_Header_When_User_Id_Parameter_Provided_And_Does_Not_Match_Current_User()
|
||||
{
|
||||
// Arrange
|
||||
var context = CreateContext(actionArgument: new KeyValuePair<string, object>("UserId", 99));
|
||||
var userIdParameter = "UserId";
|
||||
var attribute = new AppendUserModifiedHeaderAttribute(userIdParameter);
|
||||
|
||||
// Act
|
||||
attribute.OnActionExecuting(context);
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(context.HttpContext.Response.Headers.ContainsKey("X-Umb-User-Modified"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Appends_Header_When_User_Id_Parameter_Provided_And_Does_Not_Match_Current_User()
|
||||
{
|
||||
// Arrange
|
||||
var context = CreateContext(actionArgument: new KeyValuePair<string, object>("UserId", 100));
|
||||
var userIdParameter = "UserId";
|
||||
var attribute = new AppendUserModifiedHeaderAttribute(userIdParameter);
|
||||
|
||||
// Act
|
||||
attribute.OnActionExecuting(context);
|
||||
|
||||
// Assert
|
||||
context.HttpContext.Response.Headers.TryGetValue("X-Umb-User-Modified", out var headerValue);
|
||||
Assert.AreEqual("1", headerValue[0]);
|
||||
}
|
||||
|
||||
private static ActionExecutingContext CreateContext(string headerValue = null, KeyValuePair<string, object> actionArgument = default)
|
||||
{
|
||||
var httpContext = new DefaultHttpContext();
|
||||
if (!string.IsNullOrEmpty(headerValue))
|
||||
{
|
||||
httpContext.Response.Headers.Add("X-Umb-User-Modified", headerValue);
|
||||
}
|
||||
|
||||
var currentUserMock = new Mock<IUser>();
|
||||
currentUserMock
|
||||
.SetupGet(x => x.Id)
|
||||
.Returns(100);
|
||||
|
||||
var webSecurityMock = new Mock<IWebSecurity>();
|
||||
webSecurityMock
|
||||
.SetupGet(x => x.CurrentUser)
|
||||
.Returns(currentUserMock.Object);
|
||||
|
||||
var serviceProviderMock = new Mock<IServiceProvider>();
|
||||
serviceProviderMock
|
||||
.Setup(x => x.GetService(typeof(IWebSecurity)))
|
||||
.Returns(webSecurityMock.Object);
|
||||
|
||||
httpContext.RequestServices = serviceProviderMock.Object;
|
||||
|
||||
var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
|
||||
|
||||
var context = new ActionExecutingContext(
|
||||
actionContext,
|
||||
new List<IFilterMetadata>(),
|
||||
new Dictionary<string, object>(),
|
||||
new Mock<Controller>().Object);
|
||||
|
||||
if (!EqualityComparer<KeyValuePair<string, object>>.Default.Equals(actionArgument, default))
|
||||
{
|
||||
context.ActionArguments.Add(actionArgument);
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
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;
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Web.Security;
|
||||
|
||||
namespace Umbraco.Web.BackOffice.Filters
|
||||
{
|
||||
/// <summary>
|
||||
/// Appends a custom response header to notify the UI that the current user data has been modified
|
||||
/// </summary>
|
||||
public sealed class AppendUserModifiedHeaderAttribute : ActionFilterAttribute
|
||||
{
|
||||
private readonly string _userIdParameter;
|
||||
|
||||
/// <summary>
|
||||
/// An empty constructor which will always set the header.
|
||||
/// </summary>
|
||||
public AppendUserModifiedHeaderAttribute()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A constructor specifying the action parameter name containing the user id to match against the
|
||||
/// current user and if they match the header will be appended.
|
||||
/// </summary>
|
||||
/// <param name="userIdParameter"></param>
|
||||
public AppendUserModifiedHeaderAttribute(string userIdParameter)
|
||||
{
|
||||
_userIdParameter = userIdParameter ?? throw new ArgumentNullException(nameof(userIdParameter));
|
||||
}
|
||||
|
||||
public override void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
if (_userIdParameter.IsNullOrWhiteSpace())
|
||||
{
|
||||
AppendHeader(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!context.ActionArguments.ContainsKey(_userIdParameter))
|
||||
{
|
||||
throw new InvalidOperationException($"No argument found for the current action with the name: {_userIdParameter}");
|
||||
}
|
||||
|
||||
var webSecurityService = context.HttpContext.RequestServices.GetService<IWebSecurity>();
|
||||
var user = webSecurityService.CurrentUser;
|
||||
if (user == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var userId = GetUserIdFromParameter(context.ActionArguments[_userIdParameter]);
|
||||
if (userId == user.Id)
|
||||
{
|
||||
AppendHeader(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void AppendHeader(ActionExecutingContext context)
|
||||
{
|
||||
const string HeaderName = "X-Umb-User-Modified";
|
||||
if (context.HttpContext.Response.Headers.ContainsKey(HeaderName) == false)
|
||||
{
|
||||
context.HttpContext.Response.Headers.Add(HeaderName, "1");
|
||||
}
|
||||
}
|
||||
|
||||
private int GetUserIdFromParameter(object parameterValue)
|
||||
{
|
||||
if (parameterValue is int)
|
||||
{
|
||||
return (int)parameterValue;
|
||||
}
|
||||
|
||||
throw new InvalidOperationException($"The id type: {parameterValue.GetType()} is not a supported id.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ namespace Umbraco.Web.WebApi.Filters
|
||||
/// <summary>
|
||||
/// Appends a custom response header to notify the UI that the current user data has been modified
|
||||
/// </summary>
|
||||
/// Migrated to NET core
|
||||
public sealed class AppendUserModifiedHeaderAttribute : ActionFilterAttribute
|
||||
{
|
||||
private readonly string _userIdParameter;
|
||||
|
||||
Reference in New Issue
Block a user