blob: 42fac31dfecaecce8303fc5bd3c408b8c9c38fd1 [file] [log] [blame]
using System;
using System.Collections.Generic;
using Casbin.Evaluation;
namespace Casbin.Effect
{
/// <summary>
/// DefaultEffector is default effector for Casbin.
/// </summary>
public class DefaultEffector : IEffector, IChainEffector
{
public EffectChain CreateChain(string effectExpression) => new(effectExpression);
public EffectChain CreateChain(string effectExpression, EffectExpressionType effectExpressionType) =>
new(effectExpression, effectExpressionType);
/// <summary>
/// Merges all matching results collected by the enforcer into a single decision.
/// </summary>
/// <param name="effectExpression"></param>
/// <param name="effects"></param>
/// <param name="matches"></param>
/// <param name="policyIndex"></param>
/// <param name="policyCount"></param>
/// <param name="hitPolicyIndex"></param>
/// <returns></returns>
public PolicyEffect MergeEffects(string effectExpression, IReadOnlyList<PolicyEffect> effects,
IReadOnlyList<float> matches, int policyIndex, int policyCount, out int hitPolicyIndex)
{
EffectExpressionType effectExpressionType = ParseEffectExpressionType(effectExpression);
bool? result = MergeEffects(effectExpressionType, effects, matches, policyIndex, policyCount,
out hitPolicyIndex);
return result.ToPolicyEffect();
}
/// <summary>
/// Merges all matching results collected by the enforcer into a single decision.
/// </summary>
/// <param name="effectExpressionType"></param>
/// <param name="effects"></param>
/// <param name="matches"></param>
/// <param name="policyCount"></param>
/// <param name="hitPolicyIndex"></param>
/// <param name="policyIndex"></param>
/// <returns></returns>
private static bool? MergeEffects(EffectExpressionType effectExpressionType,
IReadOnlyList<PolicyEffect> effects,
IReadOnlyList<float> matches, int policyIndex, int policyCount, out int hitPolicyIndex)
{
hitPolicyIndex = -1;
int effectCount = policyIndex + 1;
bool finalResult = false;
for (int index = 0; index < effectCount; index++)
{
if (EffectEvaluator.TryEvaluate(effects[index], effectExpressionType,
ref finalResult, out bool hitPolicy))
{
if (hitPolicy)
{
hitPolicyIndex = index;
}
return finalResult;
}
}
if (effectCount == policyCount)
{
return finalResult;
}
return null;
}
public static EffectExpressionType ParseEffectExpressionType(string effectExpression) => effectExpression switch
{
PermConstants.PolicyEffect.AllowOverride => EffectExpressionType.AllowOverride,
PermConstants.PolicyEffect.DenyOverride => EffectExpressionType.DenyOverride,
PermConstants.PolicyEffect.AllowAndDeny => EffectExpressionType.AllowAndDeny,
PermConstants.PolicyEffect.Priority => EffectExpressionType.Priority,
PermConstants.PolicyEffect.SubjectPriority => EffectExpressionType.PriorityAllOverride,
PermConstants.PolicyEffect.PriorityDenyOverride => EffectExpressionType.PriorityDenyOverride,
_ => throw new NotSupportedException("Not supported policy effect.")
};
}
}