Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions NetCasbin.UnitTest/ModelTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -503,27 +503,32 @@ public void TestPriorityExplicitDenyOverrideModel()
TestEnforce(e, "alice", "data2", "write", true);
TestEnforce(e, "bob", "data2", "read", true);

// adding a new group, simulating behaviour when two different groups are added to the same person
// adding a new group, simulating behaviour when two different groups are added to the same person.
e.AddPolicy("10", "data2_deny_group_new", "data2", "write", "deny");
e.AddGroupingPolicy("alice", "data2_deny_group_new");

TestEnforce(e, "alice", "data2", "write", false);
TestEnforce(e, "bob", "data2", "read", true);

// adding higher priority policy for alice, to override group policies
// expected enforcement result should be true,
// as there is a policy with a lower rank 10, that produces allow result.
e.AddPolicy("5", "alice", "data2", "write", "allow");
TestEnforce(e, "alice", "data2", "write", true);

// adding deny policy for alice for the same obj,
// to ensure that if there is at least one deny, final result will be deny
// to ensure that if there is at least one deny, final result will be deny.
e.AddPolicy("5", "alice", "data2", "write", "deny");
TestEnforce(e, "alice", "data2", "write", false);

//adding higher priority policy for alice, to override group policies again
e.AddPolicy("1", "alice", "data2", "write", "allow");
// adding higher fake higher priority policy for alice,
// expected enforcement result should be true (ignore this policy).
e.AddPolicy("2", "alice", "data2", "write", "allow");
TestEnforce(e, "alice", "data2", "write", true);
e.AddPolicy("1", "fake-subject", "fake-object", "very-fake-action", "allow");
TestEnforce(e, "alice", "data2", "write", true);

//adding higher priority policy for alice, to override group policies again
// adding higher (less of 0) priority policy for alice,
// to override group policies again.
e.AddPolicy("-1", "alice", "data2", "write", "deny");
TestEnforce(e, "alice", "data2", "write", false);
}
Expand Down
57 changes: 28 additions & 29 deletions NetCasbin/CoreEnforcer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -832,11 +832,11 @@ private Task<bool> InternalEnforceAsync(IReadOnlyList<object> requestValues, str
/// <param name="requestValues">The request needs to be mediated, usually an array of strings,
/// can be class instances if ABAC is used.</param>
/// <param name="matcher">The custom matcher.</param>
/// <param name="explains"></param>
/// <param name="explains">Collection of matched policy explains</param>
/// <returns>Whether to allow the request.</returns>
private bool InternalEnforce(IReadOnlyList<object> requestValues, string matcher = null, ICollection<IEnumerable<string>> explains = null)
{
EnforceContext context = EnforceContext.Create(model, matcher, explains is not null);
var context = EnforceContext.Create(model, matcher, explains is not null);

if (context.RequestTokens.Count != requestValues.Count)
{
Expand Down Expand Up @@ -955,36 +955,43 @@ private bool InternalEnforce(IReadOnlyList<object> requestValues, string matcher
/// <param name="context">Storage of enforcer variables</param>
/// <param name="requestValues">The request needs to be mediated, usually an array of strings, can be class instances if ABAC is used.</param>
/// <param name="explains">Collection of matched policy explains</param>
/// <param name="maxPriority">Index of maxPriority to filter out lower tier policies</param>
/// <returns>Whether to allow the request.</returns>
private bool InternalEnforceWithChainEffector(
EnforceContext context,
IChainEffector chainEffector,
IReadOnlyList<object> requestValues = null,
ICollection<IEnumerable<string>> explains = null,
PolicyEffectType effectType = PolicyEffectType.Custom,
int maxPriority = int.MaxValue)
ICollection<IEnumerable<string>> explains = null)
{
bool result = false;
bool finalResult = false;
chainEffector.StartChain(context.Effect);

bool hasPriority = context.PolicyAssertion.TryGetPriorityIndex(out int priorityIndex);
bool isPriorityDenyOverrideEfffet = chainEffector.PolicyEffectType is PolicyEffectType.PriorityDenyOverride;
int? priority = null;
var nowEffect = Effect.Effect.Indeterminate;

if (context.Policies.Count is not 0)
{
IEnumerable<IReadOnlyList<string>> policies = context.Policies;
if (hasPriority && chainEffector.PolicyEffectType is PolicyEffectType.PriorityDenyOverride)
{
policies = policies.Where(t => maxPriority == int.MaxValue || int.Parse(t[priorityIndex]) == maxPriority);
}

foreach (IReadOnlyList<string> policyValues in policies)
foreach (IReadOnlyList<string> policyValues in context.Policies)
{
if (context.PolicyTokens.Count != policyValues.Count)
{
throw new ArgumentException($"Invalid policy size: expected {context.PolicyTokens.Count}, got {policyValues.Count}.");
}

if (hasPriority && isPriorityDenyOverrideEfffet)
{
if (int.TryParse(policyValues[priorityIndex], out int nowPriority))
{
if (priority.HasValue && nowPriority != priority.Value
&& nowEffect is not Effect.Effect.Indeterminate)
{
break;
}
priority = nowPriority;
}
}

ExpressionHandler.SetPolicyParameters(policyValues);

bool expressionResult;
Expand All @@ -999,15 +1006,7 @@ private bool InternalEnforceWithChainEffector(
expressionResult = ExpressionHandler.Invoke(context.Matcher, requestValues);
}

var nowEffect = GetEffect(expressionResult);

if (context.Effect.Equals(PermConstants.PolicyEffect.PriorityDenyOverride)
&& nowEffect == Effect.Effect.Allow
&& maxPriority == int.MaxValue)
{
return InternalEnforceWithChainEffector(context, chainEffector, requestValues, explains, effectType,
int.Parse(policyValues[priorityIndex]));
}
nowEffect = GetEffect(expressionResult);

if (nowEffect is not Effect.Effect.Indeterminate
&& ExpressionHandler.Parameters.TryGetValue("p_eft", out Parameter parameter))
Expand All @@ -1034,7 +1033,7 @@ private bool InternalEnforceWithChainEffector(
}
}

result = chainEffector.Result;
finalResult = chainEffector.Result;
}
else
{
Expand All @@ -1045,11 +1044,11 @@ private bool InternalEnforceWithChainEffector(

IReadOnlyList<string> policyValues = Enumerable.Repeat(string.Empty, context.PolicyTokens.Count).ToArray();
ExpressionHandler.SetPolicyParameters(policyValues);
Effect.Effect nowEffect = GetEffect(ExpressionHandler.Invoke(context.Matcher, requestValues));
nowEffect = GetEffect(ExpressionHandler.Invoke(context.Matcher, requestValues));

if (chainEffector.TryChain(nowEffect))
{
result = chainEffector.Result;
finalResult = chainEffector.Result;
}

if (context.Explain && chainEffector.HitPolicy)
Expand All @@ -1061,14 +1060,14 @@ private bool InternalEnforceWithChainEffector(
#if !NET45
if (context.Explain)
{
Logger?.LogEnforceResult(requestValues, result, explains);
Logger?.LogEnforceResult(requestValues, finalResult, explains);
}
else
{
Logger?.LogEnforceResult(requestValues, result);
Logger?.LogEnforceResult(requestValues, finalResult);
}
#endif
return result;
return finalResult;
}

private static Effect.Effect GetEffect(bool expressionResult)
Expand Down