Implementing AdminAuthorizationFilter to test for AccessAdminPanel

Authorization will be required for a controller named "Admin"
or when an [Admin] attribute is on controller, base controllers, or action
Result will be HttpUnauthorizedResult if current user does not
have StandardPermissions.AccessAdminPanel

--HG--
branch : dev
This commit is contained in:
Louis DeJardin
2010-02-26 00:50:19 -08:00
parent ca7d66cff8
commit fe29853912
6 changed files with 191 additions and 35 deletions

View File

@@ -156,6 +156,7 @@
<Compile Include="Mvc\RouteCollectionPublisherTests.cs" />
<Compile Include="Mvc\Routes\StandardExtensionRouteProviderTests.cs" />
<Compile Include="Tasks\SweepGeneratorTests.cs" />
<Compile Include="UI\Admin\AdminAttributeTests.cs" />
<Compile Include="UI\Notify\NotifierTests.cs" />
<Compile Include="UI\Notify\NotifyFilterTests.cs" />
<Compile Include="Services\ClockTests.cs" />

View File

@@ -0,0 +1,134 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using Moq;
using NUnit.Framework;
using Orchard.Localization;
using Orchard.Security;
using Orchard.Security.Permissions;
using Orchard.UI.Admin;
namespace Orchard.Tests.UI.Admin {
[TestFixture]
public class AdminAttributeTests {
private static AuthorizationContext GetAuthorizationContext<TController>() {
var controllerDescriptor = new ReflectedControllerDescriptor(typeof(TController));
var controllerContext = new ControllerContext();
return new AuthorizationContext(
controllerContext,
controllerDescriptor.FindAction(controllerContext, "Index"));
}
private static IAuthorizer GetAuthorizer(bool result) {
var authorizer = new Mock<IAuthorizer>();
authorizer
.Setup(x => x.Authorize(StandardPermissions.AccessAdminPanel, It.IsAny<LocalizedString>())).
Returns(result);
return authorizer.Object;
}
[Test]
public void NormalRequestShouldNotBeAffected() {
var authorizationContext = GetAuthorizationContext<NormalController>();
var filter = new AdminAuthorizationFilter(GetAuthorizer(false));
filter.OnAuthorization(authorizationContext);
Assert.That(authorizationContext.Result, Is.Null);
}
[Test]
public void AdminRequestShouldRequirePermission() {
var authorizationContext = GetAuthorizationContext<AdminController>();
var filter = new AdminAuthorizationFilter(GetAuthorizer(false));
filter.OnAuthorization(authorizationContext);
Assert.That(authorizationContext.Result, Is.InstanceOf<HttpUnauthorizedResult>());
var authorizationContext2 = GetAuthorizationContext<AdminController>();
var filter2 = new AdminAuthorizationFilter(GetAuthorizer(true));
filter2.OnAuthorization(authorizationContext2);
Assert.That(authorizationContext2.Result, Is.Null);
}
[Test]
public void NormalWithAttribRequestShouldRequirePermission() {
var authorizationContext = GetAuthorizationContext<NormalWithAttribController>();
var filter = new AdminAuthorizationFilter(GetAuthorizer(false));
filter.OnAuthorization(authorizationContext);
Assert.That(authorizationContext.Result, Is.InstanceOf<HttpUnauthorizedResult>());
var authorizationContext2 = GetAuthorizationContext<NormalWithAttribController>();
var filter2 = new AdminAuthorizationFilter(GetAuthorizer(true));
filter2.OnAuthorization(authorizationContext2);
Assert.That(authorizationContext2.Result, Is.Null);
}
[Test]
public void NormalWithActionAttribRequestShouldRequirePermission() {
var authorizationContext = GetAuthorizationContext<NormalWithActionAttribController>();
var filter = new AdminAuthorizationFilter(GetAuthorizer(false));
filter.OnAuthorization(authorizationContext);
Assert.That(authorizationContext.Result, Is.InstanceOf<HttpUnauthorizedResult>());
var authorizationContext2 = GetAuthorizationContext<NormalWithActionAttribController>();
var filter2 = new AdminAuthorizationFilter(GetAuthorizer(true));
filter2.OnAuthorization(authorizationContext2);
Assert.That(authorizationContext2.Result, Is.Null);
}
[Test]
public void InheritedAttribRequestShouldRequirePermission() {
var authorizationContext = GetAuthorizationContext<InheritedAttribController>();
var filter = new AdminAuthorizationFilter(GetAuthorizer(false));
filter.OnAuthorization(authorizationContext);
Assert.That(authorizationContext.Result, Is.InstanceOf<HttpUnauthorizedResult>());
var authorizationContext2 = GetAuthorizationContext<InheritedAttribController>();
var filter2 = new AdminAuthorizationFilter(GetAuthorizer(true));
filter2.OnAuthorization(authorizationContext2);
Assert.That(authorizationContext2.Result, Is.Null);
}
}
public class NormalController : Controller {
public ActionResult Index() {
return View();
}
}
public class AdminController : Controller {
public ActionResult Index() {
return View();
}
}
[Admin]
public class NormalWithAttribController : Controller {
public ActionResult Index() {
return View();
}
}
public class NormalWithActionAttribController : Controller {
[Admin]
public ActionResult Index() {
return View();
}
}
[Admin]
public class BaseWithAttribController : Controller {
public ActionResult Something() {
return View();
}
}
public class InheritedAttribController : BaseWithAttribController {
public ActionResult Index() {
return View();
}
}
}

View File

@@ -225,7 +225,8 @@
<Compile Include="Extensions\ExtensionDescriptor.cs" />
<Compile Include="Extensions\ExtensionEntry.cs" />
<Compile Include="IOrchardServices.cs" />
<Compile Include="UI\Admin\AdminFilter.cs" />
<Compile Include="UI\Admin\AdminAttribute.cs" />
<Compile Include="UI\Admin\AdminAuthorizationFilter.cs" />
<Compile Include="Mvc\AntiForgery\AntiForgeryAuthorizationFilter.cs" />
<Compile Include="Mvc\Html\FileRegistrationContext.cs" />
<Compile Include="Mvc\Html\MvcFormAntiForgeryPost.cs" />

View File

@@ -0,0 +1,6 @@
using System;
namespace Orchard.UI.Admin {
public class AdminAttribute : Attribute {
}
}

View File

@@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Orchard.Localization;
using Orchard.Mvc.Filters;
using Orchard.Security;
namespace Orchard.UI.Admin {
public class AdminAuthorizationFilter : FilterProvider, IAuthorizationFilter {
private readonly IAuthorizer _authorizer;
public AdminAuthorizationFilter(IAuthorizer authorizer) {
_authorizer = authorizer;
T = NullLocalizer.Instance;
}
public Localizer T { get; set; }
public void OnAuthorization(AuthorizationContext filterContext) {
if (!IsAdmin(filterContext))
return;
if (!_authorizer.Authorize(StandardPermissions.AccessAdminPanel, T("Can't access the admin"))) {
filterContext.Result = new HttpUnauthorizedResult();
}
}
private static bool IsAdmin(AuthorizationContext filterContext) {
if (string.Equals(filterContext.ActionDescriptor.ControllerDescriptor.ControllerName, "Admin",
StringComparison.InvariantCultureIgnoreCase)) {
return true;
}
var adminAttributes = GetAdminAttributes(filterContext.ActionDescriptor);
if (adminAttributes != null && adminAttributes.Any()) {
return true;
}
return false;
}
private static IEnumerable<AdminAttribute> GetAdminAttributes(ActionDescriptor descriptor) {
return descriptor.GetCustomAttributes(typeof(AdminAttribute), true)
.Concat(descriptor.ControllerDescriptor.GetCustomAttributes(typeof(AdminAttribute), true))
.OfType<AdminAttribute>();
}
}
}

View File

@@ -1,34 +0,0 @@
using System.Globalization;
using System.IO;
using System.Web.Mvc;
using Orchard.Mvc.Filters;
using Orchard.Security;
using Orchard.Settings;
namespace Orchard.UI.Admin {
public class AdminFilter : FilterProvider, IActionFilter
{
private readonly IAuthorizer _authorizer;
private readonly ISiteService _siteService;
public AdminFilter(IAuthorizer authorizer, ISiteService siteService)
{
_authorizer = authorizer;
_siteService = siteService;
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
var siteUrl = _siteService.GetSiteSettings().SiteUrl;
//todo: (heskew) get at the admin path in a less hacky way
if (filterContext.HttpContext.Request.RawUrl.StartsWith(Path.Combine(siteUrl, "admin").Replace("\\", "/"), true, CultureInfo.InvariantCulture)
&& !_authorizer.Authorize(StandardPermissions.AccessAdminPanel, "Can't access the admin")) {
filterContext.Result = new HttpUnauthorizedResult();
}
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
}
}
}