Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

- Fixed issue with RequireRolePolicy resolving roles 3 times/execution.

- Added extension method EnsureIsList<T> for ensuring we are working with a list and to prevent multiple enumerations.
  • Loading branch information...
commit 475e69a0e71475acb0258e75fb70fc4b05535655 1 parent 6a22709
Kristoffer Ahl authored
View
20 FluentSecurity.Specification/Policy/RequireRolePolicySpec.cs
@@ -3,6 +3,7 @@
using FluentSecurity.Policy;
using FluentSecurity.Specification.Helpers;
using FluentSecurity.Specification.TestData;
+using Moq;
using NUnit.Framework;
namespace FluentSecurity.Specification.Policy
@@ -67,6 +68,25 @@ public void Should_return_expected_roles()
public class When_enforcing_security_for_a_RequireRolePolicy
{
[Test]
+ public void Should_resolve_authentication_status_and_roles_exactly_once()
+ {
+ // Arrange
+ var roles = new object[1];
+ var policy = new RequireRolePolicy(roles);
+ var context = new Mock<ISecurityContext>();
+ context.Setup(x => x.CurrenUserAuthenticated()).Returns(true);
+ context.Setup(x => x.CurrenUserRoles()).Returns(roles);
+
+ // Act
+ var result = policy.Enforce(context.Object);
+
+ // Assert
+ Assert.That(result.ViolationOccured, Is.False);
+ context.Verify(x => x.CurrenUserAuthenticated(), Times.Exactly(1), "The authentication status should be resolved at most once.");
+ context.Verify(x => x.CurrenUserRoles(), Times.Exactly(1), "The roles should be resolved at most once.");
+ }
+
+ [Test]
public void Should_not_be_successful_when_isAuthenticated_is_false()
{
// Arrange
View
10 FluentSecurity/Extensions.cs
@@ -168,6 +168,16 @@ internal static void Each<T>(this IEnumerable<T> items, Action<T> action)
}
/// <summary>
+ /// Ensures we are working with a list of T
+ /// </summary>
+ internal static IList<T> EnsureIsList<T>(this IEnumerable<T> items)
+ {
+ return items == null
+ ? new List<T>()
+ : (items as IList<T> ?? items.ToList());
+ }
+
+ /// <summary>
/// Returns true if the value is null or empty
/// </summary>
/// <param name="value">The value</param>
View
5 FluentSecurity/Policy/RequireRolePolicy.cs
@@ -25,10 +25,11 @@ public PolicyResult Enforce(ISecurityContext context)
if (context.CurrenUserAuthenticated() == false)
return PolicyResult.CreateFailureResult(this, "Anonymous access denied");
- if (context.CurrenUserRoles() == null || context.CurrenUserRoles().Any() == false)
+ var currentUserRoles = context.CurrenUserRoles().EnsureIsList();
+ if (currentUserRoles.Any() == false)
return PolicyResult.CreateFailureResult(this, "Access denied");
- if (context.CurrenUserRoles().Any(role => _requiredRoles.Contains(role)) == false)
+ if (currentUserRoles.Any(role => _requiredRoles.Contains(role)) == false)
{
const string message = "Access requires one of the following roles: {0}.";
var formattedMessage = string.Format(message, GetRoles());
Please sign in to comment.
Something went wrong with that request. Please try again.