Skip to content

Commit

Permalink
Declarative Authorization, step 2. #20
Browse files Browse the repository at this point in the history
  • Loading branch information
jezzsantos committed Jan 22, 2024
1 parent 05dedff commit 7602796
Show file tree
Hide file tree
Showing 51 changed files with 1,821 additions and 295 deletions.
65 changes: 65 additions & 0 deletions src/Application.Interfaces/ICallerContext.RolesAndFeatures.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using Domain.Interfaces.Authorization;

namespace Application.Interfaces;

/// <inheritdoc cref="ICallerContext" />
public partial interface ICallerContext
{
/// <summary>
/// Defines the authorization roles that a caller can have
/// </summary>
public class CallerRoles
{
public CallerRoles()
{
All = Array.Empty<string>();
Platform = Array.Empty<string>();
Organization = Array.Empty<string>();
}

public CallerRoles(string[]? platform, string[]? member)
{
Platform = platform ?? Array.Empty<string>();
Organization = member ?? Array.Empty<string>();
All = Platform
.Concat(Organization)
.Distinct()
.ToArray();
}

public string[] All { get; }

public string[] Organization { get; }

public string[] Platform { get; }
}

/// <summary>
/// Defines the sets of features that a caller can have
/// </summary>
public class CallerFeatureLevels
{
public CallerFeatureLevels()
{
All = Array.Empty<FeatureLevel>();
Platform = Array.Empty<FeatureLevel>();
Organization = Array.Empty<FeatureLevel>();
}

public CallerFeatureLevels(FeatureLevel[]? platform, FeatureLevel[]? member)
{
Platform = platform ?? Array.Empty<FeatureLevel>();
Organization = member ?? Array.Empty<FeatureLevel>();
All = Platform
.Concat(Organization)
.Distinct()
.ToArray();
}

public FeatureLevel[] All { get; }

public FeatureLevel[] Organization { get; }

public FeatureLevel[] Platform { get; }
}
}
61 changes: 1 addition & 60 deletions src/Application.Interfaces/ICallerContext.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
using Common;
using Domain.Interfaces.Authorization;

namespace Application.Interfaces;

/// <summary>
/// The context of the currently identified caller
/// </summary>
public interface ICallerContext
public partial interface ICallerContext
{
/// <summary>
/// Defines the scheme of the authorization
Expand Down Expand Up @@ -73,62 +72,4 @@ public CallerAuthorization(AuthorizationMethod method, string value)

public string Value { get; }
}

/// <summary>
/// Defines the authorization roles that a caller can have
/// </summary>
public class CallerRoles
{
public CallerRoles()
{
All = Array.Empty<string>();
Platform = Array.Empty<string>();
Organization = Array.Empty<string>();
}

public CallerRoles(string[]? platform, string[]? member)
{
Platform = platform ?? Array.Empty<string>();
Organization = member ?? Array.Empty<string>();
All = Platform
.Concat(Organization)
.Distinct()
.ToArray();
}

public string[] All { get; }

public string[] Organization { get; }

public string[] Platform { get; }
}

/// <summary>
/// Defines the sets of features that a caller can have
/// </summary>
public class CallerFeatureLevels
{
public CallerFeatureLevels()
{
All = Array.Empty<FeatureLevel>();
Platform = Array.Empty<FeatureLevel>();
Organization = Array.Empty<FeatureLevel>();
}

public CallerFeatureLevels(FeatureLevel[]? platform, FeatureLevel[]? member)
{
Platform = platform ?? Array.Empty<FeatureLevel>();
Organization = member ?? Array.Empty<FeatureLevel>();
All = Platform
.Concat(Organization)
.Distinct()
.ToArray();
}

public FeatureLevel[] All { get; }

public FeatureLevel[] Organization { get; }

public FeatureLevel[] Platform { get; }
}
}
185 changes: 185 additions & 0 deletions src/Domain.Interfaces.UnitTests/Authorization/FeatureLevelSpec.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
using Domain.Interfaces.Authorization;
using FluentAssertions;
using Xunit;

namespace Domain.Interfaces.UnitTests.Authorization;

[Trait("Category", "Unit")]
public class FeatureLevelSpec
{
[Fact]
public void WhenEqualsAndNamesDifferent_ThenReturnsFalse()
{
var level1 = new FeatureLevel("alevel1");
var level2 = new FeatureLevel("alevel2");

var result = level1.Equals(level2);

result.Should().BeFalse();
}

[Fact]
public void WhenEqualsAndNamesSameButNoChildren_ThenReturnsTrue()
{
var level1 = new FeatureLevel("alevel1");
var level2 = new FeatureLevel("alevel1");

var result = level1.Equals(level2);

result.Should().BeTrue();
}

[Fact]
public void WhenEqualsAndNamesSameButOneHasChild_ThenReturnsFalse()
{
var level1 = new FeatureLevel("alevel1");
var level2 = new FeatureLevel("alevel1", new FeatureLevel[] { new("achild1") });

var result = level1.Equals(level2);

Check failure on line 38 in src/Domain.Interfaces.UnitTests/Authorization/FeatureLevelSpec.cs

View workflow job for this annotation

GitHub Actions / All Tests

Domain.Interfaces.UnitTests.Authorization.FeatureLevelSpec ► WhenEqualsAndNamesSameButOneHasChild_ThenReturnsFalse

Failed test found in: src/TestResults/csharp/runneradmin_fv-az1212-317_2024-01-22_09_59_52[1].trx Error: Expected boolean to be false, but found True.
Raw output
Expected boolean to be false, but found True.
   at FluentAssertions.Execution.XUnit2TestFramework.Throw(String message)
   at FluentAssertions.Execution.TestFrameworkProvider.Throw(String message)
   at FluentAssertions.Execution.DefaultAssertionStrategy.HandleFailure(String message)
   at FluentAssertions.Execution.AssertionScope.FailWith(Func`1 failReasonFunc)
   at FluentAssertions.Primitives.BooleanAssertions`1.BeFalse(String because, Object[] becauseArgs)
   at Domain.Interfaces.UnitTests.Authorization.FeatureLevelSpec.WhenEqualsAndNamesSameButOneHasChild_ThenReturnsFalse() in D:\a\saastack\saastack\src\Domain.Interfaces.UnitTests\Authorization\FeatureLevelSpec.cs:line 38
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)

result.Should().BeFalse();
}

[Fact]
public void WhenEqualsAndNamesSameButOneHasGrandChild_ThenReturnsFalse()
{
var level1 = new FeatureLevel("alevel1", new FeatureLevel[] { new("achild1") });
var level2 = new FeatureLevel("alevel1",
new FeatureLevel[] { new("achild1", new FeatureLevel[] { new("achild2") }) });

var result = level1.Equals(level2);

Check failure on line 50 in src/Domain.Interfaces.UnitTests/Authorization/FeatureLevelSpec.cs

View workflow job for this annotation

GitHub Actions / All Tests

Domain.Interfaces.UnitTests.Authorization.FeatureLevelSpec ► WhenEqualsAndNamesSameButOneHasGrandChild_ThenReturnsFalse

Failed test found in: src/TestResults/csharp/runneradmin_fv-az1212-317_2024-01-22_09_59_52[1].trx Error: Expected boolean to be false, but found True.
Raw output
Expected boolean to be false, but found True.
   at FluentAssertions.Execution.XUnit2TestFramework.Throw(String message)
   at FluentAssertions.Execution.TestFrameworkProvider.Throw(String message)
   at FluentAssertions.Execution.DefaultAssertionStrategy.HandleFailure(String message)
   at FluentAssertions.Execution.AssertionScope.FailWith(Func`1 failReasonFunc)
   at FluentAssertions.Primitives.BooleanAssertions`1.BeFalse(String because, Object[] becauseArgs)
   at Domain.Interfaces.UnitTests.Authorization.FeatureLevelSpec.WhenEqualsAndNamesSameButOneHasGrandChild_ThenReturnsFalse() in D:\a\saastack\saastack\src\Domain.Interfaces.UnitTests\Authorization\FeatureLevelSpec.cs:line 50
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)

result.Should().BeFalse();
}

[Fact]
public void WhenEqualsAndNamesSameAndSameChild_ThenReturnsTrue()
{
var level1 = new FeatureLevel("alevel1", new FeatureLevel[] { new("achild1") });
var level2 = new FeatureLevel("alevel1", new FeatureLevel[] { new("achild1") });

var result = level1.Equals(level2);

result.Should().BeTrue();
}

[Fact]
public void WhenEqualsAndNamesSameAndDifferentAncestors_ThenReturnsFalse()
{
var level1 = new FeatureLevel("alevel1",
new FeatureLevel[] { new("achild1", new FeatureLevel[] { new("achild2") }) });
var level2 = new FeatureLevel("alevel1",
new FeatureLevel[] { new("achild1", new FeatureLevel[] { new("achild3") }) });

var result = level1.Equals(level2);

Check failure on line 74 in src/Domain.Interfaces.UnitTests/Authorization/FeatureLevelSpec.cs

View workflow job for this annotation

GitHub Actions / All Tests

Domain.Interfaces.UnitTests.Authorization.FeatureLevelSpec ► WhenEqualsAndNamesSameAndDifferentAncestors_ThenReturnsFalse

Failed test found in: src/TestResults/csharp/runneradmin_fv-az1212-317_2024-01-22_09_59_52[1].trx Error: Expected boolean to be false, but found True.
Raw output
Expected boolean to be false, but found True.
   at FluentAssertions.Execution.XUnit2TestFramework.Throw(String message)
   at FluentAssertions.Execution.TestFrameworkProvider.Throw(String message)
   at FluentAssertions.Execution.DefaultAssertionStrategy.HandleFailure(String message)
   at FluentAssertions.Execution.AssertionScope.FailWith(Func`1 failReasonFunc)
   at FluentAssertions.Primitives.BooleanAssertions`1.BeFalse(String because, Object[] becauseArgs)
   at Domain.Interfaces.UnitTests.Authorization.FeatureLevelSpec.WhenEqualsAndNamesSameAndDifferentAncestors_ThenReturnsFalse() in D:\a\saastack\saastack\src\Domain.Interfaces.UnitTests\Authorization\FeatureLevelSpec.cs:line 74
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)

result.Should().BeFalse();
}

[Fact]
public void WhenEqualsAndNamesSameAndSameAncestors_ThenReturnsTrue()
{
var level1 = new FeatureLevel("alevel1",
new FeatureLevel[] { new("achild1", new FeatureLevel[] { new("achild2") }) });
var level2 = new FeatureLevel("alevel1",
new FeatureLevel[] { new("achild1", new FeatureLevel[] { new("achild2") }) });

var result = level1.Equals(level2);

result.Should().BeTrue();
}

[Fact]
public void WhenIsDescendantAndHasNoChild_ThenFalse()
{
var level = new FeatureLevel("alevel1");

var result = level.IsDescendant(new FeatureLevel("achild"));

result.Should().BeFalse();
}

[Fact]
public void WhenIsDescendantAndHasChild_ThenTrue()
{
var level = new FeatureLevel("alevel1", new FeatureLevel[]
{
new("achild")
});

var result = level.IsDescendant(new FeatureLevel("achild"));

Check failure on line 110 in src/Domain.Interfaces.UnitTests/Authorization/FeatureLevelSpec.cs

View workflow job for this annotation

GitHub Actions / All Tests

Domain.Interfaces.UnitTests.Authorization.FeatureLevelSpec ► WhenIsDescendantAndHasChild_ThenTrue

Failed test found in: src/TestResults/csharp/runneradmin_fv-az1212-317_2024-01-22_09_59_52[1].trx Error: Expected boolean to be true, but found False.
Raw output
Expected boolean to be true, but found False.
   at FluentAssertions.Execution.XUnit2TestFramework.Throw(String message)
   at FluentAssertions.Execution.TestFrameworkProvider.Throw(String message)
   at FluentAssertions.Execution.DefaultAssertionStrategy.HandleFailure(String message)
   at FluentAssertions.Execution.AssertionScope.FailWith(Func`1 failReasonFunc)
   at FluentAssertions.Execution.AssertionScope.FailWith(Func`1 failReasonFunc)
   at FluentAssertions.Execution.AssertionScope.FailWith(String message, Object[] args)
   at FluentAssertions.Primitives.BooleanAssertions`1.BeTrue(String because, Object[] becauseArgs)
   at Domain.Interfaces.UnitTests.Authorization.FeatureLevelSpec.WhenIsDescendantAndHasChild_ThenTrue() in D:\a\saastack\saastack\src\Domain.Interfaces.UnitTests\Authorization\FeatureLevelSpec.cs:line 110
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)

result.Should().BeTrue();
}

[Fact]
public void WhenIsDescendantAndHasNoChild2_ThenFalse()
{
var level = new FeatureLevel("alevel1", new FeatureLevel[]
{
new("alevel2")
});

var result = level.IsDescendant(new FeatureLevel("achild2"));

result.Should().BeFalse();
}

[Fact]
public void WhenIsDescendantAndHasGrandChild_ThenTrue()
{
var level = new FeatureLevel("alevel1",
new FeatureLevel[]
{
new("alevel2", new FeatureLevel[]
{
new("achild")
})
});

var result = level.IsDescendant(new FeatureLevel("achild"));

Check failure on line 140 in src/Domain.Interfaces.UnitTests/Authorization/FeatureLevelSpec.cs

View workflow job for this annotation

GitHub Actions / All Tests

Domain.Interfaces.UnitTests.Authorization.FeatureLevelSpec ► WhenIsDescendantAndHasGrandChild_ThenTrue

Failed test found in: src/TestResults/csharp/runneradmin_fv-az1212-317_2024-01-22_09_59_52[1].trx Error: Expected boolean to be true, but found False.
Raw output
Expected boolean to be true, but found False.
   at FluentAssertions.Execution.XUnit2TestFramework.Throw(String message)
   at FluentAssertions.Execution.TestFrameworkProvider.Throw(String message)
   at FluentAssertions.Execution.DefaultAssertionStrategy.HandleFailure(String message)
   at FluentAssertions.Execution.AssertionScope.FailWith(Func`1 failReasonFunc)
   at FluentAssertions.Primitives.BooleanAssertions`1.BeTrue(String because, Object[] becauseArgs)
   at Domain.Interfaces.UnitTests.Authorization.FeatureLevelSpec.WhenIsDescendantAndHasGrandChild_ThenTrue() in D:\a\saastack\saastack\src\Domain.Interfaces.UnitTests\Authorization\FeatureLevelSpec.cs:line 140
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)

result.Should().BeTrue();
}

[Fact]
public void WhenIsDescendantAndHasGreatGrandChild_ThenTrue()
{
var level = new FeatureLevel("alevel1",
new FeatureLevel[]
{
new("alevel2", new FeatureLevel[]
{
new("alevel3", new FeatureLevel[]
{
new("achild")
})
})
});

var result = level.IsDescendant(new FeatureLevel("achild"));

Check failure on line 160 in src/Domain.Interfaces.UnitTests/Authorization/FeatureLevelSpec.cs

View workflow job for this annotation

GitHub Actions / All Tests

Domain.Interfaces.UnitTests.Authorization.FeatureLevelSpec ► WhenIsDescendantAndHasGreatGrandChild_ThenTrue

Failed test found in: src/TestResults/csharp/runneradmin_fv-az1212-317_2024-01-22_09_59_52[1].trx Error: Expected boolean to be true, but found False.
Raw output
Expected boolean to be true, but found False.
   at FluentAssertions.Execution.XUnit2TestFramework.Throw(String message)
   at FluentAssertions.Execution.TestFrameworkProvider.Throw(String message)
   at FluentAssertions.Execution.DefaultAssertionStrategy.HandleFailure(String message)
   at FluentAssertions.Execution.AssertionScope.FailWith(Func`1 failReasonFunc)
   at FluentAssertions.Primitives.BooleanAssertions`1.BeTrue(String because, Object[] becauseArgs)
   at Domain.Interfaces.UnitTests.Authorization.FeatureLevelSpec.WhenIsDescendantAndHasGreatGrandChild_ThenTrue() in D:\a\saastack\saastack\src\Domain.Interfaces.UnitTests\Authorization\FeatureLevelSpec.cs:line 160
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)

result.Should().BeTrue();
}

[Fact]
public void WhenIsDescendantAndHasGreatGrandChild2_ThenTrue()
{
var level = new FeatureLevel("alevel1",
new FeatureLevel[]
{
new("alevel2",
new FeatureLevel[]
{
new("alevel3",
new FeatureLevel("achild1"),
new FeatureLevel("achild2"),
new FeatureLevel("achild3"))
})
});

var result = level.IsDescendant(new FeatureLevel("achild2"));

Check failure on line 181 in src/Domain.Interfaces.UnitTests/Authorization/FeatureLevelSpec.cs

View workflow job for this annotation

GitHub Actions / All Tests

Domain.Interfaces.UnitTests.Authorization.FeatureLevelSpec ► WhenIsDescendantAndHasGreatGrandChild2_ThenTrue

Failed test found in: src/TestResults/csharp/runneradmin_fv-az1212-317_2024-01-22_09_59_52[1].trx Error: Expected boolean to be true, but found False.
Raw output
Expected boolean to be true, but found False.
   at FluentAssertions.Execution.XUnit2TestFramework.Throw(String message)
   at FluentAssertions.Execution.TestFrameworkProvider.Throw(String message)
   at FluentAssertions.Execution.DefaultAssertionStrategy.HandleFailure(String message)
   at FluentAssertions.Execution.AssertionScope.FailWith(Func`1 failReasonFunc)
   at FluentAssertions.Primitives.BooleanAssertions`1.BeTrue(String because, Object[] becauseArgs)
   at Domain.Interfaces.UnitTests.Authorization.FeatureLevelSpec.WhenIsDescendantAndHasGreatGrandChild2_ThenTrue() in D:\a\saastack\saastack\src\Domain.Interfaces.UnitTests\Authorization\FeatureLevelSpec.cs:line 181
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)

result.Should().BeTrue();
}
}
7 changes: 7 additions & 0 deletions src/Domain.Interfaces/Authorization/FeatureLevel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,18 @@ public FeatureLevel(string name, params FeatureLevel[] childLevels)

public string Name { get; }

public bool IsDescendant(FeatureLevel feature)
{
//TODO: Iterate through all children recursively looking for the specified ancestor.
return false;
}

public override bool Equals(object? obj)
{
return ReferenceEquals(this, obj) || (obj is FeatureLevel other && Equals(other));
}

//TODO: Equals can only be the case if the name and the children match
public override int GetHashCode()
{
return Name.GetHashCode();
Expand Down
Loading

0 comments on commit 7602796

Please sign in to comment.