Skip to content

Commit

Permalink
feat: Make expression handler stateless
Browse files Browse the repository at this point in the history
Signed-off-by: Sagilio <Sagilio@outlook.com>
  • Loading branch information
sagilio committed Nov 21, 2021
1 parent bb8b51b commit 1003f5b
Show file tree
Hide file tree
Showing 25 changed files with 674 additions and 381 deletions.
4 changes: 2 additions & 2 deletions NetCasbin.UnitTest/Fixtures/TestModelFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,9 @@ public static string GetTestFile(string fileName)
private static IModel LoadModelFromMemory(IModel model, string policy)
{
model.ClearPolicy();
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(policy)))
using (MemoryStream ms = new(Encoding.UTF8.GetBytes(policy)))
{
FileAdapter fileAdapter = new FileAdapter(ms);
FileAdapter fileAdapter = new(ms);
fileAdapter.LoadPolicy(model);
}
model.RefreshPolicyStringSet();
Expand Down
13 changes: 13 additions & 0 deletions NetCasbin/Abstractions/Caching/IExpressionCache.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace Casbin.Caching;

public interface IExpressionCache<T> : IExpressionCache
{
public bool TryGet(string expressionString, out T t);

public void Set(string expressionString, T t);
}

public interface IExpressionCache
{
public void Clear();
}
10 changes: 10 additions & 0 deletions NetCasbin/Abstractions/Caching/IGFunctionCache.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Casbin.Caching;

public interface IGFunctionCache
{
public void Set(string name1, string name2, bool result, string domain = null);

public bool TryGet(string name1, string name2, out bool result, string domain = null);

public void Clear();
}
8 changes: 8 additions & 0 deletions NetCasbin/Abstractions/Caching/IGFunctionCachePool.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Casbin.Caching;

public interface IGFunctionCachePool
{
public IGFunctionCache GetCache(string roleType);

public void Clear(string roleType);
}
2 changes: 2 additions & 0 deletions NetCasbin/Abstractions/Effect/IChainEffector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@
public interface IChainEffector
{
public IEffectChain CreateChain(string policyEffect);

public IEffectChain CreateChain(string policyEffect, EffectExpressionType effectExpressionType);
}
}
27 changes: 5 additions & 22 deletions NetCasbin/Abstractions/Evaluation/IExpressionHandler.cs
Original file line number Diff line number Diff line change
@@ -1,27 +1,10 @@
using System;
using System.Collections.Generic;
using DynamicExpresso;

namespace Casbin.Evaluation
{
public interface IExpressionHandler
{
public EnforceContext EnforceContext { get; }

public IDictionary<string, Parameter> Parameters { get; }

public void SetEnforceContext(in EnforceContext context);

public void SetFunction(string name, Delegate function);
namespace Casbin.Evaluation;

public void SetGFunctions();

public void EnsureCreated(string expressionString, IReadOnlyList<object> requestValues);

public bool Invoke(string expressionString, IReadOnlyList<object> requestValues);

public void SetRequestParameters(IReadOnlyList<object> requestValues);
public interface IExpressionHandler
{
public void SetFunction(string name, Delegate function);

public void SetPolicyParameters(IReadOnlyList<string> policyValues);
}
public bool Invoke(in EnforceContext context, ref EnforceSession session);
}
37 changes: 35 additions & 2 deletions NetCasbin/Abstractions/Model/IModel.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using Casbin.Caching;
using System.Collections.Generic;
using Casbin.Caching;
using Casbin.Evaluation;
using Casbin.Rbac;

namespace Casbin.Model
{
Expand All @@ -13,12 +15,43 @@ public interface IModel : IPolicy

public IExpressionHandler ExpressionHandler { get; }

public IPolicyManager PolicyManager { get; set; }
IPolicyManager PolicyManager { get; set; }

public void LoadModelFromFile(string path);

public void LoadModelFromText(string text);

public bool AddDef(string section, string key, string value);

public void SetRoleManager(string roleType, IRoleManager roleManager);

/// <summary>
/// Provides incremental build the role inheritance relation.
/// </summary>
/// <param name="policyOperation"></param>
/// <param name="section"></param>
/// <param name="roleType"></param>
/// <param name="rule"></param>
public void BuildIncrementalRoleLink(PolicyOperation policyOperation,
string section, string roleType, IEnumerable<string> rule);

/// <summary>
/// Provides incremental build the role inheritance relations.
/// </summary>
/// <param name="policyOperation"></param>
/// <param name="section"></param>
/// <param name="roleType"></param>
/// <param name="rules"></param>
public void BuildIncrementalRoleLinks(PolicyOperation policyOperation,
string section, string roleType, IEnumerable<IEnumerable<string>> rules);

/// <summary>
/// Initializes the roles in RBAC.
/// </summary>
public void BuildRoleLinks(string roleType = null);

public void RefreshPolicyStringSet();

public void SortPoliciesByPriority();
}
}
29 changes: 0 additions & 29 deletions NetCasbin/Abstractions/Model/IPolicy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,6 @@ public interface IPolicy

public Assertion GetRequiredAssertion(string section, string type);

/// <summary>
/// Provides incremental build the role inheritance relation.
/// </summary>
/// <param name="policyOperation"></param>
/// <param name="section"></param>
/// <param name="policyType"></param>
/// <param name="rule"></param>
public void BuildIncrementalRoleLink(PolicyOperation policyOperation,
string section, string policyType, IEnumerable<string> rule);

/// <summary>
/// Provides incremental build the role inheritance relations.
/// </summary>
/// <param name="policyOperation"></param>
/// <param name="section"></param>
/// <param name="policyType"></param>
/// <param name="rules"></param>
public void BuildIncrementalRoleLinks(PolicyOperation policyOperation,
string section, string policyType, IEnumerable<IEnumerable<string>> rules);

/// <summary>
/// Initializes the roles in RBAC.
/// </summary>
public void BuildRoleLinks();

public void RefreshPolicyStringSet();

public void SortPoliciesByPriority();

public IEnumerable<IEnumerable<string>> GetPolicy(string section, string policyType);

public IEnumerable<IEnumerable<string>> GetFilteredPolicy(string section, string policyType, int fieldIndex,
Expand Down
39 changes: 39 additions & 0 deletions NetCasbin/Caching/ExpressionCache.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using DynamicExpresso;

namespace Casbin.Caching;

internal class ExpressionCache : IExpressionCache<Lambda>
{
private readonly Lazy<Dictionary<string, Lambda>> _cache = new();

public bool TryGet(string expressionString, out Lambda lambda)
{
return _cache.Value.TryGetValue(expressionString, out lambda);
}

public void Set(string expressionString, Lambda lambda)
{
_cache.Value[expressionString] = lambda;
}

public void Clear() => _cache.Value.Clear();
}

internal class ExpressionCache<TFunc> : IExpressionCache<TFunc> where TFunc : Delegate
{
private readonly Lazy<Dictionary<string, TFunc>> _cache = new();

public bool TryGet(string expressionString, out TFunc func)
{
return _cache.Value.TryGetValue(expressionString, out func);
}

public void Set(string expressionString, TFunc func)
{
_cache.Value[expressionString] = func;
}

public void Clear() => _cache.Value.Clear();
}
31 changes: 31 additions & 0 deletions NetCasbin/Caching/GFunctionCache.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Collections.Generic;

namespace Casbin.Caching;

public class GFunctionCache : IGFunctionCache
{
private readonly Dictionary<string, bool> _cache = new();

public void Set(string name1, string name2, bool result, string domain = null)
{
_cache[Key(name1, name2, domain)] = result;
}

public bool TryGet(string name1, string name2, out bool result, string domain = null)
{
return _cache.TryGetValue(Key(name1, name2, domain), out result);
}

private static string Key(string name1, string name2, string domain = null)
{
bool hasDomain = domain is not null;
return hasDomain
? string.Join(":", name1, name2, domain)
: string.Join(":", name1, name2);
}

public void Clear()
{
_cache.Clear();
}
}
28 changes: 28 additions & 0 deletions NetCasbin/Caching/GFunctionPool.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.Collections.Generic;

namespace Casbin.Caching;

public class GFunctionCachePool : IGFunctionCachePool
{
private readonly Dictionary<string, IGFunctionCache> _cachePool = new();

public void Clear(string roleType)
{
if (_cachePool.TryGetValue(roleType, out IGFunctionCache cache))
{
cache.Clear();
}
}

public IGFunctionCache GetCache(string roleType)
{
if (_cachePool.TryGetValue(roleType, out IGFunctionCache cache))
{
return cache;
}

cache = new GFunctionCache();
_cachePool[roleType] = cache;
return cache;
}
}
1 change: 1 addition & 0 deletions NetCasbin/Casbin.csproj
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<!--EXTERNAL_PROPERTIES: TargetFramework-->
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
Expand Down
8 changes: 7 additions & 1 deletion NetCasbin/Effect/DefaultEffector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ public PolicyEffect MergeEffects(string effectExpression, IReadOnlyList<PolicyEf
/// <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)
Expand Down Expand Up @@ -69,6 +71,10 @@ public PolicyEffect MergeEffects(string effectExpression, IReadOnlyList<PolicyEf
_ => throw new NotSupportedException("Not supported policy effect.")
};

public IEffectChain CreateChain(string effectExpression) => new EffectChain(effectExpression);
public IEffectChain CreateChain(string effectExpression)
=> new EffectChain(effectExpression);

public IEffectChain CreateChain(string effectExpression, EffectExpressionType effectExpressionType)
=> new EffectChain(effectExpression, effectExpressionType);
}
}
16 changes: 14 additions & 2 deletions NetCasbin/Effect/EffectChain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@ public EffectChain(string effectExpression)
HitPolicyCount = 0;
}

public EffectChain(string effectExpression, EffectExpressionType effectExpressionType)
{
EffectExpression = effectExpression;
EffectExpressionType = effectExpressionType;

CanChain = true;
Result = false;

HitPolicy = false;
HitPolicyCount = 0;
}

public bool Result { get; private set; }

public bool HitPolicy { get; private set; }
Expand All @@ -25,9 +37,9 @@ public EffectChain(string effectExpression)

public bool CanChain { get; private set; }

public string EffectExpression { get; private set; }
public string EffectExpression { get; }

public EffectExpressionType EffectExpressionType { get; private set; }
public EffectExpressionType EffectExpressionType { get; }

public bool Chain(PolicyEffect effect)
{
Expand Down
2 changes: 1 addition & 1 deletion NetCasbin/EnforceSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace Casbin;

internal ref struct EnforceSession
public ref struct EnforceSession
{
internal IReadOnlyList<object> RequestValues { get; set; }
internal IReadOnlyList<string> PolicyValues { get; set; }
Expand Down
21 changes: 18 additions & 3 deletions NetCasbin/EnforceView.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
using System.Diagnostics.CodeAnalysis;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Casbin.Effect;
using Casbin.Model;
using Casbin.Util;

namespace Casbin
{
// The netstandard 2.0 TFM is not support private init.
// TODO: The .NET Standard 2.0 TFM is not support private init.
[SuppressMessage("ReSharper", "PropertyCanBeMadeInitOnly.Local")]
public class EnforceView
{
public IReadOnlyAssertion RequestAssertion { get; private set; }
public IReadOnlyList<string> RequestTokens { get; private set; }

public IReadOnlyAssertion PolicyAssertion { get; private set; }
public IReadOnlyList<string> PolicyTokens { get; private set; }

public bool HasPriority { get; private set; }
public int PriorityIndex { get; private set; }

Expand Down Expand Up @@ -39,16 +45,25 @@ public static EnforceView CreateWithMatcher(
string effectType = PermConstants.DefaultPolicyEffectType,
bool escapeMatcher = true)
{
IReadOnlyAssertion requestAssertion = model.GetRequiredAssertion(PermConstants.Section.RequestSection, requestType);
IReadOnlyAssertion policyAssertion = model.GetRequiredAssertion(PermConstants.Section.PolicySection, policyType);
IReadOnlyAssertion effectAssertion = model.GetRequiredAssertion(PermConstants.Section.PolicyEffectSection, effectType);
var view = new EnforceView
{
RequestAssertion = model.GetRequiredAssertion(PermConstants.Section.RequestSection, requestType),
RequestAssertion = requestAssertion,
// TODO: ToImmutableArray dot support .NET 4.5.2
RequestTokens = requestAssertion.Tokens.Keys.ToArray(),

PolicyAssertion = policyAssertion,
// TODO: ToImmutableArray dot support .NET 4.5.2
PolicyTokens = policyAssertion.Tokens.Keys.ToArray(),

Matcher = escapeMatcher ? StringUtil.EscapeAssertion(matcher) : matcher,
HasEval = StringUtil.HasEval(matcher),

Effect = effectAssertion.Value,
EffectExpressionType = DefaultEffector.ParseEffectExpressionType(effectAssertion.Value),

HasPriority = policyAssertion.TryGetTokenIndex("priority", out int priorityIndex),
PriorityIndex = priorityIndex,
};
Expand Down
Loading

0 comments on commit 1003f5b

Please sign in to comment.