Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

365 lines
14 KiB
C#

// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Security.Principal;
using System.Web.TestUtil;
using Moq;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Mvc.Test
{
public class AuthorizeAttributeTest
{
[Fact]
public void AuthorizeAttributeReturnsUniqueTypeIDs()
{
// Arrange
AuthorizeAttribute attr1 = new AuthorizeAttribute();
AuthorizeAttribute attr2 = new AuthorizeAttribute();
// Assert
Assert.NotEqual(attr1.TypeId, attr2.TypeId);
}
[Authorize(Roles = "foo")]
[Authorize(Roles = "bar")]
private class ClassWithMultipleAuthorizeAttributes
{
}
[Fact]
public void CanRetrieveMultipleAuthorizeAttributesFromOneClass()
{
// Arrange
ClassWithMultipleAuthorizeAttributes @class = new ClassWithMultipleAuthorizeAttributes();
// Act
IEnumerable<AuthorizeAttribute> attributes = TypeDescriptor.GetAttributes(@class).OfType<AuthorizeAttribute>();
// Assert
Assert.Equal(2, attributes.Count());
Assert.True(attributes.Any(a => a.Roles == "foo"));
Assert.True(attributes.Any(a => a.Roles == "bar"));
}
[Fact]
public void AuthorizeCoreReturnsFalseIfNameDoesNotMatch()
{
// Arrange
AuthorizeAttributeHelper helper = new AuthorizeAttributeHelper() { Users = "SomeName" };
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(c => c.User.Identity.IsAuthenticated).Returns(true);
mockHttpContext.Setup(c => c.User.Identity.Name).Returns("SomeOtherName");
// Act
bool retVal = helper.PublicAuthorizeCore(mockHttpContext.Object);
// Assert
Assert.False(retVal);
}
[Fact]
public void AuthorizeCoreReturnsFalseIfRoleDoesNotMatch()
{
// Arrange
AuthorizeAttributeHelper helper = new AuthorizeAttributeHelper() { Roles = "SomeRole" };
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(c => c.User.Identity.IsAuthenticated).Returns(true);
mockHttpContext.Setup(c => c.User.IsInRole("SomeRole")).Returns(false).Verifiable();
// Act
bool retVal = helper.PublicAuthorizeCore(mockHttpContext.Object);
// Assert
Assert.False(retVal);
mockHttpContext.Verify();
}
[Fact]
public void AuthorizeCoreReturnsFalseIfUserIsUnauthenticated()
{
// Arrange
AuthorizeAttributeHelper helper = new AuthorizeAttributeHelper();
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(c => c.User.Identity.IsAuthenticated).Returns(false);
// Act
bool retVal = helper.PublicAuthorizeCore(mockHttpContext.Object);
// Assert
Assert.False(retVal);
}
[Fact]
public void AuthorizeCoreReturnsTrueIfUserIsAuthenticatedAndNamesOrRolesSpecified()
{
// Arrange
AuthorizeAttributeHelper helper = new AuthorizeAttributeHelper() { Users = "SomeUser, SomeOtherUser", Roles = "SomeRole, SomeOtherRole" };
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(c => c.User.Identity.IsAuthenticated).Returns(true);
mockHttpContext.Setup(c => c.User.Identity.Name).Returns("SomeUser");
mockHttpContext.Setup(c => c.User.IsInRole("SomeRole")).Returns(false).Verifiable();
mockHttpContext.Setup(c => c.User.IsInRole("SomeOtherRole")).Returns(true).Verifiable();
// Act
bool retVal = helper.PublicAuthorizeCore(mockHttpContext.Object);
// Assert
Assert.True(retVal);
mockHttpContext.Verify();
}
[Fact]
public void AuthorizeCoreReturnsTrueIfUserIsAuthenticatedAndNoNamesOrRolesSpecified()
{
// Arrange
AuthorizeAttributeHelper helper = new AuthorizeAttributeHelper();
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(c => c.User.Identity.IsAuthenticated).Returns(true);
// Act
bool retVal = helper.PublicAuthorizeCore(mockHttpContext.Object);
// Assert
Assert.True(retVal);
}
[Fact]
public void AuthorizeCoreThrowsIfHttpContextIsNull()
{
// Arrange
AuthorizeAttributeHelper helper = new AuthorizeAttributeHelper();
// Act & assert
Assert.ThrowsArgumentNull(
delegate { helper.PublicAuthorizeCore((HttpContextBase)null); }, "httpContext");
}
[Fact]
public void OnAuthorizationCallsHandleUnauthorizedRequestIfUserUnauthorized()
{
// Arrange
CustomFailAuthorizeAttribute attr = new CustomFailAuthorizeAttribute();
Mock<AuthorizationContext> mockAuthContext = new Mock<AuthorizationContext>();
mockAuthContext.Setup(c => c.HttpContext.User.Identity.IsAuthenticated).Returns(false);
mockAuthContext.Setup(c => c.HttpContext.Items).Returns(new Hashtable());
mockAuthContext.Setup(c => c.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true)).Returns(false);
AuthorizationContext authContext = mockAuthContext.Object;
// Act
attr.OnAuthorization(authContext);
// Assert
Assert.Equal(CustomFailAuthorizeAttribute.ExpectedResult, authContext.Result);
}
[Fact]
public void OnAuthorizationFailedSetsHttpUnauthorizedResultIfUserUnauthorized()
{
// Arrange
Mock<AuthorizeAttributeHelper> mockHelper = new Mock<AuthorizeAttributeHelper>() { CallBase = true };
mockHelper.Setup(h => h.PublicAuthorizeCore(It.IsAny<HttpContextBase>())).Returns(false);
AuthorizeAttributeHelper helper = mockHelper.Object;
AuthorizationContext filterContext = new Mock<AuthorizationContext>() { DefaultValue = DefaultValue.Mock }.Object;
// Act
helper.OnAuthorization(filterContext);
// Assert
Assert.IsType<HttpUnauthorizedResult>(filterContext.Result);
}
[Fact]
public void OnAuthorizationHooksCacheValidationIfUserAuthorized()
{
// Arrange
Mock<AuthorizeAttributeHelper> mockHelper = new Mock<AuthorizeAttributeHelper>() { CallBase = true };
mockHelper.Setup(h => h.PublicAuthorizeCore(It.IsAny<HttpContextBase>())).Returns(true);
AuthorizeAttributeHelper helper = mockHelper.Object;
MethodInfo callbackMethod = typeof(AuthorizeAttribute).GetMethod("CacheValidateHandler", BindingFlags.Instance | BindingFlags.NonPublic);
Mock<AuthorizationContext> mockFilterContext = new Mock<AuthorizationContext>();
mockFilterContext.Setup(c => c.HttpContext.Response.Cache.SetProxyMaxAge(new TimeSpan(0))).Verifiable();
mockFilterContext.Setup(c => c.HttpContext.Items).Returns(new Hashtable());
mockFilterContext
.Setup(c => c.HttpContext.Response.Cache.AddValidationCallback(It.IsAny<HttpCacheValidateHandler>(), null /* data */))
.Callback(
delegate(HttpCacheValidateHandler handler, object data)
{
Assert.Equal(helper, handler.Target);
Assert.Equal(callbackMethod, handler.Method);
})
.Verifiable();
mockFilterContext.Setup(c => c.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true)).Returns(false);
AuthorizationContext filterContext = mockFilterContext.Object;
// Act
helper.OnAuthorization(filterContext);
// Assert
mockFilterContext.Verify();
}
[Fact]
public void OnAuthorizationThrowsIfFilterContextIsNull()
{
// Arrange
AuthorizeAttribute attr = new AuthorizeAttribute();
// Act & assert
Assert.ThrowsArgumentNull(
delegate { attr.OnAuthorization(null); }, "filterContext");
}
[Fact]
public void OnAuthorizationReturnsWithNoResultIfAllowAnonymousAttributeIsDefinedOnAction()
{
// Arrange
Mock<AuthorizeAttributeHelper> mockHelper = new Mock<AuthorizeAttributeHelper>() { CallBase = true };
AuthorizeAttributeHelper helper = mockHelper.Object;
Mock<AuthorizationContext> mockFilterContext = new Mock<AuthorizationContext>();
mockFilterContext.Setup(c => c.HttpContext.Items).Returns(new Hashtable());
mockFilterContext.Setup(c => c.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true)).Returns(true);
// Act
helper.OnAuthorization(mockFilterContext.Object);
// Assert
Assert.Null(mockFilterContext.Object.Result);
mockHelper.Verify(h => h.PublicAuthorizeCore(It.IsAny<HttpContextBase>()), Times.Never());
}
[Fact]
public void OnAuthorizationReturnsWithNoResultIfAllowAnonymousAttributeIsDefinedOnController()
{
// Arrange
Mock<AuthorizeAttributeHelper> mockHelper = new Mock<AuthorizeAttributeHelper>() { CallBase = true };
AuthorizeAttributeHelper helper = mockHelper.Object;
Mock<AuthorizationContext> mockFilterContext = new Mock<AuthorizationContext>();
mockFilterContext.Setup(c => c.HttpContext.Items).Returns(new Hashtable());
mockFilterContext.Setup(c => c.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true)).Returns(true);
// Act
helper.OnAuthorization(mockFilterContext.Object);
// Assert
Assert.Null(mockFilterContext.Object.Result);
mockHelper.Verify(h => h.PublicAuthorizeCore(It.IsAny<HttpContextBase>()), Times.Never());
}
[Fact]
public void OnCacheAuthorizationReturnsIgnoreRequestIfUserIsUnauthorized()
{
// Arrange
Mock<AuthorizeAttributeHelper> mockHelper = new Mock<AuthorizeAttributeHelper>() { CallBase = true };
mockHelper.Setup(h => h.PublicAuthorizeCore(It.IsAny<HttpContextBase>())).Returns(false);
AuthorizeAttributeHelper helper = mockHelper.Object;
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(c => c.User).Returns(new Mock<IPrincipal>().Object);
// Act
HttpValidationStatus validationStatus = helper.PublicOnCacheAuthorization(mockHttpContext.Object);
// Assert
Assert.Equal(HttpValidationStatus.IgnoreThisRequest, validationStatus);
}
[Fact]
public void OnCacheAuthorizationReturnsValidIfUserIsAuthorized()
{
// Arrange
Mock<AuthorizeAttributeHelper> mockHelper = new Mock<AuthorizeAttributeHelper>() { CallBase = true };
mockHelper.Setup(h => h.PublicAuthorizeCore(It.IsAny<HttpContextBase>())).Returns(true);
AuthorizeAttributeHelper helper = mockHelper.Object;
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(c => c.User).Returns(new Mock<IPrincipal>().Object);
// Act
HttpValidationStatus validationStatus = helper.PublicOnCacheAuthorization(mockHttpContext.Object);
// Assert
Assert.Equal(HttpValidationStatus.Valid, validationStatus);
}
[Fact]
public void OnCacheAuthorizationThrowsIfHttpContextIsNull()
{
// Arrange
AuthorizeAttributeHelper helper = new AuthorizeAttributeHelper();
// Act & assert
Assert.ThrowsArgumentNull(
delegate { helper.PublicOnCacheAuthorization(null); }, "httpContext");
}
[Fact]
public void RolesProperty()
{
// Arrange
AuthorizeAttribute attr = new AuthorizeAttribute();
// Act & assert
MemberHelper.TestStringProperty(attr, "Roles", String.Empty);
}
[Fact]
public void UsersProperty()
{
// Arrange
AuthorizeAttribute attr = new AuthorizeAttribute();
// Act & assert
MemberHelper.TestStringProperty(attr, "Users", String.Empty);
}
public class AuthorizeAttributeHelper : AuthorizeAttribute
{
public virtual bool PublicAuthorizeCore(HttpContextBase httpContext)
{
return base.AuthorizeCore(httpContext);
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
return PublicAuthorizeCore(httpContext);
}
public virtual HttpValidationStatus PublicOnCacheAuthorization(HttpContextBase httpContext)
{
return base.OnCacheAuthorization(httpContext);
}
protected override HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext)
{
return PublicOnCacheAuthorization(httpContext);
}
}
public class CustomFailAuthorizeAttribute : AuthorizeAttribute
{
public static readonly ActionResult ExpectedResult = new ContentResult();
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
filterContext.Result = ExpectedResult;
}
}
}
}