From 43f4ef4ace5d0df5d10f796250b18734307fe3d2 Mon Sep 17 00:00:00 2001 From: sagilio Date: Wed, 17 Apr 2024 21:05:23 +0800 Subject: [PATCH 1/3] Revert "fix: fix bugs in policy equal and persist (#347)" This reverts commit 33063757b27dfdf1256bbed7e0ea93ced99ac197. --- Casbin/Abstractions/Model/IPolicyValues.cs | 2 -- Casbin/Model/PolicyValues.cs | 20 +------------------- Casbin/Persist/PersistantPolicy.cs | 4 ++-- 3 files changed, 3 insertions(+), 23 deletions(-) diff --git a/Casbin/Abstractions/Model/IPolicyValues.cs b/Casbin/Abstractions/Model/IPolicyValues.cs index 6783b4e..41e3371 100644 --- a/Casbin/Abstractions/Model/IPolicyValues.cs +++ b/Casbin/Abstractions/Model/IPolicyValues.cs @@ -10,6 +10,4 @@ public interface IPolicyValues : IList public string ToText(); public bool Equals(IPolicyValues other); - - int GetRealCount(); } diff --git a/Casbin/Model/PolicyValues.cs b/Casbin/Model/PolicyValues.cs index f6b254a..720bd46 100644 --- a/Casbin/Model/PolicyValues.cs +++ b/Casbin/Model/PolicyValues.cs @@ -17,9 +17,6 @@ public record PolicyValues : IPolicyValues public bool IsReadOnly => false; int ICollection.Count => Values.Count; - - - int IPolicyValues.GetRealCount() => Count; string IList.this[int index] { get => Values[index]; set => new NotImplementedException(); } @@ -37,22 +34,7 @@ internal static string ToText(IEnumerable values) => string.Join(PermConstants.PolicySeparatorString, values); internal static bool Equals(T values, T other) where T : IPolicyValues - { - if (values.GetRealCount() != other.GetRealCount()) - { - return false; - } - - for(int i = 0; i< values.GetRealCount(); i++) - { - if (values[i] != other[i]) - { - return false; - } - } - - return true; - } + => values.Count == other.Count && values.ToText().Equals(other.ToText()); internal static string ToStringValue(T value) => value as string ?? value.ToString(); diff --git a/Casbin/Persist/PersistantPolicy.cs b/Casbin/Persist/PersistantPolicy.cs index 61f1427..b6567e4 100644 --- a/Casbin/Persist/PersistantPolicy.cs +++ b/Casbin/Persist/PersistantPolicy.cs @@ -31,7 +31,7 @@ public static TPersistPolicy Create(string section, string type, where TPersistPolicy : IPersistPolicy, new() { TPersistPolicy persistPolicy = new TPersistPolicy { Section = section, Type = type }; - switch (values.GetRealCount()) + switch (values.Count) { case 1: persistPolicy.Value1 = values[0]; @@ -136,7 +136,7 @@ public static TPersistPolicy Create(string section, string type, persistPolicy.Value12 = values[11]; break; default: - throw new ArgumentOutOfRangeException(nameof(values), values.GetRealCount(), + throw new ArgumentOutOfRangeException(nameof(values), values.Count, "The number of values must be between 1 and 12."); } From 8f647b5f7697fd127306d54664e50d8a8974727a Mon Sep 17 00:00:00 2001 From: sagilio Date: Wed, 17 Apr 2024 21:05:50 +0800 Subject: [PATCH 2/3] Revert "feat: fix null value handling logic (#337)" This reverts commit 54db948595c86122761d6a15fbd23f63e15adcdf. --- .../DefaultPolicyManagerBenchmark.cs | 8 +- .../GenericTests/GenericMatcherTest.cs | 33 +- Casbin/Abstractions/Model/IPolicyValues.cs | 5 +- Casbin/EnforceView.cs | 3 +- Casbin/Enforcer.Internal.cs | 32 +- Casbin/Model/DefaultPolicyStore.Node.cs | 14 +- Casbin/Model/Policy.cs | 188 +++++++-- Casbin/Model/PolicyValues.cs | 376 +++++++++++++++--- 8 files changed, 533 insertions(+), 126 deletions(-) diff --git a/Casbin.Benchmark/DefaultPolicyManagerBenchmark.cs b/Casbin.Benchmark/DefaultPolicyManagerBenchmark.cs index 653f855..5f2365d 100644 --- a/Casbin.Benchmark/DefaultPolicyManagerBenchmark.cs +++ b/Casbin.Benchmark/DefaultPolicyManagerBenchmark.cs @@ -49,9 +49,9 @@ public void GlobalSetup() if (num == 0) { NowTestExistedPolicyList.Add( - new PolicyValues($"group{i}", $"obj{i / 10}", "read")); + new PolicyValues($"group{i}", $"obj{i / 10}", "read")); NowTestNullPolicyList.Add( - new PolicyValues($"name{i}", $"data{i / 10}", "read")); + new PolicyValues($"name{i}", $"data{i / 10}", "read")); } } @@ -59,7 +59,7 @@ public void GlobalSetup() NowTestUserName = $"name{NowPolicyCount / 2 + 1}"; NowTestDataName = $"data{NowPolicyCount / 2 + 1}"; - NowTestPolicy = new PolicyValues(NowTestUserName, NowTestDataName, "read"); + NowTestPolicy = new PolicyValues(NowTestUserName, NowTestDataName, "read"); Console.WriteLine($"// Already set user name to {NowTestUserName}."); Console.WriteLine($"// Already set data name to {NowTestDataName}."); } @@ -83,7 +83,7 @@ public async Task RemovePolicyAsync() public async Task UpdatePolicyAsync() { await _policyManager.UpdatePolicyAsync(NowTestPolicy, - new PolicyValues(NowTestUserName + "up", NowTestDataName + "up", "read")); + new PolicyValues(NowTestUserName + "up", NowTestDataName + "up", "read")); } [Benchmark] diff --git a/Casbin.UnitTests/GenericTests/GenericMatcherTest.cs b/Casbin.UnitTests/GenericTests/GenericMatcherTest.cs index 5689f81..e533c3b 100644 --- a/Casbin.UnitTests/GenericTests/GenericMatcherTest.cs +++ b/Casbin.UnitTests/GenericTests/GenericMatcherTest.cs @@ -10,26 +10,25 @@ public class GenericMatcherTest [Fact] public void TestGenericMatcher() { - //RequestValues r = Request.CreateValues("A", 1); - //PolicyValues p = Policy.CreateValues("A", 1); - //Func, PolicyValues, bool> func1 = Compile( - // "r.Value1 == p[0].GetType()(p[0]) && r.Value2 == p[1].GetType()(p[1])", - // nameof(r), in r, nameof(p), in p); + RequestValues r = Request.CreateValues("A", 1); + PolicyValues p = Policy.CreateValues("A", 1); + Func, PolicyValues, bool> func1 = Compile( + "r.Value1 == p.Value1 && r.Value2 == p.Value2", + nameof(r), in r, nameof(p), in p); - //Assert.True(func1(Request.CreateValues("A", 1), Policy.CreateValues("A", 1))); - //Assert.False(func1(Request.CreateValues("A", 1), Policy.CreateValues("A", 2))); - //Assert.False(func1(Request.CreateValues("B", 1), Policy.CreateValues("B", 2))); + Assert.True(func1(Request.CreateValues("A", 1), Policy.CreateValues("A", 1))); + Assert.False(func1(Request.CreateValues("A", 1), Policy.CreateValues("A", 2))); + Assert.False(func1(Request.CreateValues("B", 1), Policy.CreateValues("B", 2))); - //RequestValues r2 = Request.CreateValues("A", 1, "read"); - //PolicyValues p2 = Policy.CreateValues("A", 1, "read"); - //Func, PolicyValues, bool> func2 = Compile( - // "r2.Value1 == p2[0] && r2.Value2 == p2[1] && r2.Value3 == p2[2]", - // nameof(r2), in r2, nameof(p2), in p2); + RequestValues r2 = Request.CreateValues("A", 1, "read"); + PolicyValues p2 = Policy.CreateValues("A", 1, "read"); + Func, PolicyValues, bool> func2 = Compile( + "r2.Value1 == p2.Value1 && r2.Value2 == p2.Value2 && r2.Value3 == p2.Value3", + nameof(r2), in r2, nameof(p2), in p2); - //Assert.True(func2(Request.CreateValues("A", 1, "read"), Policy.CreateValues("A", 1, "read"))); - //Assert.False(func2(Request.CreateValues("A", 1, "read"), Policy.CreateValues("A", 2, "read"))); - //Assert.False(func2(Request.CreateValues("B", 1, "read"), Policy.CreateValues("B", 2, "read"))); - Assert.True(1==1); + Assert.True(func2(Request.CreateValues("A", 1, "read"), Policy.CreateValues("A", 1, "read"))); + Assert.False(func2(Request.CreateValues("A", 1, "read"), Policy.CreateValues("A", 2, "read"))); + Assert.False(func2(Request.CreateValues("B", 1, "read"), Policy.CreateValues("B", 2, "read"))); } private static Func Compile diff --git a/Casbin/Abstractions/Model/IPolicyValues.cs b/Casbin/Abstractions/Model/IPolicyValues.cs index 41e3371..fefc826 100644 --- a/Casbin/Abstractions/Model/IPolicyValues.cs +++ b/Casbin/Abstractions/Model/IPolicyValues.cs @@ -1,9 +1,8 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; namespace Casbin.Model; -public interface IPolicyValues : IList +public interface IPolicyValues : IReadOnlyList { public new string this[int index] { get; } diff --git a/Casbin/EnforceView.cs b/Casbin/EnforceView.cs index c532377..cc0dc99 100644 --- a/Casbin/EnforceView.cs +++ b/Casbin/EnforceView.cs @@ -146,8 +146,7 @@ public static string TransformMatcher(in EnforceView view, string matcher) foreach (KeyValuePair tokenPair in view.PolicyAssertion.Tokens) { Regex reg = new Regex(perfix + $@"{view.PolicyType}\.{tokenPair.Key}" + suffix); - //matcher = reg.Replace(matcher, $"{view.PolicyType}.Value{tokenPair.Value + 1}"); - matcher = reg.Replace(matcher, $"{view.PolicyType}[{tokenPair.Value}]"); + matcher = reg.Replace(matcher, $"{view.PolicyType}.Value{tokenPair.Value + 1}"); } return matcher; diff --git a/Casbin/Enforcer.Internal.cs b/Casbin/Enforcer.Internal.cs index 5900ea5..fb5f3d9 100644 --- a/Casbin/Enforcer.Internal.cs +++ b/Casbin/Enforcer.Internal.cs @@ -30,8 +30,36 @@ private bool InternalEnforce(in EnforceContext context, in TRequest re return InternalEnforce(in context, requestValues); } - return InternalEnforce(in context, requestValues); - + return context.View.PolicyTokens.Count switch + { + 1 => InternalEnforce>(in context, requestValues), + 2 => InternalEnforce>(in context, requestValues), + 3 => InternalEnforce>(in context, requestValues), + 4 => InternalEnforce>(in context, + requestValues), + 5 => InternalEnforce>(in context, + requestValues), + 6 => InternalEnforce>( + in context, + requestValues), + 7 => InternalEnforce>( + in context, requestValues), + 8 => InternalEnforce>(in context, + requestValues), + 9 => InternalEnforce>( + in context, + requestValues), + 10 => InternalEnforce>(in context, requestValues), + 11 => InternalEnforce>(in context, requestValues), + 12 => InternalEnforce>(in context, requestValues), + _ => InternalEnforce(in context, requestValues) + }; } private bool InternalEnforce(in EnforceContext context, in TRequest requestValues) diff --git a/Casbin/Model/DefaultPolicyStore.Node.cs b/Casbin/Model/DefaultPolicyStore.Node.cs index 9634187..104e6a1 100644 --- a/Casbin/Model/DefaultPolicyStore.Node.cs +++ b/Casbin/Model/DefaultPolicyStore.Node.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Threading; namespace Casbin.Model; @@ -45,24 +44,19 @@ public IReadOnlyList SetPolicy(List valuesList) => public bool ContainsPolicy(IPolicyValues values) => PolicyTextSet.Contains(values.ToText()); - public bool ValidatePolicy(ref IPolicyValues values) + public bool ValidatePolicy(IPolicyValues values) { if (_assertion.Section is PermConstants.Section.RoleSection) { return _assertion.Tokens.Count <= values.Count; } - while(_assertion.Tokens.Count > values.Count) - { - values.Add(""); - } - - return _assertion.Tokens.Count >= values.Count; + return _assertion.Tokens.Count == values.Count; } public bool TryAddPolicy(IPolicyValues values) { - if (ValidatePolicy(ref values) is false) + if (ValidatePolicy(values) is false) { return false; } @@ -93,7 +87,7 @@ public bool TryAddPolicy(IPolicyValues values) public bool TryUpdatePolicy(IPolicyValues oldValues, IPolicyValues newValues) { - if (ValidatePolicy(ref newValues) is false) + if (ValidatePolicy(newValues) is false) { return false; } diff --git a/Casbin/Model/Policy.cs b/Casbin/Model/Policy.cs index def72ee..cae8942 100644 --- a/Casbin/Model/Policy.cs +++ b/Casbin/Model/Policy.cs @@ -12,67 +12,182 @@ public static bool SupportGeneric(int count) return count is >= 1 and <= 12; } - internal static PolicyValues CreateValues(IList values) => new(PolicyValues.ToText(values), values); + public static PolicyValues CreateValues(T1 value1) => new(value1); - internal static PolicyValues CreateValues(params object[] objs) => new(objs); + public static PolicyValues CreateValues(T1 value1, T2 value2) => new(value1, value2); - public static IPolicyValues ValuesFrom(IList values) + public static PolicyValues CreateValues(T1 value1, T2 value2, T3 value3) => + new(value1, value2, value3); + + public static PolicyValues + CreateValues(T1 value1, T2 value2, T3 value3, T4 value4) => + new(value1, value2, value3, value4); + + public static PolicyValues CreateValues(T1 value1, T2 value2, T3 value3, + T4 value4, T5 value5) => new(value1, value2, value3, value4, value5); + + public static PolicyValues CreateValues(T1 value1, T2 value2, + T3 value3, + T4 value4, T5 value5, T6 value6) => new(value1, value2, value3, value4, value5, value6); + + public static PolicyValues CreateValues(T1 value1, + T2 value2, + T3 value3, T4 value4, T5 value5, T6 value6, T7 value7) => + new(value1, value2, value3, value4, value5, value6, value7); + + public static PolicyValues CreateValues(T1 value1, + T2 value2, + T3 value3, + T4 value4, T5 value5, T6 value6, T7 value7, T8 value8) => + new(value1, value2, value3, value4, value5, value6, value7, + value8); + + public static PolicyValues CreateValues( + T1 value1, + T2 value2, T3 value3, + T4 value4, T5 value5, T6 value6, T7 value7, T8 value8, T9 value9) => + new(value1, value2, value3, value4, value5, value6, value7, + value8, value9); + + public static PolicyValues CreateValues( + T1 value1, T2 value2, T3 value3, + T4 value4, T5 value5, T6 value6, T7 value7, T8 value8, T9 value9, T10 value10) => + new(value1, value2, value3, value4, value5, value6, + value7, value8, value9, value10); + + public static PolicyValues CreateValues(T1 value1, T2 value2, T3 value3, + T4 value4, T5 value5, T6 value6, T7 value7, T8 value8, T9 value9, T10 value10, T11 value11) => + new(value1, value2, value3, value4, value5, value6, + value7, value8, value9, value10, value11); + + public static PolicyValues CreateValues(T1 value1, T2 value2, T3 value3, + T4 value4, T5 value5, T6 value6, T7 value7, T8 value8, T9 value9, T10 value10, T11 value11, T12 value12) => + new(value1, value2, value3, value4, value5, + value6, value7, value8, value9, value10, value11, value12); + + + internal static PolicyValues CreateValues(IReadOnlyList values, string value1) + => new(PolicyValues.ToText(values), value1, value1); + + internal static PolicyValues CreateValues(IReadOnlyList values, string value1, + string value2) + => new(PolicyValues.ToText(values), value1, value1, value2, value2); + + internal static PolicyValues CreateValues(IReadOnlyList values, string value1, + string value2, string value3) + => new(PolicyValues.ToText(values), value1, value1, value2, value2, value3, value3); + + internal static PolicyValues CreateValues(IReadOnlyList values, + string value1, + string value2, string value3, string value4) + => new(PolicyValues.ToText(values), value1, value1, value2, value2, value3, value3, value4, value4); + + internal static PolicyValues CreateValues(IReadOnlyList values, + string value1, string value2, string value3, string value4, string value5) + => new(PolicyValues.ToText(values), value1, value1, value2, value2, value3, value3, value4, value4, value5, + value5); + + internal static PolicyValues CreateValues( + IReadOnlyList values, + string value1, string value2, string value3, string value4, string value5, string value6) + => new(PolicyValues.ToText(values), value1, value1, value2, value2, value3, value3, value4, value4, value5, + value5, value6, + value6); + + internal static PolicyValues CreateValues( + IReadOnlyList values, string value1, string value2, string value3, string value4, string value5, + string value6, string value7) + => new(PolicyValues.ToText(values), value1, value1, value2, value2, value3, value3, value4, value4, value5, + value5, value6, + value6, value7, value7); + + public static IPolicyValues ValuesFrom(IReadOnlyList values) { - return CreateValues(values); + return values.Count switch + { + 1 => CreateValues(values, values[0]), + 2 => CreateValues(values, values[0], values[1]), + 3 => CreateValues(values, values[0], values[1], values[2]), + 4 => CreateValues(values, values[0], values[1], values[2], values[3]), + 5 => CreateValues(values, values[0], values[1], values[2], values[3], values[4]), + 6 => CreateValues(values, values[0], values[1], values[2], values[3], values[4], values[5]), + 7 => CreateValues(values, values[0], values[1], values[2], values[3], values[4], values[5], values[6]), + 8 => CreateValues(values[0], values[1], values[2], values[3], + values[4], values[5], values[6], values[7]), + 9 => CreateValues(values[0], values[1], values[2], values[3], + values[4], values[5], values[6], values[7], values[8]), + 10 => CreateValues(values[0], values[1], values[2], values[3], + values[4], values[5], values[6], values[7], values[8], + values[9]), + 11 => CreateValues(values[0], values[1], values[2], values[3], + values[4], values[5], values[6], values[7], values[8], + values[9], values[10]), + 12 => CreateValues(values[0], values[1], values[2], values[3], + values[4], values[5], values[6], values[7], values[8], + values[9], values[10], values[11]), + _ => new StringListPolicyValues(values) + }; } public static IPolicyValues ValuesFrom(IEnumerable values) => - ValuesFrom(values as IList ?? values.ToArray()); + ValuesFrom(values as IReadOnlyList ?? values.ToArray()); public static IPolicyValues ValuesFrom(IPersistPolicy values) { // Find the latest not empty value as the count. int count; - if (!(values.Value12 is null)) + if (string.IsNullOrWhiteSpace(values.Value12) is false) { count = 12; } - else if (!(values.Value11 is null)) + else if (string.IsNullOrWhiteSpace(values.Value11) is false) { count = 11; } - else if (!(values.Value10 is null)) + else if (string.IsNullOrWhiteSpace(values.Value10) is false) { count = 10; } - else if (!(values.Value9 is null)) + else if (string.IsNullOrWhiteSpace(values.Value9) is false) { count = 9; } - else if (!(values.Value8 is null)) + else if (string.IsNullOrWhiteSpace(values.Value8) is false) { count = 8; } - else if (!(values.Value7 is null)) + else if (string.IsNullOrWhiteSpace(values.Value7) is false) { count = 7; } - else if (!(values.Value6 is null)) + else if (string.IsNullOrWhiteSpace(values.Value6) is false) { count = 6; } - else if (!(values.Value5 is null)) + else if (string.IsNullOrWhiteSpace(values.Value5) is false) { count = 5; } - else if (!(values.Value4 is null)) + else if (string.IsNullOrWhiteSpace(values.Value4) is false) { count = 4; } - else if (!(values.Value3 is null)) + else if (string.IsNullOrWhiteSpace(values.Value3) is false) { count = 3; } - else if (!(values.Value2 is null)) + else if (string.IsNullOrWhiteSpace(values.Value2) is false) { count = 2; } - else if (!(values.Value1 is null)) + else if (string.IsNullOrWhiteSpace(values.Value1) is false) { count = 1; } @@ -83,31 +198,30 @@ public static IPolicyValues ValuesFrom(IPersistPolicy values) return count switch { - 1 => CreateValues(new List() { values.Value1 }), - 2 => CreateValues(new List() { values.Value1, values.Value2 }), - 3 => CreateValues(new List() { values.Value1, values.Value2, values.Value3 }), - 4 => CreateValues(new List() { values.Value1, values.Value2, values.Value3, values.Value4 }), - 5 => CreateValues(new List() { values.Value1, values.Value2, values.Value3, values.Value4, values.Value5 }), - 6 => CreateValues(new List() {values.Value1, values.Value2, values.Value3, values.Value4, values.Value5, - values.Value6 }), - 7 => CreateValues(new List() {values.Value1, values.Value2, values.Value3, values.Value4, values.Value5, - values.Value6, values.Value7 }), - 8 => CreateValues(new List() {values.Value1, values.Value2, values.Value3, values.Value4, values.Value5, - values.Value6, values.Value7, values.Value8 }), - 9 => CreateValues(new List() {values.Value1, values.Value2, values.Value3, values.Value4, values.Value5, - values.Value6, values.Value7, values.Value8, values.Value9 }), - 10 => CreateValues(new List() {values.Value1, values.Value2, values.Value3, values.Value4, values.Value5, - values.Value6, values.Value7, values.Value8, values.Value9, values.Value10 }), - 11 => CreateValues(new List() {values.Value1, values.Value2, values.Value3, values.Value4, values.Value5, - values.Value6, values.Value7, values.Value8, values.Value9, values.Value10, values.Value11 }), - 12 => CreateValues(new List() {values.Value1, values.Value2, values.Value3, values.Value4, values.Value5, + 1 => CreateValues(values.Value1), + 2 => CreateValues(values.Value1, values.Value2), + 3 => CreateValues(values.Value1, values.Value2, values.Value3), + 4 => CreateValues(values.Value1, values.Value2, values.Value3, values.Value4), + 5 => CreateValues(values.Value1, values.Value2, values.Value3, values.Value4, values.Value5), + 6 => CreateValues(values.Value1, values.Value2, values.Value3, values.Value4, values.Value5, + values.Value6), + 7 => CreateValues(values.Value1, values.Value2, values.Value3, values.Value4, values.Value5, + values.Value6, values.Value7), + 8 => CreateValues(values.Value1, values.Value2, values.Value3, values.Value4, values.Value5, + values.Value6, values.Value7, values.Value8), + 9 => CreateValues(values.Value1, values.Value2, values.Value3, values.Value4, values.Value5, + values.Value6, values.Value7, values.Value8, values.Value9), + 10 => CreateValues(values.Value1, values.Value2, values.Value3, values.Value4, values.Value5, + values.Value6, values.Value7, values.Value8, values.Value9, values.Value10), + 11 => CreateValues(values.Value1, values.Value2, values.Value3, values.Value4, values.Value5, + values.Value6, values.Value7, values.Value8, values.Value9, values.Value10, values.Value11), + 12 => CreateValues(values.Value1, values.Value2, values.Value3, values.Value4, values.Value5, values.Value6, values.Value7, values.Value8, values.Value9, values.Value10, values.Value11, - values.Value12 }), + values.Value12), _ => throw new ArgumentOutOfRangeException(nameof(count), count, null) }; } - public static IReadOnlyList ValuesListFrom(IEnumerable> rules) { IEnumerable policies = rules.Select(ValuesFrom); diff --git a/Casbin/Model/PolicyValues.cs b/Casbin/Model/PolicyValues.cs index 720bd46..fd4eea4 100644 --- a/Casbin/Model/PolicyValues.cs +++ b/Casbin/Model/PolicyValues.cs @@ -8,80 +8,356 @@ public record PolicyValues : IPolicyValues { protected string Text; - private List Values{ get; set; } = new(); - public static PolicyValues Empty { get; } = new(); + public virtual int Count => 0; + public virtual string this[int index] => throw new ArgumentOutOfRangeException(nameof(index)); + public virtual IEnumerator GetEnumerator() => new PolicyEnumerator(this); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public string ToText() => Text ??= ToText((IEnumerable)this); + public bool Equals(IPolicyValues other) => Equals(this, other); - public int Count; + internal static string ToText(T values) where T : IPolicyValues + => string.Join(PermConstants.PolicySeparatorString, values); - public bool IsReadOnly => false; + internal static string ToText(IEnumerable values) + => string.Join(PermConstants.PolicySeparatorString, values); - int ICollection.Count => Values.Count; + internal static bool Equals(T values, T other) where T : IPolicyValues + => values.Count == other.Count && values.ToText().Equals(other.ToText()); - string IList.this[int index] { get => Values[index]; set => new NotImplementedException(); } + internal static string ToStringValue(T value) => value as string ?? value.ToString(); +} - public string this[int index] => Values[index]; +public record PolicyValues(T1 Value1) : PolicyValues +{ + private string _stringValue1; - public virtual IEnumerator GetEnumerator() => new PolicyEnumerator(this); + internal PolicyValues(string text, T1 value1, string stringValue1) : this(value1) + { + _stringValue1 = stringValue1; + Text = text; + } - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public override int Count => 1; - public string ToText() => Text ??= ToText(this); + public override string this[int index] => index switch + { + 0 => _stringValue1 ??= ToStringValue(Value1), + _ => throw new ArgumentOutOfRangeException(nameof(index)) + }; - public bool Equals(IPolicyValues other) => Equals(this, other); + public override IEnumerator GetEnumerator() => new PolicyEnumerator>(this); +} - internal static string ToText(IEnumerable values) - => string.Join(PermConstants.PolicySeparatorString, values); +public record PolicyValues(T1 Value1, T2 Value2) : PolicyValues +{ + private string _stringValue1, _stringValue2; - internal static bool Equals(T values, T other) where T : IPolicyValues - => values.Count == other.Count && values.ToText().Equals(other.ToText()); + internal PolicyValues(string text, T1 value1, string stringValue1, T2 value2, string stringValue2) : this(value1, + value2) + { + _stringValue1 = stringValue1; + _stringValue2 = stringValue2; + Text = text; + } - internal static string ToStringValue(T value) => value as string ?? value.ToString(); + public override int Count => 2; - public int IndexOf(string item) => ((IList)Empty).IndexOf(item); + public override string this[int index] => index switch + { + 0 => _stringValue1 ??= ToStringValue(Value1), + 1 => _stringValue2 ??= ToStringValue(Value2), + _ => throw new ArgumentOutOfRangeException(nameof(index)) + }; - public void Insert(int index, string item) => ((IList)Empty).Insert(index, item); + public override IEnumerator GetEnumerator() => new PolicyEnumerator>(this); +} - public void RemoveAt(int index) => ((IList)Empty).RemoveAt(index); +public record PolicyValues(T1 Value1, T2 Value2, T3 Value3) : PolicyValues +{ + private string _stringValue1, _stringValue2, _stringValue3; - public void Add(string item) => Values.Add(item); + internal PolicyValues(string text, T1 value1, string stringValue1, T2 value2, string stringValue2, + T3 value3, string stringValue3) : this(value1, value2, value3) + { + _stringValue1 = stringValue1; + _stringValue2 = stringValue2; + _stringValue3 = stringValue3; + Text = text; + } - public void Clear() => Values.Clear(); + public override int Count => 3; - public bool Contains(string item) => Values.Contains(item); + public override string this[int index] => index switch + { + 0 => _stringValue1 ??= ToStringValue(Value1), + 1 => _stringValue2 ??= ToStringValue(Value2), + 2 => _stringValue3 ??= ToStringValue(Value3), + _ => throw new ArgumentOutOfRangeException(nameof(index)) + }; - public void CopyTo(string[] array, int arrayIndex) => Values.CopyTo(array, arrayIndex); + public override IEnumerator GetEnumerator() => new PolicyEnumerator>(this); +} - public bool Remove(string item) => Values.Remove(item); +public record PolicyValues(T1 Value1, T2 Value2, T3 Value3, T4 Value4) : PolicyValues +{ + private string _stringValue1, _stringValue2, _stringValue3, _stringValue4; - public PolicyValues(params object[] values) + internal PolicyValues(string text, T1 value1, string stringValue1, T2 value2, string stringValue2, + T3 value3, string stringValue3, T4 value4, string stringValue4) : this(value1, value2, value3, value4) { - foreach (var item in values) - { - Values.Add(item.ToString()); - } - Text = ToText(Values); + _stringValue1 = stringValue1; + _stringValue2 = stringValue2; + _stringValue3 = stringValue3; + _stringValue4 = stringValue4; + Text = text; } - public PolicyValues(string text, IList values) + public override int Count => 4; + + public override string this[int index] => index switch + { + 0 => _stringValue1 ??= ToStringValue(Value1), + 1 => _stringValue2 ??= ToStringValue(Value2), + 2 => _stringValue3 ??= ToStringValue(Value3), + 3 => _stringValue4 ??= ToStringValue(Value4), + _ => throw new ArgumentOutOfRangeException(nameof(index)) + }; + + public override IEnumerator GetEnumerator() => new PolicyEnumerator>(this); +} + +public record PolicyValues(T1 Value1, T2 Value2, T3 Value3, T4 Value4, T5 Value5) : PolicyValues +{ + private string _stringValue1, _stringValue2, _stringValue3, _stringValue4, _stringValue5; + + internal PolicyValues(string text, T1 value1, string stringValue1, T2 value2, string stringValue2, + T3 value3, string stringValue3, T4 value4, string stringValue4, T5 value5, string stringValue5) + : this(value1, value2, value3, value4, value5) + { + _stringValue1 = stringValue1; + _stringValue2 = stringValue2; + _stringValue3 = stringValue3; + _stringValue4 = stringValue4; + _stringValue5 = stringValue5; + Text = text; + } + + public override int Count => 5; + + public override string this[int index] => index switch + { + 0 => _stringValue1 ??= ToStringValue(Value1), + 1 => _stringValue2 ??= ToStringValue(Value2), + 2 => _stringValue3 ??= ToStringValue(Value3), + 3 => _stringValue4 ??= ToStringValue(Value4), + 4 => _stringValue5 ??= ToStringValue(Value5), + _ => throw new ArgumentOutOfRangeException(nameof(index)) + }; + + public override IEnumerator GetEnumerator() => new PolicyEnumerator>(this); +} + +public record PolicyValues + (T1 Value1, T2 Value2, T3 Value3, T4 Value4, T5 Value5, T6 Value6) : PolicyValues +{ + private string _stringValue1, _stringValue2, _stringValue3, _stringValue4, _stringValue5, _stringValue6; + + internal PolicyValues(string text, T1 value1, string stringValue1, T2 value2, string stringValue2, + T3 value3, string stringValue3, T4 value4, string stringValue4, T5 value5, string stringValue5, + T6 value6, string stringValue6) : this(value1, value2, value3, value4, value5, value6) { + _stringValue1 = stringValue1; + _stringValue2 = stringValue2; + _stringValue3 = stringValue3; + _stringValue4 = stringValue4; + _stringValue5 = stringValue5; + _stringValue6 = stringValue6; Text = text; - foreach (var item in values) - { - Values.Add(item.ToString()); - } - Count = Values.Count; } - public PolicyValues(string text, params object[] values) + public override int Count => 6; + + public override string this[int index] => index switch { + 0 => _stringValue1 ??= ToStringValue(Value1), + 1 => _stringValue2 ??= ToStringValue(Value2), + 2 => _stringValue3 ??= ToStringValue(Value3), + 3 => _stringValue4 ??= ToStringValue(Value4), + 4 => _stringValue5 ??= ToStringValue(Value5), + 5 => _stringValue6 ??= ToStringValue(Value6), + _ => throw new ArgumentOutOfRangeException(nameof(index)) + }; + + public override IEnumerator GetEnumerator() => + new PolicyEnumerator>(this); +} + +public record PolicyValues(T1 Value1, T2 Value2, T3 Value3, T4 Value4, T5 Value5, T6 Value6, + T7 Value7) : PolicyValues +{ + private string _stringValue1, + _stringValue2, + _stringValue3, + _stringValue4, + _stringValue5, + _stringValue6, + _stringValue7; + + internal PolicyValues(string text, T1 value1, string stringValue1, T2 value2, string stringValue2, + T3 value3, string stringValue3, T4 value4, string stringValue4, T5 value5, string stringValue5, + T6 value6, string stringValue6, T7 value7, string stringValue7) : this(value1, value2, value3, value4, value5, + value6, value7) + { + _stringValue1 = stringValue1; + _stringValue2 = stringValue2; + _stringValue3 = stringValue3; + _stringValue4 = stringValue4; + _stringValue5 = stringValue5; + _stringValue6 = stringValue6; + _stringValue7 = stringValue7; Text = text; - foreach (var item in values) - { - Values.Add(item.ToString()); - } - Count = Values.Count; } + + public override int Count => 7; + + public override string this[int index] => index switch + { + 0 => _stringValue1 ??= ToStringValue(Value1), + 1 => _stringValue2 ??= ToStringValue(Value2), + 2 => _stringValue3 ??= ToStringValue(Value3), + 3 => _stringValue4 ??= ToStringValue(Value4), + 4 => _stringValue5 ??= ToStringValue(Value5), + 5 => _stringValue6 ??= ToStringValue(Value6), + 6 => _stringValue7 ??= ToStringValue(Value7), + _ => throw new ArgumentOutOfRangeException(nameof(index)) + }; + + public override IEnumerator GetEnumerator() => + new PolicyEnumerator>(this); +} + +public record PolicyValues(T1 Value1, T2 Value2, T3 Value3, T4 Value4, T5 Value5, + T6 Value6, + T7 Value7, T8 Value8) : PolicyValues +{ + public override int Count => 8; + + public override string this[int index] => index switch + { + 0 => ToStringValue(Value1), + 1 => ToStringValue(Value2), + 2 => ToStringValue(Value3), + 3 => ToStringValue(Value4), + 4 => ToStringValue(Value5), + 5 => ToStringValue(Value6), + 6 => ToStringValue(Value7), + 7 => ToStringValue(Value8), + _ => throw new ArgumentOutOfRangeException(nameof(index)) + }; + + public override IEnumerator GetEnumerator() => + new PolicyEnumerator>(this); +} + +public record PolicyValues(T1 Value1, T2 Value2, T3 Value3, T4 Value4, T5 Value5, + T6 Value6, T7 Value7, T8 Value8, T9 Value9) : PolicyValues +{ + public override int Count => 9; + + public override string this[int index] => index switch + { + 0 => ToStringValue(Value1), + 1 => ToStringValue(Value2), + 2 => ToStringValue(Value3), + 3 => ToStringValue(Value4), + 4 => ToStringValue(Value5), + 5 => ToStringValue(Value6), + 6 => ToStringValue(Value7), + 7 => ToStringValue(Value8), + 8 => ToStringValue(Value9), + _ => throw new ArgumentOutOfRangeException(nameof(index)) + }; + + public override IEnumerator GetEnumerator() => + new PolicyEnumerator>(this); +} + +public record PolicyValues(T1 Value1, T2 Value2, T3 Value3, T4 Value4, + T5 Value5, + T6 Value6, T7 Value7, T8 Value8, T9 Value9, T10 Value10) : PolicyValues +{ + public override int Count => 10; + + public override string this[int index] => index switch + { + 0 => ToStringValue(Value1), + 1 => ToStringValue(Value2), + 2 => ToStringValue(Value3), + 3 => ToStringValue(Value4), + 4 => ToStringValue(Value5), + 5 => ToStringValue(Value6), + 6 => ToStringValue(Value7), + 7 => ToStringValue(Value8), + 8 => ToStringValue(Value9), + 9 => ToStringValue(Value10), + _ => throw new ArgumentOutOfRangeException(nameof(index)) + }; + + public override IEnumerator GetEnumerator() => + new PolicyEnumerator>(this); +} + +public record PolicyValues(T1 Value1, T2 Value2, T3 Value3, T4 Value4, + T5 Value5, T6 Value6, T7 Value7, T8 Value8, T9 Value9, T10 Value10, T11 Value11) : PolicyValues +{ + public override int Count => 11; + + public override string this[int index] => index switch + { + 0 => ToStringValue(Value1), + 1 => ToStringValue(Value2), + 2 => ToStringValue(Value3), + 3 => ToStringValue(Value4), + 4 => ToStringValue(Value5), + 5 => ToStringValue(Value6), + 6 => ToStringValue(Value7), + 7 => ToStringValue(Value8), + 8 => ToStringValue(Value9), + 9 => ToStringValue(Value10), + 10 => ToStringValue(Value11), + _ => throw new ArgumentOutOfRangeException(nameof(index)) + }; + + public override IEnumerator GetEnumerator() => + new PolicyEnumerator>(this); +} + +public record PolicyValues(T1 Value1, T2 Value2, T3 Value3, + T4 Value4, + T5 Value5, T6 Value6, T7 Value7, T8 Value8, T9 Value9, T10 Value10, T11 Value11, T12 Value12) : PolicyValues +{ + public override int Count => 12; + + public override string this[int index] => index switch + { + 0 => ToStringValue(Value1), + 1 => ToStringValue(Value2), + 2 => ToStringValue(Value3), + 3 => ToStringValue(Value4), + 4 => ToStringValue(Value5), + 5 => ToStringValue(Value6), + 6 => ToStringValue(Value7), + 7 => ToStringValue(Value8), + 8 => ToStringValue(Value9), + 9 => ToStringValue(Value10), + 10 => ToStringValue(Value11), + 11 => ToStringValue(Value12), + _ => throw new ArgumentOutOfRangeException(nameof(index)) + }; + + public override IEnumerator GetEnumerator() => + new PolicyEnumerator>(this); } internal record DummyPolicyValues(string Value1 = "", string Value2 = "", string Value3 = "", @@ -90,9 +366,9 @@ internal record DummyPolicyValues(string Value1 = "", string Value2 = "", string string Value10 = "", string Value11 = "", string Value12 = "") : PolicyValues { public static new readonly DummyPolicyValues Empty = new(); - public new int Count => 12; + public override int Count => 12; - public new string this[int index] => index switch + public override string this[int index] => index switch { 0 => Value1, 1 => Value2, @@ -115,18 +391,16 @@ public override IEnumerator GetEnumerator() => internal record StringListPolicyValues : PolicyValues { - private readonly IList _values; - - public StringListPolicyValues(IList values) => _values = values; - - public new int Count => _values.Count; + private readonly IReadOnlyList _values; - public new string this[int index] => _values[index]; + public StringListPolicyValues(IReadOnlyList values) => _values = values; + public override int Count => _values.Count; + public override string this[int index] => _values[index]; public override IEnumerator GetEnumerator() => _values.GetEnumerator(); } - internal struct PolicyEnumerator : IEnumerator where T : IPolicyValues +internal struct PolicyEnumerator : IEnumerator where T : IPolicyValues { public PolicyEnumerator(T value) { From f3d3dcdd6e5094a24f5e7bcaba8116527a443ff4 Mon Sep 17 00:00:00 2001 From: sagilio Date: Sun, 21 Apr 2024 23:01:34 +0800 Subject: [PATCH 3/3] feat: compatible with unexpected policy Signed-off-by: sagilio --- .../Enforcer/ManagementEnforcerExtension.cs | 14 + .../Model/RequestValuesExtension.cs | 18 + .../Extensions/RequestValuesExtension.cs | 18 - ...pportCountTests.cs => SupportCountTest.cs} | 54 +- .../ModelTests/ManagementApiTest.cs | 35 + Casbin.UnitTests/Util/TestUtil.cs | 4 +- .../Model/IReadOnlyPolicyStore.cs | 6 + .../Enforcer/ManagementEnforcerExtension.cs | 964 +++++++++--------- Casbin/Extensions/ListExtension.cs | 21 + Casbin/Model/DefaultPolicyStore.Node.cs | 14 +- Casbin/Model/DefaultPolicyStore.cs | 18 +- Casbin/Model/Policy.cs | 256 +++-- Casbin/Model/PolicyValues.cs | 114 +-- Casbin/Persist/Adapter/File/FileAdapter.cs | 32 +- .../Adapter/Stream/StreamFilteredAdapter.cs | 6 +- 15 files changed, 843 insertions(+), 731 deletions(-) create mode 100644 Casbin.UnitTests/Extensions/Enforcer/ManagementEnforcerExtension.cs create mode 100644 Casbin.UnitTests/Extensions/Model/RequestValuesExtension.cs delete mode 100644 Casbin.UnitTests/Extensions/RequestValuesExtension.cs rename Casbin.UnitTests/GenericTests/{SupportCountTests.cs => SupportCountTest.cs} (69%) create mode 100644 Casbin/Extensions/ListExtension.cs diff --git a/Casbin.UnitTests/Extensions/Enforcer/ManagementEnforcerExtension.cs b/Casbin.UnitTests/Extensions/Enforcer/ManagementEnforcerExtension.cs new file mode 100644 index 0000000..418d54e --- /dev/null +++ b/Casbin.UnitTests/Extensions/Enforcer/ManagementEnforcerExtension.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Casbin.Model; +using Xunit; + +namespace Casbin.UnitTests.Extensions; + +internal static class ManagementEnforcerExtension +{ + internal static void TestGetPolicy(this IEnforcer e, IReadOnlyList exceptedValues) + { + IEnumerable> actualValues = e.GetPolicy(); + Assert.True(exceptedValues.DeepEquals(actualValues)); + } +} diff --git a/Casbin.UnitTests/Extensions/Model/RequestValuesExtension.cs b/Casbin.UnitTests/Extensions/Model/RequestValuesExtension.cs new file mode 100644 index 0000000..0e6f96f --- /dev/null +++ b/Casbin.UnitTests/Extensions/Model/RequestValuesExtension.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using Casbin.Model; + +namespace Casbin.UnitTests.Extensions; + +internal static class RequestValuesExtension +{ + internal static IEnumerable ToEnumerable(this IRequestValues values) + { + string[] res = new string[values.Count]; + for (int i = 0; i < values.Count; i++) + { + res[i] = values[i]; + } + + return res; + } +} diff --git a/Casbin.UnitTests/Extensions/RequestValuesExtension.cs b/Casbin.UnitTests/Extensions/RequestValuesExtension.cs deleted file mode 100644 index df91025..0000000 --- a/Casbin.UnitTests/Extensions/RequestValuesExtension.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Collections.Generic; -using Casbin.Model; - -namespace Casbin.UnitTests.Extensions -{ - public static class RequestValuesExtension - { - public static IEnumerable ToEnumerable(this IRequestValues values) - { - string[] res = new string[values.Count]; - for (int i = 0; i < values.Count; i++) - { - res[i] = values[i]; - } - return res; - } - } -} diff --git a/Casbin.UnitTests/GenericTests/SupportCountTests.cs b/Casbin.UnitTests/GenericTests/SupportCountTest.cs similarity index 69% rename from Casbin.UnitTests/GenericTests/SupportCountTests.cs rename to Casbin.UnitTests/GenericTests/SupportCountTest.cs index bf5b16a..7b182f3 100644 --- a/Casbin.UnitTests/GenericTests/SupportCountTests.cs +++ b/Casbin.UnitTests/GenericTests/SupportCountTest.cs @@ -7,11 +7,11 @@ namespace Casbin.UnitTests.GenericTests; [Collection("Model collection")] -public class SupportCountTests +public class SupportCountTest { private readonly TestModelFixture _testModelFixture; - public SupportCountTests(TestModelFixture testModelFixture) => _testModelFixture = testModelFixture; + public SupportCountTest(TestModelFixture testModelFixture) => _testModelFixture = testModelFixture; [Fact] public void TestSupportCount() @@ -59,60 +59,74 @@ private static void TestEnforce(IEnforcer enforcer, EnforceContext context, int case 5: Assert.True(enforcer.Enforce(context, "value1", "value2", "value3", "value4", "value5")); - Assert.True(enforcer.Enforce(context, new[] { "value1", "value2", "value3", - "value4", "value5" })); + Assert.True(enforcer.Enforce(context, new[] { "value1", "value2", "value3", "value4", "value5" })); break; case 6: Assert.True(enforcer.Enforce(context, "value1", "value2", "value3", "value4", "value5", "value6")); - Assert.True(enforcer.Enforce(context, new[] { "value1", "value2", "value3", - "value4", "value5", "value6" })); + Assert.True(enforcer.Enforce(context, + new[] { "value1", "value2", "value3", "value4", "value5", "value6" })); break; case 7: Assert.True(enforcer.Enforce(context, "value1", "value2", "value3", "value4", "value5", "value6", "value7")); - Assert.True(enforcer.Enforce(context, new[] { "value1", "value2", "value3", - "value4", "value5", "value6", "value7" })); + Assert.True(enforcer.Enforce(context, + new[] { "value1", "value2", "value3", "value4", "value5", "value6", "value7" })); break; case 8: Assert.True(enforcer.Enforce(context, "value1", "value2", "value3", "value4", "value5", "value6", "value7", "value8")); - Assert.True(enforcer.Enforce(context, new[] { "value1", "value2", "value3", - "value4", "value5", "value6", "value7", "value8" })); + Assert.True(enforcer.Enforce(context, + new[] { "value1", "value2", "value3", "value4", "value5", "value6", "value7", "value8" })); break; case 9: Assert.True(enforcer.Enforce(context, "value1", "value2", "value3", "value4", "value5", "value6", "value7", "value8", "value9")); - Assert.True(enforcer.Enforce(context, new[] { "value1", "value2", "value3", - "value4", "value5", "value6", "value7", "value8", "value9" })); + Assert.True(enforcer.Enforce(context, + new[] + { + "value1", "value2", "value3", "value4", "value5", "value6", "value7", "value8", "value9" + })); break; case 10: Assert.True(enforcer.Enforce(context, "value1", "value2", "value3", "value4", "value5", "value6", "value7", "value8", "value9", "value10")); - Assert.True(enforcer.Enforce(context, new[] { "value1", "value2", "value3", - "value4", "value5", "value6", "value7", "value8", "value9", "value10" })); + Assert.True(enforcer.Enforce(context, + new[] + { + "value1", "value2", "value3", "value4", "value5", "value6", "value7", "value8", "value9", + "value10" + })); break; case 11: Assert.True(enforcer.Enforce(context, "value1", "value2", "value3", "value4", "value5", "value6", "value7", "value8", "value9", "value10", "value11")); - Assert.True(enforcer.Enforce(context, new[] { "value1", "value2", "value3", - "value4", "value5", "value6", "value7", "value8", "value9", "value10", "value11" })); + Assert.True(enforcer.Enforce(context, + new[] + { + "value1", "value2", "value3", "value4", "value5", "value6", "value7", "value8", "value9", + "value10", "value11" + })); break; case 12: Assert.True(enforcer.Enforce(context, "value1", "value2", "value3", "value4", "value5", "value6", "value7", "value8", "value9", "value10", "value11", "value12")); - Assert.True(enforcer.Enforce(context, new[] { "value1", "value2", "value3", - "value4", "value5", "value6", "value7", "value8", "value9", "value10", "value11", "value12" })); + Assert.True(enforcer.Enforce(context, + new[] + { + "value1", "value2", "value3", "value4", "value5", "value6", "value7", "value8", "value9", + "value10", "value11", "value12" + })); break; case 13: Assert.True(enforcer.Enforce(context, Request.CreateValues("value1", "value2", "value3", "value4", "value5", "value6", "value7", "value8", "value9", "value10", "value11", "value12", "value13"))); - Assert.True(enforcer.Enforce(context, new[] { "value1", "value2", "value3", - "value4", "value5", "value6", "value7", "value8", "value9", "value10", "value11", "value12", "value13" })); + Assert.True(enforcer.Enforce(context, "value1", "value2", "value3", "value4", "value5", "value6", + "value7", "value8", "value9", "value10", "value11", "value12", "value13")); break; default: throw new ArgumentOutOfRangeException(nameof(requestCount)); diff --git a/Casbin.UnitTests/ModelTests/ManagementApiTest.cs b/Casbin.UnitTests/ModelTests/ManagementApiTest.cs index f160484..5a5dc86 100644 --- a/Casbin.UnitTests/ModelTests/ManagementApiTest.cs +++ b/Casbin.UnitTests/ModelTests/ManagementApiTest.cs @@ -1,5 +1,7 @@ using System.Collections.Generic; using System.Threading.Tasks; +using Casbin.Model; +using Casbin.UnitTests.Extensions; using Casbin.UnitTests.Fixtures; using Xunit; using static Casbin.UnitTests.Util.TestUtil; @@ -551,4 +553,37 @@ public async Task TestModifyGroupingPolicyAsync() TestGetRoles(e, "admin", AsList("data5_admin")); TestGetRoles(e, "eve", AsList("admin_groups")); } + + [Fact] + public void TestModifySpecialPolicy() + { + Enforcer e = new(TestModelFixture.GetNewTestModel(_testModelFixture._rbacModelText)); + + e.AddPolicy("alice", "data1"); + e.AddPolicy("alice", "data1", "read"); + e.AddPolicy("alice", "data1", "read", "dump1"); + + e.TestGetPolicy(Policy.ValuesListFrom(new[] + { + Policy.CreateValues("alice", "data1", ""), Policy.CreateValues("alice", "data1", "read"), + } + )); + } + + [Fact] + public async Task TestModifySpecialPolicyAsync() + { + Enforcer e = new(_testModelFixture.GetNewRbacTestModel()); + e.ClearPolicy(); + + await e.AddPolicyAsync("alice", "data1"); + await e.AddPolicyAsync("alice", "data1", "read"); + await e.AddPolicyAsync("alice", "data1", "read", "dump1"); + + e.TestGetPolicy(Policy.ValuesListFrom(new[] + { + Policy.CreateValues("alice", "data1", ""), Policy.CreateValues("alice", "data1", "read"), + } + )); + } } diff --git a/Casbin.UnitTests/Util/TestUtil.cs b/Casbin.UnitTests/Util/TestUtil.cs index 5b014de..1d6f191 100644 --- a/Casbin.UnitTests/Util/TestUtil.cs +++ b/Casbin.UnitTests/Util/TestUtil.cs @@ -1,14 +1,14 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Casbin.Rbac; using Casbin.Model; +using Casbin.Rbac; using Casbin.Util; using Xunit; namespace Casbin.UnitTests.Util; -public static class TestUtil +internal static class TestUtil { internal static List AsList(params T[] values) => values.ToList(); diff --git a/Casbin/Abstractions/Model/IReadOnlyPolicyStore.cs b/Casbin/Abstractions/Model/IReadOnlyPolicyStore.cs index 41b1fa4..9070be9 100644 --- a/Casbin/Abstractions/Model/IReadOnlyPolicyStore.cs +++ b/Casbin/Abstractions/Model/IReadOnlyPolicyStore.cs @@ -8,6 +8,12 @@ public interface IReadOnlyPolicyStore public bool ContainsNode(string section, string policyType); + public int GetRequiredValuesCount(string section, string policyType); + + public bool ValidatePolicy(string section, string policyType, IPolicyValues values); + + public bool ValidatePolicies(string section, string policyType, IReadOnlyList valuesList); + public PolicyScanner Scan(string section, string policyType); public IEnumerable GetPolicy(string section, string policyType); diff --git a/Casbin/Extensions/Enforcer/ManagementEnforcerExtension.cs b/Casbin/Extensions/Enforcer/ManagementEnforcerExtension.cs index 18c1713..502d819 100644 --- a/Casbin/Extensions/Enforcer/ManagementEnforcerExtension.cs +++ b/Casbin/Extensions/Enforcer/ManagementEnforcerExtension.cs @@ -39,10 +39,8 @@ public static void AddFunction(this IEnforcer enforcer, string name, Func - public static IEnumerable GetAllSubjects(this IEnforcer enforcer) - { - return GetAllNamedSubjects(enforcer, PermConstants.Section.PolicySection); - } + public static IEnumerable GetAllSubjects(this IEnforcer enforcer) => + GetAllNamedSubjects(enforcer, PermConstants.Section.PolicySection); /// /// GetAllNamedSubjects gets the list of subjects that show up in the current named policy. @@ -67,10 +65,8 @@ public static IEnumerable GetAllNamedSubjects(this IEnforcer enforcer, s /// 1-index elements of "p" policy rules.So make sure your object /// is the 1-index element, like (sub, obj, act). /// Duplicates are removed. - public static IEnumerable GetAllObjects(this IEnforcer enforcer) - { - return GetAllNamedObjects(enforcer, PermConstants.Section.PolicySection); - } + public static IEnumerable GetAllObjects(this IEnforcer enforcer) => + GetAllNamedObjects(enforcer, PermConstants.Section.PolicySection); /// /// Gets the list of objects that show up in the current named policy. @@ -94,10 +90,8 @@ public static IEnumerable GetAllNamedObjects(this IEnforcer enforcer, st /// the 2-index elements of "p" policy rules.So make sure your action /// is the 2-index element, like (sub, obj, act). /// Duplicates are removed. - public static IEnumerable GetAllActions(this IEnforcer enforcer) - { - return GetAllNamedActions(enforcer, PermConstants.Section.PolicySection); - } + public static IEnumerable GetAllActions(this IEnforcer enforcer) => + GetAllNamedActions(enforcer, PermConstants.Section.PolicySection); /// /// Gets the list of actions that show up in the current named policy. @@ -121,10 +115,8 @@ public static IEnumerable GetAllNamedActions(this IEnforcer enforcer, st /// Gets all the authorization rules in the policy. /// /// all the "p" policy rules. - public static IEnumerable> GetPolicy(this IEnforcer enforcer) - { - return GetNamedPolicy(enforcer, PermConstants.Section.PolicySection); - } + public static IEnumerable> GetPolicy(this IEnforcer enforcer) => + enforcer.GetNamedPolicy(PermConstants.Section.PolicySection); /// /// Gets all the authorization rules in the named policy. @@ -143,10 +135,8 @@ public static IEnumerable> GetNamedPolicy(this IEnforcer enf /// The field values to be matched, value "" means not to match this field. /// The filtered "p" policy rules. public static IEnumerable> GetFilteredPolicy(this IEnforcer enforcer, int fieldIndex, - params string[] fieldValues) - { - return GetFilteredNamedPolicy(enforcer, PermConstants.Section.PolicySection, fieldIndex, fieldValues); - } + params string[] fieldValues) => + enforcer.GetFilteredNamedPolicy(PermConstants.Section.PolicySection, fieldIndex, fieldValues); /// /// Gets all the authorization rules in the named policy, field filters can be specified. @@ -157,8 +147,7 @@ public static IEnumerable> GetFilteredPolicy(this IEnforcer /// The field values to be matched, value "" means not to match this field. /// The filtered "p" policy rules of the specified policyType. public static IEnumerable> GetFilteredNamedPolicy(this IEnforcer enforcer, - string policyType, - int fieldIndex, params string[] fieldValues) => + string policyType, int fieldIndex, params string[] fieldValues) => enforcer.InternalGetFilteredPolicy(PermConstants.Section.PolicySection, policyType, fieldIndex, Policy.ValuesFrom(fieldValues)); @@ -170,44 +159,44 @@ public static IEnumerable> GetFilteredNamedPolicy(this IEnfo /// Determines whether an authorization rule exists. /// /// - /// The "p" policy rule, policyType "p" is implicitly used. + /// The "p" policy rule, policyType "p" is implicitly used. /// Whether the rule exists. - public static bool HasPolicy(this IEnforcer enforcer, IEnumerable paramList) - { - return HasNamedPolicy(enforcer, PermConstants.DefaultPolicyType, paramList); - } + public static bool HasPolicy(this IEnforcer enforcer, IEnumerable values) => + enforcer.HasPolicy(values as string[] ?? values.ToArray()); /// /// Determines whether an authorization rule exists. /// /// - /// The "p" policy rule, policyType "p" is implicitly used. + /// The "p" policy rule, policyType "p" is implicitly used. /// Whether the rule exists. - public static bool HasPolicy(this IEnforcer enforcer, params string[] parameters) - { - return HasPolicy(enforcer, parameters as IEnumerable); - } + public static bool HasPolicy(this IEnforcer enforcer, params string[] values) => + enforcer.HasNamedPolicy(PermConstants.DefaultPolicyType, values); /// /// Determines whether a named authorization rule exists. /// /// /// The policy type, can be "p", "p2", "p3", .. - /// The "p" policy rule. + /// The "p" policy rule. /// Whether the rule exists. - public static bool HasNamedPolicy(this IEnforcer enforcer, string policyType, IEnumerable paramList) => - enforcer.Model.PolicyStoreHolder.PolicyStore.HasPolicy(PermConstants.Section.PolicySection, policyType, - Policy.ValuesFrom(paramList)); + public static bool HasNamedPolicy(this IEnforcer enforcer, string policyType, IEnumerable values) => + enforcer.HasNamedPolicy(policyType, values as string[] ?? values.ToArray()); /// /// Determines whether a named authorization rule exists. /// /// /// The policy type, can be "p", "p2", "p3", .. - /// The "p" policy rule. + /// The "p" policy rule. /// Whether the rule exists. - public static bool HasNamedPolicy(this IEnforcer enforcer, string policyType, params string[] parameters) => - HasNamedPolicy(enforcer, policyType, parameters as IEnumerable); + public static bool HasNamedPolicy(this IEnforcer enforcer, string policyType, params string[] values) + { + IPolicyStore policyStore = enforcer.Model.PolicyStoreHolder.PolicyStore; + int requiredCount = policyStore.GetRequiredValuesCount(PermConstants.Section.PolicySection, policyType); + return policyStore.HasPolicy(PermConstants.Section.PolicySection, policyType, + Policy.ValuesFrom(values, requiredCount)); + } #endregion @@ -221,11 +210,8 @@ public static bool HasNamedPolicy(this IEnforcer enforcer, string policyType, pa /// /// The "p" policy rule, policyType "p" is implicitly used. /// Succeeds or not. - public static bool AddPolicy(this IEnforcer enforcer, IEnumerable values) - { - string[] valueArray = values as string[] ?? values.ToArray(); - return enforcer.AddPolicy(valueArray); - } + public static bool AddPolicy(this IEnforcer enforcer, IEnumerable values) => + enforcer.AddPolicy(values as string[] ?? values.ToArray()); /// /// Adds an authorization rule to the current policy. If the rule @@ -244,12 +230,10 @@ public static bool AddPolicy(this IEnforcer enforcer, params string[] values) => /// Otherwise the function returns true by adding the new rule. /// /// - /// The "p" policy rule, policyType "p" is implicitly used. + /// The "p" policy rule, policyType "p" is implicitly used. /// Succeeds or not. - public static Task AddPolicyAsync(this IEnforcer enforcer, params string[] parameters) - { - return AddPolicyAsync(enforcer, parameters as IEnumerable); - } + public static Task AddPolicyAsync(this IEnforcer enforcer, IEnumerable values) => + AddPolicyAsync(enforcer, values as string[] ?? values.ToArray()); /// /// Adds an authorization rule to the current policy. If the rule @@ -257,12 +241,10 @@ public static Task AddPolicyAsync(this IEnforcer enforcer, params string[] /// Otherwise the function returns true by adding the new rule. /// /// - /// The "p" policy rule, policyType "p" is implicitly used. + /// The "p" policy rule, policyType "p" is implicitly used. /// Succeeds or not. - public static Task AddPolicyAsync(this IEnforcer enforcer, IEnumerable parameters) - { - return AddNamedPolicyAsync(enforcer, PermConstants.DefaultPolicyType, parameters); - } + public static Task AddPolicyAsync(this IEnforcer enforcer, params string[] values) => + enforcer.AddNamedPolicyAsync(PermConstants.DefaultPolicyType, values); /// /// Adds an authorization rule to the current named policy.If the @@ -273,11 +255,8 @@ public static Task AddPolicyAsync(this IEnforcer enforcer, IEnumerableThe policy type, can be "p", "p2", "p3", .. /// The "p" policy rule. /// Succeeds or not. - public static bool AddNamedPolicy(this IEnforcer enforcer, string policyType, IEnumerable values) - { - string[] valueArray = values as string[] ?? values.ToArray(); - return enforcer.AddNamedPolicy(policyType, valueArray); - } + public static bool AddNamedPolicy(this IEnforcer enforcer, string policyType, IEnumerable values) => + enforcer.AddNamedPolicy(policyType, values as string[] ?? values.ToArray()); /// /// Adds an authorization rule to the current named policy.If the @@ -288,35 +267,43 @@ public static bool AddNamedPolicy(this IEnforcer enforcer, string policyType, IE /// The policy type, can be "p", "p2", "p3", .. /// The "p" policy rule. /// Succeeds or not. - public static bool AddNamedPolicy(this IEnforcer enforcer, string policyType, params string[] values) => - enforcer.InternalAddPolicy(PermConstants.Section.PolicySection, policyType, Policy.ValuesFrom(values)); - + public static bool AddNamedPolicy(this IEnforcer enforcer, string policyType, params string[] values) + { + IPolicyStore policyStore = enforcer.Model.PolicyStoreHolder.PolicyStore; + int requiredCount = policyStore.GetRequiredValuesCount(PermConstants.Section.PolicySection, policyType); + return enforcer.InternalAddPolicy(PermConstants.Section.PolicySection, policyType, + Policy.ValuesFrom(values, requiredCount)); + } /// - /// Adds an authorization rule to the current named policy.If the - /// rule already exists, the function returns false and the rule will not be added. - /// Otherwise the function returns true by adding the new rule. + /// Adds an authorization rule to the current named policy.If the + /// rule already exists, the function returns false and the rule will not be added. + /// Otherwise the function returns true by adding the new rule. /// /// /// The policy type, can be "p", "p2", "p3", .. - /// The "p" policy rule. + /// The "p" policy rule. /// Succeeds or not. public static Task AddNamedPolicyAsync(this IEnforcer enforcer, string policyType, - params string[] parameters) => AddNamedPolicyAsync(enforcer, policyType, parameters as IEnumerable); + IEnumerable values) => + enforcer.AddNamedPolicyAsync(policyType, values as string[] ?? values.ToArray()); /// - /// Adds an authorization rule to the current named policy.If the - /// rule already exists, the function returns false and the rule will not be added. - /// Otherwise the function returns true by adding the new rule. + /// Adds an authorization rule to the current named policy.If the + /// rule already exists, the function returns false and the rule will not be added. + /// Otherwise the function returns true by adding the new rule. /// /// /// The policy type, can be "p", "p2", "p3", .. - /// The "p" policy rule. + /// The "p" policy rule. /// Succeeds or not. - public static Task AddNamedPolicyAsync(this IEnforcer enforcer, string policyType, - IEnumerable parameters) => - enforcer.InternalAddPolicyAsync(PermConstants.Section.PolicySection, policyType, - Policy.ValuesFrom(parameters)); + public static Task AddNamedPolicyAsync(this IEnforcer enforcer, string policyType, params string[] values) + { + IPolicyStore policyStore = enforcer.Model.PolicyStoreHolder.PolicyStore; + int requiredCount = policyStore.GetRequiredValuesCount(PermConstants.Section.PolicySection, policyType); + return enforcer.InternalAddPolicyAsync(PermConstants.Section.PolicySection, policyType, + Policy.ValuesFrom(values, requiredCount)); + } /// /// Adds authorization rules to the current policy. If the rule @@ -324,12 +311,10 @@ public static Task AddNamedPolicyAsync(this IEnforcer enforcer, string pol /// Otherwise the function returns true by adding the new rule. /// /// - /// The "p" policy rule, policyType "p" is implicitly used. + /// The "p" policy rule, policyType "p" is implicitly used. /// Succeeds or not. - public static bool AddPolicies(this IEnforcer enforcer, IEnumerable> rules) - { - return AddNamedPolicies(enforcer, PermConstants.DefaultPolicyType, rules); - } + public static bool AddPolicies(this IEnforcer enforcer, IEnumerable> values) => + AddNamedPolicies(enforcer, PermConstants.DefaultPolicyType, values); /// /// Adds authorization rules to the current policy. If the rule @@ -337,12 +322,10 @@ public static bool AddPolicies(this IEnforcer enforcer, IEnumerable /// - /// The "p" policy rule, policyType "p" is implicitly used. + /// The "p" policy rule, policyType "p" is implicitly used. /// Succeeds or not. - public static Task AddPoliciesAsync(this IEnforcer enforcer, IEnumerable> rules) - { - return AddNamedPoliciesAsync(enforcer, PermConstants.DefaultPolicyType, rules); - } + public static Task AddPoliciesAsync(this IEnforcer enforcer, IEnumerable> values) => + AddNamedPoliciesAsync(enforcer, PermConstants.DefaultPolicyType, values); /// /// Adds authorization rules to the current named policy.If the @@ -351,12 +334,16 @@ public static Task AddPoliciesAsync(this IEnforcer enforcer, IEnumerable /// /// The policy type, can be "p", "p2", "p3", .. - /// The "p" policy rule. + /// The "p" policy rule. /// Succeeds or not. public static bool AddNamedPolicies(this IEnforcer enforcer, string policyType, - IEnumerable> rules) => - enforcer.InternalAddPolicies(PermConstants.Section.PolicySection, policyType, - Policy.ValuesListFrom(rules)); + IEnumerable> valuesList) + { + IPolicyStore policyStore = enforcer.Model.PolicyStoreHolder.PolicyStore; + int requiredCount = policyStore.GetRequiredValuesCount(PermConstants.Section.PolicySection, policyType); + return enforcer.InternalAddPolicies(PermConstants.Section.PolicySection, policyType, + Policy.ValuesListFrom(valuesList, requiredCount)); + } /// /// Adds authorization rules to the current named policy.If the @@ -365,12 +352,16 @@ public static bool AddNamedPolicies(this IEnforcer enforcer, string policyType, /// /// /// The policy type, can be "p", "p2", "p3", .. - /// The "p" policy rule. + /// The "p" policy rule. /// Succeeds or not. public static Task AddNamedPoliciesAsync(this IEnforcer enforcer, string policyType, - IEnumerable> rules) => - enforcer.InternalAddPoliciesAsync(PermConstants.Section.PolicySection, policyType, - Policy.ValuesListFrom(rules)); + IEnumerable> valuesList) + { + IPolicyStore policyStore = enforcer.Model.PolicyStoreHolder.PolicyStore; + int requiredCount = policyStore.GetRequiredValuesCount(PermConstants.Section.PolicySection, policyType); + return enforcer.InternalAddPoliciesAsync(PermConstants.Section.PolicySection, policyType, + Policy.ValuesListFrom(valuesList, requiredCount)); + } #endregion @@ -380,144 +371,160 @@ public static Task AddNamedPoliciesAsync(this IEnforcer enforcer, string p /// Updates an authorization rule to the current policy. /// /// - /// The "p" policy rule to be replaced, policyType "p" is implicitly used. - /// The "p" policy rule to replace the old one, policyType "p" is implicitly used. + /// The "p" policy rule to be replaced, policyType "p" is implicitly used. + /// The "p" policy rule to replace the old one, policyType "p" is implicitly used. /// Succeeds or not. - public static bool UpdatePolicy(this IEnforcer enforcer, IEnumerable oldParameters, - params string[] newParameters) => - UpdatePolicy(enforcer, oldParameters, newParameters as IEnumerable); + public static bool UpdatePolicy(this IEnforcer enforcer, IEnumerable oldValues, + IEnumerable newValues) => + enforcer.UpdatePolicy(oldValues, newValues as string[] ?? newValues.ToArray()); /// /// Updates an authorization rule to the current policy. /// /// - /// The "p" policy rule to be replaced, policyType "p" is implicitly used. - /// The "p" policy rule to replace the old one, policyType "p" is implicitly used. + /// The "p" policy rule to be replaced, policyType "p" is implicitly used. + /// The "p" policy rule to replace the old one, policyType "p" is implicitly used. /// Succeeds or not. - public static Task UpdatePolicyAsync(this IEnforcer enforcer, IEnumerable oldParameters, - params string[] newParameters) => - UpdatePolicyAsync(enforcer, oldParameters, newParameters as IEnumerable); + public static bool UpdatePolicy(this IEnforcer enforcer, IEnumerable oldValues, + params string[] newValues) => + enforcer.UpdateNamedPolicy(PermConstants.DefaultPolicyType, oldValues, newValues); /// /// Updates an authorization rule to the current policy. /// /// - /// The "p" policy rule to be replaced, policyType "p" is implicitly used. - /// The "p" policy rule to replace the old one, policyType "p" is implicitly used. + /// The "p" policy rule to be replaced, policyType "p" is implicitly used. + /// The "p" policy rule to replace the old one, policyType "p" is implicitly used. /// Succeeds or not. - public static bool UpdatePolicy(this IEnforcer enforcer, IEnumerable oldParameters, - IEnumerable newParameters) => - UpdateNamedPolicy(enforcer, PermConstants.DefaultPolicyType, oldParameters, newParameters); + public static Task UpdatePolicyAsync(this IEnforcer enforcer, IEnumerable oldValues, + IEnumerable newValues) => + enforcer.UpdatePolicyAsync(oldValues, newValues as string[] ?? newValues.ToArray()); /// /// Updates an authorization rule to the current policy. /// /// - /// The "p" policy rule to be replaced, policyType "p" is implicitly used. - /// The "p" policy rule to replace the old one, policyType "p" is implicitly used. + /// The "p" policy rule to be replaced, policyType "p" is implicitly used. + /// The "p" policy rule to replace the old one, policyType "p" is implicitly used. /// Succeeds or not. - public static Task UpdatePolicyAsync(this IEnforcer enforcer, IEnumerable oldParameters, - IEnumerable newParameters) => - UpdateNamedPolicyAsync(enforcer, PermConstants.DefaultPolicyType, oldParameters, newParameters); + public static Task UpdatePolicyAsync(this IEnforcer enforcer, IEnumerable oldValues, + params string[] newValues) => + enforcer.UpdateNamedPolicyAsync(PermConstants.DefaultPolicyType, oldValues, newValues); /// - /// Updates an authorization rule to the current policy. + /// Updates an authorization rule to the current named policy. /// /// /// The policy type, can be "p", "p2", "p3", .. - /// The "p" policy rule to be replaced. - /// The "p" policy rule to replace the old one. + /// The "p" policy rule to be replaced. + /// The "p" policy rule to replace the old one. /// Succeeds or not. public static bool UpdateNamedPolicy(this IEnforcer enforcer, string policyType, - IEnumerable oldParameters, - params string[] newParameters) => - UpdateNamedPolicy(enforcer, policyType, oldParameters, newParameters as IEnumerable); + IEnumerable oldValues, IEnumerable newValues) => + enforcer.UpdateNamedPolicy(policyType, oldValues, newValues as string[] ?? newValues.ToArray()); /// /// Updates an authorization rule to the current policy. /// /// /// The policy type, can be "p", "p2", "p3", .. - /// The "p" policy rule to be replaced. - /// The "p" policy rule to replace the old one. + /// The "p" policy rule to be replaced. + /// The "p" policy rule to replace the old one. /// Succeeds or not. - public static Task UpdateNamedPolicyAsync(this IEnforcer enforcer, string policyType, - IEnumerable oldParameters, params string[] newParameters) => - UpdateNamedPolicyAsync(enforcer, policyType, oldParameters, newParameters as IEnumerable); + public static bool UpdateNamedPolicy(this IEnforcer enforcer, string policyType, + IEnumerable oldValues, params string[] newValues) + { + IPolicyStore policyStore = enforcer.Model.PolicyStoreHolder.PolicyStore; + int requiredCount = policyStore.GetRequiredValuesCount(PermConstants.Section.PolicySection, policyType); + return enforcer.InternalUpdatePolicy(PermConstants.Section.PolicySection, policyType, + Policy.ValuesFrom(oldValues, requiredCount), Policy.ValuesFrom(newValues, requiredCount)); + } + /// /// Updates an authorization rule to the current named policy. /// /// /// The policy type, can be "p", "p2", "p3", .. - /// The "p" policy rule to be replaced. - /// The "p" policy rule to replace the old one. + /// The "p" policy rule to be replaced. + /// The "p" policy rule to replace the old one. /// Succeeds or not. - public static bool UpdateNamedPolicy(this IEnforcer enforcer, string policyType, - IEnumerable oldParameters, - IEnumerable newParameters) => enforcer.InternalUpdatePolicy(PermConstants.Section.PolicySection, - policyType, Policy.ValuesFrom(oldParameters), Policy.ValuesFrom(newParameters)); + public static Task UpdateNamedPolicyAsync(this IEnforcer enforcer, string policyType, + IEnumerable oldValues, IEnumerable newValues) => + enforcer.UpdateNamedPolicyAsync(policyType, oldValues, newValues as string[] ?? newValues.ToArray()); /// - /// Updates an authorization rule to the current named policy. + /// Updates an authorization rule to the current policy. /// /// /// The policy type, can be "p", "p2", "p3", .. - /// The "p" policy rule to be replaced. - /// The "p" policy rule to replace the old one. + /// The "p" policy rule to be replaced. + /// The "p" policy rule to replace the old one. /// Succeeds or not. public static Task UpdateNamedPolicyAsync(this IEnforcer enforcer, string policyType, - IEnumerable oldParameters, IEnumerable newParameters) => - enforcer.InternalUpdatePolicyAsync(PermConstants.Section.PolicySection, policyType, - Policy.ValuesFrom(oldParameters), Policy.ValuesFrom(newParameters)); + IEnumerable oldValues, params string[] newValues) + { + IPolicyStore policyStore = enforcer.Model.PolicyStoreHolder.PolicyStore; + int requiredCount = policyStore.GetRequiredValuesCount(PermConstants.Section.PolicySection, policyType); + return enforcer.InternalUpdatePolicyAsync(PermConstants.Section.PolicySection, policyType, + Policy.ValuesFrom(oldValues, requiredCount), Policy.ValuesFrom(newValues, requiredCount)); + } /// /// Updates authorization rules to the current policies. /// /// - /// The "p" policy rules to be replaced, policyType "p" is implicitly used. - /// The "p" policy rules to replace the old ones, policyType "p" is implicitly used. + /// The "p" policy rules to be replaced, policyType "p" is implicitly used. + /// The "p" policy rules to replace the old ones, policyType "p" is implicitly used. /// Succeeds or not. - public static bool UpdatePolicies(this IEnforcer enforcer, IEnumerable> oldRules, - IEnumerable> newRules) => - UpdateNamedPolicies(enforcer, PermConstants.DefaultPolicyType, oldRules, newRules); + public static bool UpdatePolicies(this IEnforcer enforcer, IEnumerable> oldValues, + IEnumerable> newValues) => + enforcer.UpdateNamedPolicies(PermConstants.DefaultPolicyType, oldValues, newValues); /// /// Updates authorization rules to the current policies. /// /// - /// The "p" policy rules to be replaced, policyType "p" is implicitly used. - /// The "p" policy rules to replace the old ones, policyType "p" is implicitly used. + /// The "p" policy rules to be replaced, policyType "p" is implicitly used. + /// The "p" policy rules to replace the old ones, policyType "p" is implicitly used. /// Succeeds or not. - public static Task UpdatePoliciesAsync(this IEnforcer enforcer, IEnumerable> oldRules, - IEnumerable> newRules) => - UpdateNamedPoliciesAsync(enforcer, PermConstants.DefaultPolicyType, oldRules, newRules); + public static Task UpdatePoliciesAsync(this IEnforcer enforcer, + IEnumerable> oldValues, IEnumerable> newValues) => + enforcer.UpdateNamedPoliciesAsync(PermConstants.DefaultPolicyType, oldValues, newValues); /// /// Updates authorization rules to the current named policies. /// /// /// The policy type, can be "p", "p2", "p3", .. - /// The "p" policy rule to be replaced. - /// The "p" policy rule to replace the old ones. + /// The "p" policy rule to be replaced. + /// The "p" policy rule to replace the old ones. /// Succeeds or not. public static bool UpdateNamedPolicies(this IEnforcer enforcer, string policyType, - IEnumerable> oldRules, IEnumerable> newRules) => - enforcer.InternalUpdatePolicies(PermConstants.Section.PolicySection, policyType, - Policy.ValuesListFrom(oldRules), Policy.ValuesListFrom(newRules)); + IEnumerable> oldValues, IEnumerable> newValues) + { + IPolicyStore policyStore = enforcer.Model.PolicyStoreHolder.PolicyStore; + int requiredCount = policyStore.GetRequiredValuesCount(PermConstants.Section.PolicySection, policyType); + return enforcer.InternalUpdatePolicies(PermConstants.Section.PolicySection, policyType, + Policy.ValuesListFrom(oldValues), Policy.ValuesListFrom(newValues, requiredCount)); + } /// /// Updates authorization rules to the current named policies. /// /// /// The policy type, can be "p", "p2", "p3", .. - /// The "p" policy rule to be replaced. - /// The "p" policy rule to replace the old ones. + /// The "p" policy rule to be replaced. + /// The "p" policy rule to replace the old ones. /// Succeeds or not. public static Task UpdateNamedPoliciesAsync(this IEnforcer enforcer, string policyType, - IEnumerable> oldRules, IEnumerable> newRules) => - enforcer.InternalUpdatePoliciesAsync(PermConstants.Section.PolicySection, policyType, - Policy.ValuesListFrom(oldRules), Policy.ValuesListFrom(newRules)); + IEnumerable> oldValues, IEnumerable> newValues) + { + IPolicyStore policyStore = enforcer.Model.PolicyStoreHolder.PolicyStore; + int requiredCount = policyStore.GetRequiredValuesCount(PermConstants.Section.PolicySection, policyType); + return enforcer.InternalUpdatePoliciesAsync(PermConstants.Section.PolicySection, policyType, + Policy.ValuesListFrom(oldValues), Policy.ValuesListFrom(newValues, requiredCount)); + } #endregion @@ -527,136 +534,141 @@ public static Task UpdateNamedPoliciesAsync(this IEnforcer enforcer, strin /// Removes an authorization rule from the current policy. /// /// - /// The "p" policy rule, policyType "p" is implicitly used. + /// The "p" policy rule, policyType "p" is implicitly used. /// Succeeds or not. - public static bool RemovePolicy(this IEnforcer enforcer, IEnumerable parameters) - { - return RemoveNamedPolicy(enforcer, PermConstants.Section.PolicySection, parameters); - } + public static bool RemovePolicy(this IEnforcer enforcer, IEnumerable values) => + enforcer.RemovePolicy(values as string[] ?? values.ToArray()); /// - /// Removes an authorization rule from the current policy. + /// Removes an authorization rule from the current policy. /// /// - /// The "p" policy rule, policyType "p" is implicitly used. + /// The "p" policy rule, policyType "p" is implicitly used. /// Succeeds or not. - public static Task RemovePolicyAsync(this IEnforcer enforcer, IEnumerable parameters) - { - return RemoveNamedPolicyAsync(enforcer, PermConstants.DefaultPolicyType, parameters); - } + public static bool RemovePolicy(this IEnforcer enforcer, params string[] values) => + enforcer.RemoveNamedPolicy(PermConstants.Section.PolicySection, values); /// /// Removes an authorization rule from the current policy. /// /// - /// The "p" policy rule, policyType "p" is implicitly used. + /// The "p" policy rule, policyType "p" is implicitly used. /// Succeeds or not. - public static bool RemovePolicy(this IEnforcer enforcer, params string[] parameters) - { - return RemovePolicy(enforcer, parameters as IEnumerable); - } + public static Task RemovePolicyAsync(this IEnforcer enforcer, IEnumerable values) => + enforcer.RemovePolicyAsync(values as string[] ?? values.ToArray()); /// /// Removes an authorization rule from the current policy. /// /// - /// The "p" policy rule, policyType "p" is implicitly used. + /// The "p" policy rule, policyType "p" is implicitly used. /// Succeeds or not. - public static Task RemovePolicyAsync(this IEnforcer enforcer, params string[] parameters) - { - return RemovePolicyAsync(enforcer, parameters as IEnumerable); - } + public static Task RemovePolicyAsync(this IEnforcer enforcer, params string[] values) => + enforcer.RemoveNamedPolicyAsync(PermConstants.DefaultPolicyType, values); /// - /// Removes an authorization rule from the current named policy. + /// Removes an authorization rule from the current named policy. /// /// /// The policy type, can be "p", "p2", "p3", .. - /// The "p" policy rule. + /// The "p" policy rule. /// Succeeds or not. - public static bool RemoveNamedPolicy(this IEnforcer enforcer, string policyType, params string[] parameters) => - RemoveNamedPolicy(enforcer, policyType, parameters as IEnumerable); + public static bool RemoveNamedPolicy(this IEnforcer enforcer, string policyType, + IEnumerable values) => + enforcer.RemoveNamedPolicy(policyType, values as string[] ?? values.ToArray()); /// /// Removes an authorization rule from the current named policy. /// /// /// The policy type, can be "p", "p2", "p3", .. - /// The "p" policy rule. + /// The "p" policy rule. /// Succeeds or not. - public static Task RemoveNamedPolicyAsync(this IEnforcer enforcer, string policyType, - params string[] parameters) => - RemoveNamedPolicyAsync(enforcer, policyType, parameters as IEnumerable); + public static bool RemoveNamedPolicy(this IEnforcer enforcer, string policyType, params string[] values) + { + IPolicyStore policyStore = enforcer.Model.PolicyStoreHolder.PolicyStore; + int requiredCount = policyStore.GetRequiredValuesCount(PermConstants.Section.PolicySection, policyType); + return enforcer.InternalRemovePolicy(PermConstants.Section.PolicySection, policyType, + Policy.ValuesFrom(values, requiredCount)); + } /// - /// Removes an authorization rule from the current named policy. + /// Removes an authorization rule from the current named policy. /// /// /// The policy type, can be "p", "p2", "p3", .. - /// The "p" policy rule. + /// The "p" policy rule. /// Succeeds or not. - public static bool RemoveNamedPolicy(this IEnforcer enforcer, string policyType, - IEnumerable parameters) => - enforcer.InternalRemovePolicy(PermConstants.Section.PolicySection, policyType, - Policy.ValuesFrom(parameters)); + public static Task RemoveNamedPolicyAsync(this IEnforcer enforcer, string policyType, + IEnumerable values) => + enforcer.RemoveNamedPolicyAsync(policyType, values as string[] ?? values.ToArray()); /// /// Removes an authorization rule from the current named policy. /// /// /// The policy type, can be "p", "p2", "p3", .. - /// The "p" policy rule. + /// The "p" policy rule. /// Succeeds or not. public static Task RemoveNamedPolicyAsync(this IEnforcer enforcer, string policyType, - IEnumerable parameters) => - enforcer.InternalRemovePolicyAsync(PermConstants.Section.PolicySection, policyType, - Policy.ValuesFrom(parameters)); + params string[] values) + { + IPolicyStore policyStore = enforcer.Model.PolicyStoreHolder.PolicyStore; + int requiredCount = policyStore.GetRequiredValuesCount(PermConstants.Section.PolicySection, policyType); + return enforcer.InternalRemovePolicyAsync(PermConstants.Section.PolicySection, policyType, + Policy.ValuesFrom(values, requiredCount)); + } /// /// Removes authorization rules from the current policy. /// /// - /// The "p" policy rule, policyType "p" is implicitly used. + /// The "p" policy rule, policyType "p" is implicitly used. /// Succeeds or not. - public static bool RemovePolicies(this IEnforcer enforcer, IEnumerable> rules) - { - return RemoveNamedPolicies(enforcer, PermConstants.DefaultPolicyType, rules); - } + public static bool RemovePolicies(this IEnforcer enforcer, IEnumerable> values) => + enforcer.RemoveNamedPolicies(PermConstants.DefaultPolicyType, values); /// /// Removes authorization rules from the current policy. /// /// - /// The "p" policy rule, policyType "p" is implicitly used. + /// The "p" policy rule, policyType "p" is implicitly used. /// Succeeds or not. - public static Task RemovePoliciesAsync(this IEnforcer enforcer, IEnumerable> rules) - { - return RemoveNamedPoliciesAsync(enforcer, PermConstants.DefaultPolicyType, rules); - } + public static Task + RemovePoliciesAsync(this IEnforcer enforcer, IEnumerable> values) => + enforcer.RemoveNamedPoliciesAsync(PermConstants.DefaultPolicyType, values); /// /// Removes authorization rules from the current named policy. /// /// /// The policy type, can be "p", "p2", "p3", .. - /// The "p" policy rule. + /// The "p" policy rule. /// Succeeds or not. public static bool RemoveNamedPolicies(this IEnforcer enforcer, string policyType, - IEnumerable> rules) => - enforcer.InternalRemovePolicies(PermConstants.Section.PolicySection, policyType, - Policy.ValuesListFrom(rules)); + IEnumerable> values) + { + IPolicyStore policyStore = enforcer.Model.PolicyStoreHolder.PolicyStore; + int requiredCount = policyStore.GetRequiredValuesCount(PermConstants.Section.PolicySection, policyType); + return enforcer.InternalRemovePolicies(PermConstants.Section.PolicySection, policyType, + Policy.ValuesListFrom(values, requiredCount)); + } /// /// Removes authorization rules from the current named policy. /// /// /// The policy type, can be "p", "p2", "p3", .. - /// The "p" policy rule. + /// The "p" policy rule. /// Succeeds or not. public static Task RemoveNamedPoliciesAsync(this IEnforcer enforcer, string policyType, - IEnumerable> rules) => - enforcer.InternalRemovePoliciesAsync(PermConstants.Section.PolicySection, policyType, - Policy.ValuesListFrom(rules)); + IEnumerable> values) + { + IPolicyStore policyStore = enforcer.Model.PolicyStoreHolder.PolicyStore; + int requiredCount = policyStore.GetRequiredValuesCount(PermConstants.Section.PolicySection, policyType); + return enforcer.InternalRemovePoliciesAsync(PermConstants.Section.PolicySection, policyType, + Policy.ValuesListFrom(values, requiredCount)); + } /// /// Removes an authorization rule from the current policy, field filters can be specified. @@ -665,10 +677,8 @@ public static Task RemoveNamedPoliciesAsync(this IEnforcer enforcer, strin /// The policy rule's start index to be matched. /// The field values to be matched, value "" means not to match this field. /// Succeeds or not. - public static bool RemoveFilteredPolicy(this IEnforcer enforcer, int fieldIndex, params string[] fieldValues) - { - return RemoveFilteredNamedPolicy(enforcer, PermConstants.DefaultPolicyType, fieldIndex, fieldValues); - } + public static bool RemoveFilteredPolicy(this IEnforcer enforcer, int fieldIndex, params string[] fieldValues) => + enforcer.RemoveFilteredNamedPolicy(PermConstants.DefaultPolicyType, fieldIndex, fieldValues); /// /// Removes an authorization rule from the current policy, field filters can be specified. @@ -678,11 +688,8 @@ public static bool RemoveFilteredPolicy(this IEnforcer enforcer, int fieldIndex, /// The field values to be matched, value "" means not to match this field. /// Succeeds or not. public static Task RemoveFilteredPolicyAsync(this IEnforcer enforcer, int fieldIndex, - params string[] fieldValues) - { - return RemoveFilteredNamedPolicyAsync(enforcer, PermConstants.DefaultPolicyType, fieldIndex, fieldValues); - } - + params string[] fieldValues) => + enforcer.RemoveFilteredNamedPolicyAsync(PermConstants.DefaultPolicyType, fieldIndex, fieldValues); /// /// Removes an authorization rule from the current named policy, field filters can be specified. @@ -706,8 +713,7 @@ public static bool RemoveFilteredNamedPolicy(this IEnforcer enforcer, string pol /// The field values to be matched, value "" means not to match this field. /// Succeeds or not. public static Task RemoveFilteredNamedPolicyAsync(this IEnforcer enforcer, string policyType, - int fieldIndex, - params string[] fieldValues) => + int fieldIndex, params string[] fieldValues) => enforcer.InternalRemoveFilteredPolicyAsync(PermConstants.Section.PolicySection, policyType, fieldIndex, Policy.ValuesFrom(fieldValues)); @@ -728,10 +734,8 @@ public static Task RemoveFilteredNamedPolicyAsync(this IEnforcer enforcer, /// the 1-index elements of "g" policy rules. So make sure your /// role is the 1-index element, like (sub, role). /// Duplicates are removed. - public static IEnumerable GetAllRoles(this IEnforcer enforcer) - { - return GetAllNamedRoles(enforcer, PermConstants.Section.RoleSection); - } + public static IEnumerable GetAllRoles(this IEnforcer enforcer) => + enforcer.GetAllNamedRoles(PermConstants.Section.RoleSection); /// /// Gets the list of roles that show up in the current named policy. @@ -748,67 +752,14 @@ public static IEnumerable GetAllNamedRoles(this IEnforcer enforcer, stri #endregion - #region Has Grouping/Role Store - - /// - /// Determines whether a role inheritance rule exists. - /// - /// - /// The "g" policy rule, policyType "g" is implicitly used. - /// Whether the rule exists. - public static bool HasGroupingPolicy(this IEnforcer enforcer, IEnumerable parameters) - { - return HasNamedGroupingPolicy(enforcer, PermConstants.DefaultGroupingPolicyType, parameters); - } - - /// - /// Determines whether a role inheritance rule exists. - /// - /// - /// The "g" policy rule, policyType "g" is implicitly used. - /// Whether the rule exists. - public static bool HasGroupingPolicy(this IEnforcer enforcer, params string[] parameters) - { - return HasGroupingPolicy(enforcer, parameters as IEnumerable); - } - - /// - /// Determines whether a named role inheritance rule - /// exists. - /// - /// - /// The policy type, can be "g", "g2", "g3", .. - /// The "g" policy rule. - /// Whether the rule exists. - public static bool HasNamedGroupingPolicy(this IEnforcer enforcer, string policyType, - IEnumerable parameters) => - enforcer.InternalHasPolicy(PermConstants.Section.RoleSection, policyType, - Policy.ValuesFrom(parameters)); - - /// - /// Determines whether a named role inheritance rule - /// exists. - /// - /// - /// The policy type, can be "g", "g2", "g3", .. - /// The "g" policy rule. - /// Whether the rule exists. - public static bool HasNamedGroupingPolicy(this IEnforcer enforcer, string policyType, - params string[] parameters) => - HasNamedGroupingPolicy(enforcer, policyType, parameters as IEnumerable); - - #endregion - #region Get Grouping/Role Store /// /// Gets all the role inheritance rules in the policy. /// /// all the "g" policy rules. - public static IEnumerable> GetGroupingPolicy(this IEnforcer enforcer) - { - return GetNamedGroupingPolicy(enforcer, PermConstants.DefaultGroupingPolicyType); - } + public static IEnumerable> GetGroupingPolicy(this IEnforcer enforcer) => + enforcer.GetNamedGroupingPolicy(PermConstants.DefaultGroupingPolicyType); /// /// Gets all the role inheritance rules in the policy, field filters can be specified. @@ -819,7 +770,7 @@ public static IEnumerable> GetGroupingPolicy(this IEnforcer /// The filtered "g" policy rules. public static IEnumerable> GetFilteredGroupingPolicy(this IEnforcer enforcer, int fieldIndex, params string[] fieldValues) => - GetFilteredNamedGroupingPolicy(enforcer, PermConstants.DefaultGroupingPolicyType, fieldIndex, + enforcer.GetFilteredNamedGroupingPolicy(PermConstants.DefaultGroupingPolicyType, fieldIndex, fieldValues); /// @@ -847,33 +798,80 @@ public static IEnumerable> GetFilteredNamedGroupingPolicy(th #endregion - #region Add Grouping/Role Store + #region Has Grouping/Role Store /// - /// Adds a role inheritance rule to the current policy. If the - /// rule already exists, the function returns false and the rule will not be - /// Added.Otherwise the function returns true by adding the new rule. + /// Determines whether a role inheritance rule exists. /// /// - /// The "g" policy rule, policyType "g" is implicitly used. - /// Succeeds or not. - public static bool AddGroupingPolicy(this IEnforcer enforcer, IEnumerable parameters) + /// The "g" policy rule, policyType "g" is implicitly used. + /// Whether the rule exists. + public static bool HasGroupingPolicy(this IEnforcer enforcer, IEnumerable values) => + enforcer.HasGroupingPolicy(values as string[] ?? values.ToArray()); + + /// + /// Determines whether a role inheritance rule exists. + /// + /// + /// The "g" policy rule, policyType "g" is implicitly used. + /// Whether the rule exists. + public static bool HasGroupingPolicy(this IEnforcer enforcer, params string[] values) => + enforcer.HasNamedGroupingPolicy(PermConstants.DefaultGroupingPolicyType, values); + + /// + /// Determines whether a named role inheritance rule + /// exists. + /// + /// + /// The policy type, can be "g", "g2", "g3", .. + /// The "g" policy rule. + /// Whether the rule exists. + public static bool HasNamedGroupingPolicy(this IEnforcer enforcer, string policyType, + IEnumerable values) => + enforcer.HasNamedGroupingPolicy(policyType, values as string[] ?? values.ToArray()); + + /// + /// Determines whether a named role inheritance rule + /// exists. + /// + /// + /// The policy type, can be "g", "g2", "g3", .. + /// The "g" policy rule. + /// Whether the rule exists. + public static bool HasNamedGroupingPolicy(this IEnforcer enforcer, string policyType, + params string[] values) { - return AddNamedGroupingPolicy(enforcer, PermConstants.DefaultGroupingPolicyType, parameters); + IPolicyStore policyStore = enforcer.Model.PolicyStoreHolder.PolicyStore; + int requiredCount = policyStore.GetRequiredValuesCount(PermConstants.Section.RoleSection, policyType); + return enforcer.InternalHasPolicy(PermConstants.Section.RoleSection, policyType, + Policy.ValuesFrom(values, requiredCount)); } + #endregion + + #region Add Grouping/Role Store + /// /// Adds a role inheritance rule to the current policy. If the /// rule already exists, the function returns false and the rule will not be /// Added.Otherwise the function returns true by adding the new rule. /// /// - /// The "g" policy rule, policyType "g" is implicitly used. + /// The "g" policy rule, policyType "g" is implicitly used. /// Succeeds or not. - public static Task AddGroupingPolicyAsync(this IEnforcer enforcer, IEnumerable parameters) - { - return AddNamedGroupingPolicyAsync(enforcer, PermConstants.DefaultGroupingPolicyType, parameters); - } + public static bool AddGroupingPolicy(this IEnforcer enforcer, IEnumerable values) => + enforcer.AddGroupingPolicy(values as string[] ?? values.ToArray()); + + /// + /// Adds a role inheritance rule to the current policy. If the + /// rule already exists, the function returns false and the rule will not be + /// Added.Otherwise the function returns true by adding the new rule. + /// + /// + /// The "g" policy rule, policyType "g" is implicitly used. + /// Succeeds or not. + public static bool AddGroupingPolicy(this IEnforcer enforcer, params string[] values) => + enforcer.AddNamedGroupingPolicy(PermConstants.DefaultGroupingPolicyType, values); /// /// Adds a role inheritance rule to the current policy. If the @@ -881,12 +879,10 @@ public static Task AddGroupingPolicyAsync(this IEnforcer enforcer, IEnumer /// Added.Otherwise the function returns true by adding the new rule. /// /// - /// The "g" policy rule, policyType "g" is implicitly used. + /// The "g" policy rule, policyType "g" is implicitly used. /// Succeeds or not. - public static bool AddGroupingPolicy(this IEnforcer enforcer, params string[] parameters) - { - return AddGroupingPolicy(enforcer, parameters as IEnumerable); - } + public static Task AddGroupingPolicyAsync(this IEnforcer enforcer, IEnumerable values) => + enforcer.AddGroupingPolicyAsync(values as string[] ?? values.ToArray()); /// /// Adds a role inheritance rule to the current policy. If the @@ -894,12 +890,10 @@ public static bool AddGroupingPolicy(this IEnforcer enforcer, params string[] pa /// Added.Otherwise the function returns true by adding the new rule. /// /// - /// The "g" policy rule, policyType "g" is implicitly used. + /// The "g" policy rule, policyType "g" is implicitly used. /// Succeeds or not. - public static Task AddGroupingPolicyAsync(this IEnforcer enforcer, params string[] parameters) - { - return AddGroupingPolicyAsync(enforcer, parameters as IEnumerable); - } + public static Task AddGroupingPolicyAsync(this IEnforcer enforcer, params string[] values) => + enforcer.AddNamedGroupingPolicyAsync(PermConstants.DefaultGroupingPolicyType, values); /// /// Adds a named role inheritance rule to the current @@ -911,11 +905,8 @@ public static Task AddGroupingPolicyAsync(this IEnforcer enforcer, params /// The "g" policy rule. /// Succeeds or not. public static bool AddNamedGroupingPolicy(this IEnforcer enforcer, string policyType, - IEnumerable values) - { - string[] valuesArray = values as string[] ?? values.ToArray(); - return enforcer.AddNamedGroupingPolicy(policyType, valuesArray); - } + IEnumerable values) => + enforcer.AddNamedGroupingPolicy(policyType, values as string[] ?? values.ToArray()); /// /// Adds a named role inheritance rule to the current @@ -926,8 +917,13 @@ public static bool AddNamedGroupingPolicy(this IEnforcer enforcer, string policy /// The policy type, can be "g", "g2", "g3", .. /// The "g" policy rule. /// Succeeds or not. - public static bool AddNamedGroupingPolicy(this IEnforcer enforcer, string policyType, params string[] values) => - enforcer.InternalAddPolicy(PermConstants.Section.RoleSection, policyType, Policy.ValuesFrom(values)); + public static bool AddNamedGroupingPolicy(this IEnforcer enforcer, string policyType, params string[] values) + { + IPolicyStore policyStore = enforcer.Model.PolicyStoreHolder.PolicyStore; + int requiredCount = policyStore.GetRequiredValuesCount(PermConstants.Section.RoleSection, policyType); + return enforcer.InternalAddPolicy(PermConstants.Section.RoleSection, policyType, + Policy.ValuesFrom(values, requiredCount)); + } /// /// Adds a named role inheritance rule to the current @@ -936,12 +932,11 @@ public static bool AddNamedGroupingPolicy(this IEnforcer enforcer, string policy /// /// /// The policy type, can be "g", "g2", "g3", .. - /// The "g" policy rule. + /// The "g" policy rule. /// Succeeds or not. - public static async Task AddNamedGroupingPolicyAsync(this IEnforcer enforcer, string policyType, - IEnumerable parameters) => - await enforcer.InternalAddPolicyAsync(PermConstants.Section.RoleSection, policyType, - Policy.ValuesFrom(parameters)); + public static Task AddNamedGroupingPolicyAsync(this IEnforcer enforcer, string policyType, + IEnumerable values) => + enforcer.AddNamedGroupingPolicyAsync(policyType, values as string[] ?? values.ToArray()); /// /// Adds a named role inheritance rule to the current @@ -950,12 +945,15 @@ await enforcer.InternalAddPolicyAsync(PermConstants.Section.RoleSection, policyT /// /// /// The policy type, can be "g", "g2", "g3", .. - /// The "g" policy rule. + /// The "g" policy rule. /// Succeeds or not. public static Task AddNamedGroupingPolicyAsync(this IEnforcer enforcer, string policyType, - params string[] parameters) + params string[] values) { - return enforcer.AddNamedGroupingPolicyAsync(policyType, parameters as IEnumerable); + IPolicyStore policyStore = enforcer.Model.PolicyStoreHolder.PolicyStore; + int requiredCount = policyStore.GetRequiredValuesCount(PermConstants.Section.RoleSection, policyType); + return enforcer.InternalAddPolicyAsync(PermConstants.Section.RoleSection, policyType, + Policy.ValuesFrom(values, requiredCount)); } /// @@ -964,12 +962,10 @@ public static Task AddNamedGroupingPolicyAsync(this IEnforcer enforcer, st /// Added.Otherwise the function returns true by adding the new rule. /// /// - /// The "g" policy rule, policyType "g" is implicitly used. + /// The "g" policy rule, policyType "g" is implicitly used. /// Succeeds or not. - public static bool AddGroupingPolicies(this IEnforcer enforcer, IEnumerable> rules) - { - return AddNamedGroupingPolicies(enforcer, PermConstants.DefaultGroupingPolicyType, rules); - } + public static bool AddGroupingPolicies(this IEnforcer enforcer, IEnumerable> valuesList) => + enforcer.AddNamedGroupingPolicies(PermConstants.DefaultGroupingPolicyType, valuesList); /// /// Adds roles inheritance rule to the current policy. If the @@ -977,13 +973,11 @@ public static bool AddGroupingPolicies(this IEnforcer enforcer, IEnumerable /// - /// The "g" policy rule, policyType "g" is implicitly used. + /// The "g" policy rule, policyType "g" is implicitly used. /// Succeeds or not. public static Task AddGroupingPoliciesAsync(this IEnforcer enforcer, - IEnumerable> rules) - { - return AddNamedGroupingPoliciesAsync(enforcer, PermConstants.DefaultGroupingPolicyType, rules); - } + IEnumerable> valuesList) => + enforcer.AddNamedGroupingPoliciesAsync(PermConstants.DefaultGroupingPolicyType, valuesList); /// /// Adds named roles inheritance rule to the current @@ -992,14 +986,15 @@ public static Task AddGroupingPoliciesAsync(this IEnforcer enforcer, /// /// /// The policy type, can be "g", "g2", "g3", .. - /// The "g" policy rule. + /// The "g" policy rule. /// Succeeds or not. public static bool AddNamedGroupingPolicies(this IEnforcer enforcer, string policyType, - IEnumerable> rules) + IEnumerable> valuesList) { - var ans = Policy.ValuesListFrom(rules); + IPolicyStore policyStore = enforcer.Model.PolicyStoreHolder.PolicyStore; + int requiredCount = policyStore.GetRequiredValuesCount(PermConstants.Section.RoleSection, policyType); return enforcer.InternalAddPolicies(PermConstants.Section.RoleSection, policyType, - ans); + Policy.ValuesListFrom(valuesList, requiredCount)); } /// @@ -1009,12 +1004,16 @@ public static bool AddNamedGroupingPolicies(this IEnforcer enforcer, string poli /// /// /// The policy type, can be "g", "g2", "g3", .. - /// The "g" policy rule. + /// The "g" policy rule. /// Succeeds or not. - public static async Task AddNamedGroupingPoliciesAsync(this IEnforcer enforcer, string policyType, - IEnumerable> rules) => - await enforcer.InternalAddPoliciesAsync(PermConstants.Section.RoleSection, policyType, - Policy.ValuesListFrom(rules)); + public static Task AddNamedGroupingPoliciesAsync(this IEnforcer enforcer, string policyType, + IEnumerable> valuesList) + { + IPolicyStore policyStore = enforcer.Model.PolicyStoreHolder.PolicyStore; + int requiredCount = policyStore.GetRequiredValuesCount(PermConstants.Section.RoleSection, policyType); + return enforcer.InternalAddPoliciesAsync(PermConstants.Section.RoleSection, policyType, + Policy.ValuesListFrom(valuesList, requiredCount)); + } #endregion @@ -1024,143 +1023,162 @@ await enforcer.InternalAddPoliciesAsync(PermConstants.Section.RoleSection, polic /// Updates a role inheritance rule from the current policy. /// /// - /// The "g" policy rule to be replaced, policyType "g" is implicitly used. - /// The "g" policy rule to replace the old one, policyType "g" is implicitly used. + /// The "g" policy rule to be replaced, policyType "g" is implicitly used. + /// The "g" policy rule to replace the old one, policyType "g" is implicitly used. /// Succeeds or not. - public static bool UpdateGroupingPolicy(this IEnforcer enforcer, IEnumerable oldParameters, - params string[] newParameters) => - UpdateGroupingPolicy(enforcer, oldParameters, newParameters as IEnumerable); + public static bool UpdateGroupingPolicy(this IEnforcer enforcer, IEnumerable oldValues, + IEnumerable newValues) => + enforcer.UpdateGroupingPolicy(oldValues, newValues as string[] ?? newValues.ToArray()); /// /// Updates a role inheritance rule from the current policy. /// /// - /// The "g" policy rule to be replaced, policyType "g" is implicitly used. - /// The "g" policy rule to replace the old one, policyType "g" is implicitly used. + /// The "g" policy rule to be replaced, policyType "g" is implicitly used. + /// The "g" policy rule to replace the old one, policyType "g" is implicitly used. /// Succeeds or not. - public static Task UpdateGroupingPolicyAsync(this IEnforcer enforcer, IEnumerable oldParameters, - params string[] newParameters) => - UpdateGroupingPolicyAsync(enforcer, oldParameters, newParameters as IEnumerable); + public static bool UpdateGroupingPolicy(this IEnforcer enforcer, IEnumerable oldValues, + params string[] newValues) => + enforcer.UpdateNamedGroupingPolicy(PermConstants.DefaultGroupingPolicyType, oldValues, newValues); /// /// Updates a role inheritance rule from the current policy. /// /// - /// The "g" policy rule to be replaced, policyType "g" is implicitly used. - /// The "g" policy rule to replace the old one, policyType "g" is implicitly used. + /// The "g" policy rule to be replaced, policyType "g" is implicitly used. + /// The "g" policy rule to replace the old one, policyType "g" is implicitly used. /// Succeeds or not. - public static bool UpdateGroupingPolicy(this IEnforcer enforcer, IEnumerable oldParameters, - IEnumerable newParameters) => UpdateNamedGroupingPolicy(enforcer, - PermConstants.DefaultGroupingPolicyType, oldParameters, newParameters); + public static Task UpdateGroupingPolicyAsync(this IEnforcer enforcer, IEnumerable oldValues, + IEnumerable newValues) => + enforcer.UpdateGroupingPolicyAsync(oldValues, newValues as string[] ?? newValues.ToArray()); /// /// Updates a role inheritance rule from the current policy. /// /// - /// The "g" policy rule to be replaced, policyType "g" is implicitly used. - /// The "g" policy rule to replace the old one, policyType "g" is implicitly used. + /// The "g" policy rule to be replaced, policyType "g" is implicitly used. + /// The "g" policy rule to replace the old one, policyType "g" is implicitly used. /// Succeeds or not. - public static Task UpdateGroupingPolicyAsync(this IEnforcer enforcer, IEnumerable oldParameters, - IEnumerable newParameters) => UpdateNamedGroupingPolicyAsync(enforcer, - PermConstants.DefaultGroupingPolicyType, oldParameters, newParameters); + public static Task UpdateGroupingPolicyAsync(this IEnforcer enforcer, IEnumerable oldValues, + params string[] newValues) => + enforcer.UpdateNamedGroupingPolicyAsync(PermConstants.DefaultGroupingPolicyType, oldValues, + newValues); /// /// Updates a role inheritance rule from the current policy, field filters can be specified. /// /// /// The policy type, can be "g", "g2", "g3", .. - /// The "g" policy rule to be replaced, policyType "g" is implicitly used. - /// The "g" policy rule to replace the old one, policyType "g" is implicitly used. + /// The "g" policy rule to be replaced, policyType "g" is implicitly used. + /// The "g" policy rule to replace the old one, policyType "g" is implicitly used. /// Succeeds or not. public static bool UpdateNamedGroupingPolicy(this IEnforcer enforcer, string policyType, - IEnumerable oldParameters, params string[] newParameters) => - UpdateNamedGroupingPolicy(enforcer, policyType, oldParameters, newParameters as IEnumerable); + IEnumerable oldValues, IEnumerable newValues) => + enforcer.UpdateNamedGroupingPolicy(policyType, oldValues, newValues as string[] ?? newValues.ToArray()); /// /// Updates a role inheritance rule from the current policy, field filters can be specified. /// /// /// The policy type, can be "g", "g2", "g3", .. - /// The "g" policy rule to be replaced, policyType "g" is implicitly used. - /// The "g" policy rule to replace the old one, policyType "g" is implicitly used. + /// The "g" policy rule to be replaced, policyType "g" is implicitly used. + /// The "g" policy rule to replace the old one, policyType "g" is implicitly used. /// Succeeds or not. - public static Task UpdateNamedGroupingPolicyAsync(this IEnforcer enforcer, string policyType, - IEnumerable oldParameters, params string[] newParameters) => - UpdateNamedGroupingPolicyAsync(enforcer, policyType, oldParameters, newParameters as IEnumerable); + public static bool UpdateNamedGroupingPolicy(this IEnforcer enforcer, string policyType, + IEnumerable oldValues, params string[] newValues) + { + IPolicyStore policyStore = enforcer.Model.PolicyStoreHolder.PolicyStore; + int requiredCount = policyStore.GetRequiredValuesCount(PermConstants.Section.RoleSection, policyType); + return enforcer.InternalUpdatePolicy(PermConstants.Section.RoleSection, policyType, + Policy.ValuesFrom(oldValues, requiredCount), Policy.ValuesFrom(newValues, requiredCount)); + } /// /// Updates a role inheritance rule from the current policy, field filters can be specified. /// /// /// The policy type, can be "g", "g2", "g3", .. - /// The "g" policy rule to be replaced, policyType "g" is implicitly used. - /// The "g" policy rule to replace the old one, policyType "g" is implicitly used. + /// The "g" policy rule to be replaced, policyType "g" is implicitly used. + /// The "g" policy rule to replace the old one, policyType "g" is implicitly used. /// Succeeds or not. - public static bool UpdateNamedGroupingPolicy(this IEnforcer enforcer, string policyType, - IEnumerable oldParameters, IEnumerable newParameters) => - enforcer.InternalUpdatePolicy(PermConstants.Section.RoleSection, policyType, - Policy.ValuesFrom(oldParameters), Policy.ValuesFrom(newParameters)); + public static Task UpdateNamedGroupingPolicyAsync(this IEnforcer enforcer, string policyType, + IEnumerable oldValues, IEnumerable newValues) => + enforcer.UpdateNamedGroupingPolicyAsync(policyType, oldValues, + newValues as string[] ?? newValues.ToArray()); /// /// Updates a role inheritance rule from the current policy, field filters can be specified. /// /// /// The policy type, can be "g", "g2", "g3", .. - /// The "g" policy rule to be replaced, policyType "g" is implicitly used. - /// The "g" policy rule to replace the old one, policyType "g" is implicitly used. + /// The "g" policy rule to be replaced, policyType "g" is implicitly used. + /// The "g" policy rule to replace the old one, policyType "g" is implicitly used. /// Succeeds or not. - public static async Task UpdateNamedGroupingPolicyAsync(this IEnforcer enforcer, string policyType, - IEnumerable oldParameters, IEnumerable newParameters) => - await enforcer.InternalUpdatePolicyAsync(PermConstants.Section.RoleSection, policyType, - Policy.ValuesFrom(oldParameters), Policy.ValuesFrom(newParameters)); + public static Task UpdateNamedGroupingPolicyAsync(this IEnforcer enforcer, string policyType, + IEnumerable oldValues, params string[] newValues) + { + IPolicyStore policyStore = enforcer.Model.PolicyStoreHolder.PolicyStore; + int requiredCount = policyStore.GetRequiredValuesCount(PermConstants.Section.RoleSection, policyType); + return enforcer.InternalUpdatePolicyAsync(PermConstants.Section.RoleSection, policyType, + Policy.ValuesFrom(oldValues, requiredCount), Policy.ValuesFrom(newValues, requiredCount)); + } + /// /// Updates a role inheritance rule from the current policy. /// /// - /// The "g" policy rule to be replaced, policyType "g" is implicitly used. - /// The "g" policy rule to replace the old ones, policyType "g" is implicitly used. + /// The "g" policy rule to be replaced, policyType "g" is implicitly used. + /// The "g" policy rule to replace the old ones, policyType "g" is implicitly used. /// Succeeds or not. - public static bool UpdateGroupingPolicies(this IEnforcer enforcer, IEnumerable> oldRules, - IEnumerable> newRules) => UpdateNamedGroupingPolicies(enforcer, - PermConstants.DefaultGroupingPolicyType, oldRules, newRules); + public static bool UpdateGroupingPolicies(this IEnforcer enforcer, IEnumerable> oldValues, + IEnumerable> newValues) => + enforcer.UpdateNamedGroupingPolicies(PermConstants.DefaultGroupingPolicyType, oldValues, newValues); /// /// Updates a role inheritance rule from the current policy. /// /// - /// The "g" policy rule to be replaced, policyType "g" is implicitly used. - /// The "g" policy rule to replace the old one, policyType "g" is implicitly used. + /// The "g" policy rule to be replaced, policyType "g" is implicitly used. + /// The "g" policy rule to replace the old one, policyType "g" is implicitly used. /// Succeeds or not. public static Task UpdateGroupingPoliciesAsync(this IEnforcer enforcer, - IEnumerable> oldRules, IEnumerable> newRules) => - UpdateNamedGroupingPoliciesAsync(enforcer, PermConstants.DefaultGroupingPolicyType, oldRules, newRules); + IEnumerable> oldValues, IEnumerable> newValues) => + enforcer.UpdateNamedGroupingPoliciesAsync(PermConstants.DefaultGroupingPolicyType, oldValues, newValues); /// /// Updates a role inheritance rule from the current policy, field filters can be specified. /// /// /// The policy type, can be "g", "g2", "g3", .. - /// The "g" policy rule to be replaced, policyType "g" is implicitly used. - /// The "g" policy rule to replace the old ones, policyType "g" is implicitly used. + /// The "g" policy rule to be replaced, policyType "g" is implicitly used. + /// The "g" policy rule to replace the old ones, policyType "g" is implicitly used. /// Succeeds or not. public static bool UpdateNamedGroupingPolicies(this IEnforcer enforcer, string policyType, - IEnumerable> oldRules, IEnumerable> newRules) => - enforcer.InternalUpdatePolicies(PermConstants.Section.RoleSection, policyType, - Policy.ValuesListFrom(oldRules), Policy.ValuesListFrom(newRules)); + IEnumerable> oldValues, IEnumerable> newValues) + { + IPolicyStore policyStore = enforcer.Model.PolicyStoreHolder.PolicyStore; + int requiredCount = policyStore.GetRequiredValuesCount(PermConstants.Section.RoleSection, policyType); + return enforcer.InternalUpdatePolicies(PermConstants.Section.RoleSection, policyType, + Policy.ValuesListFrom(oldValues), Policy.ValuesListFrom(newValues, requiredCount)); + } /// /// Updates a role inheritance rule from the current policy, field filters can be specified. /// /// /// The policy type, can be "g", "g2", "g3", .. - /// The "g" policy rule to be replaced, policyType "g" is implicitly used. - /// The "g" policy rule to replace the old ones, policyType "g" is implicitly used. + /// The "g" policy rule to be replaced, policyType "g" is implicitly used. + /// The "g" policy rule to replace the old ones, policyType "g" is implicitly used. /// Succeeds or not. - public static async Task UpdateNamedGroupingPoliciesAsync(this IEnforcer enforcer, string policyType, - IEnumerable> oldRules, IEnumerable> newRules) => - await enforcer.InternalUpdatePoliciesAsync(PermConstants.Section.RoleSection, policyType, - Policy.ValuesListFrom(oldRules), Policy.ValuesListFrom(newRules)); + public static Task UpdateNamedGroupingPoliciesAsync(this IEnforcer enforcer, string policyType, + IEnumerable> oldValues, IEnumerable> newValues) + { + IPolicyStore policyStore = enforcer.Model.PolicyStoreHolder.PolicyStore; + int requiredCount = policyStore.GetRequiredValuesCount(PermConstants.Section.RoleSection, policyType); + return enforcer.InternalUpdatePoliciesAsync(PermConstants.Section.RoleSection, policyType, + Policy.ValuesListFrom(oldValues), Policy.ValuesListFrom(newValues, requiredCount)); + } #endregion @@ -1170,57 +1188,49 @@ await enforcer.InternalUpdatePoliciesAsync(PermConstants.Section.RoleSection, po /// Removes a role inheritance rule from the current policy. /// /// - /// The "g" policy rule, policyType "g" is implicitly used. + /// The "g" policy rule, policyType "g" is implicitly used. /// Succeeds or not. - public static bool RemoveGroupingPolicy(this IEnforcer enforcer, params string[] parameters) - { - return RemoveGroupingPolicy(enforcer, parameters as IEnumerable); - } + public static bool RemoveGroupingPolicy(this IEnforcer enforcer, IEnumerable values) => + enforcer.RemoveGroupingPolicy(values as string[] ?? values.ToArray()); /// - /// Removes a role inheritance rule from the current policy. + /// Removes a role inheritance rule from the current policy. /// /// - /// The "g" policy rule, policyType "g" is implicitly used. + /// The "g" policy rule, policyType "g" is implicitly used. /// Succeeds or not. - public static Task RemoveGroupingPolicyAsync(this IEnforcer enforcer, params string[] parameters) - { - return RemoveGroupingPolicyAsync(enforcer, parameters as IEnumerable); - } + public static bool RemoveGroupingPolicy(this IEnforcer enforcer, params string[] values) => + enforcer.RemoveNamedGroupingPolicy(PermConstants.DefaultGroupingPolicyType, values); /// /// Removes a role inheritance rule from the current policy. /// /// - /// The "g" policy rule, policyType "g" is implicitly used. + /// The "g" policy rule, policyType "g" is implicitly used. /// Succeeds or not. - public static bool RemoveGroupingPolicy(this IEnforcer enforcer, IEnumerable parameters) - { - return RemoveNamedGroupingPolicy(enforcer, PermConstants.DefaultGroupingPolicyType, parameters); - } + public static Task RemoveGroupingPolicyAsync(this IEnforcer enforcer, IEnumerable values) => + enforcer.RemoveGroupingPolicyAsync(values as string[] ?? values.ToArray()); /// - /// Removes a role inheritance rule from the current policy. + /// Removes a role inheritance rule from the current policy. /// /// - /// The "g" policy rule, policyType "g" is implicitly used. + /// The "g" policy rule, policyType "g" is implicitly used. /// Succeeds or not. - public static Task RemoveGroupingPolicyAsync(this IEnforcer enforcer, IEnumerable parameters) - { - return RemoveNamedGroupingPolicyAsync(enforcer, PermConstants.DefaultGroupingPolicyType, parameters); - } + public static Task RemoveGroupingPolicyAsync(this IEnforcer enforcer, params string[] values) => + enforcer.RemoveNamedGroupingPolicyAsync(PermConstants.DefaultGroupingPolicyType, values); /// - /// Removes a role inheritance rule from the current - /// policy, field filters can be specified. + /// Removes a role inheritance rule from the current + /// policy, field filters can be specified. /// /// /// The policy type, can be "g", "g2", "g3", .. - /// The "g" policy rule, policyType "g" is implicitly used. + /// The "g" policy rule, policyType "g" is implicitly used. /// Succeeds or not. public static bool RemoveNamedGroupingPolicy(this IEnforcer enforcer, string policyType, - params string[] parameters) => - RemoveNamedGroupingPolicy(enforcer, policyType, parameters as IEnumerable); + IEnumerable values) => + enforcer.RemoveNamedGroupingPolicy(policyType, values as string[] ?? values.ToArray()); /// /// Removes a role inheritance rule from the current @@ -1228,24 +1238,28 @@ public static bool RemoveNamedGroupingPolicy(this IEnforcer enforcer, string pol /// /// /// The policy type, can be "g", "g2", "g3", .. - /// The "g" policy rule, policyType "g" is implicitly used. + /// The "g" policy rule, policyType "g" is implicitly used. /// Succeeds or not. - public static Task RemoveNamedGroupingPolicyAsync(this IEnforcer enforcer, string policyType, - params string[] parameters) => - RemoveNamedGroupingPolicyAsync(enforcer, policyType, parameters as IEnumerable); + public static bool RemoveNamedGroupingPolicy(this IEnforcer enforcer, string policyType, + params string[] values) + { + IPolicyStore policyStore = enforcer.Model.PolicyStoreHolder.PolicyStore; + int requiredCount = policyStore.GetRequiredValuesCount(PermConstants.Section.RoleSection, policyType); + return enforcer.InternalRemovePolicy(PermConstants.Section.RoleSection, policyType, + Policy.ValuesFrom(values, requiredCount)); + } /// - /// Removes a role inheritance rule from the current - /// policy, field filters can be specified. + /// Removes a role inheritance rule from the current + /// policy, field filters can be specified. /// /// /// The policy type, can be "g", "g2", "g3", .. - /// The "g" policy rule, policyType "g" is implicitly used. + /// The "g" policy rule, policyType "g" is implicitly used. /// Succeeds or not. - public static bool RemoveNamedGroupingPolicy(this IEnforcer enforcer, string policyType, - IEnumerable parameters) => - enforcer.InternalRemovePolicy(PermConstants.Section.RoleSection, policyType, - Policy.ValuesFrom(parameters)); + public static Task RemoveNamedGroupingPolicyAsync(this IEnforcer enforcer, string policyType, + IEnumerable values) => + enforcer.RemoveNamedGroupingPolicyAsync(policyType, values as string[] ?? values.ToArray()); /// /// Removes a role inheritance rule from the current @@ -1253,35 +1267,36 @@ public static bool RemoveNamedGroupingPolicy(this IEnforcer enforcer, string pol /// /// /// The policy type, can be "g", "g2", "g3", .. - /// The "g" policy rule, policyType "g" is implicitly used. + /// The "g" policy rule, policyType "g" is implicitly used. /// Succeeds or not. - public static async Task RemoveNamedGroupingPolicyAsync(this IEnforcer enforcer, string policyType, - IEnumerable parameters) => - await enforcer.InternalRemovePolicyAsync(PermConstants.Section.RoleSection, policyType, - Policy.ValuesFrom(parameters)); + public static Task RemoveNamedGroupingPolicyAsync(this IEnforcer enforcer, string policyType, + params string[] values) + { + IPolicyStore policyStore = enforcer.Model.PolicyStoreHolder.PolicyStore; + int requiredCount = policyStore.GetRequiredValuesCount(PermConstants.Section.RoleSection, policyType); + return enforcer.InternalRemovePolicyAsync(PermConstants.Section.RoleSection, policyType, + Policy.ValuesFrom(values, requiredCount)); + } /// /// Removes roles inheritance rule from the current policy. /// /// - /// The "g" policy rule, policyType "g" is implicitly used. + /// The "g" policy rule, policyType "g" is implicitly used. /// Succeeds or not. - public static bool RemoveGroupingPolicies(this IEnforcer enforcer, IEnumerable> rules) - { - return RemoveNamedGroupingPolicies(enforcer, PermConstants.DefaultGroupingPolicyType, rules); - } + public static bool RemoveGroupingPolicies(this IEnforcer enforcer, + IEnumerable> valuesList) => + enforcer.RemoveNamedGroupingPolicies(PermConstants.DefaultGroupingPolicyType, valuesList); /// /// Removes roles inheritance rule from the current policy. /// /// - /// The "g" policy rule, policyType "g" is implicitly used. + /// The "g" policy rule, policyType "g" is implicitly used. /// Succeeds or not. public static Task RemoveGroupingPoliciesAsync(this IEnforcer enforcer, - IEnumerable> rules) - { - return RemoveNamedGroupingPoliciesAsync(enforcer, PermConstants.DefaultGroupingPolicyType, rules); - } + IEnumerable> valuesList) => + enforcer.RemoveNamedGroupingPoliciesAsync(PermConstants.DefaultGroupingPolicyType, valuesList); /// /// Removes roles inheritance rule from the current @@ -1289,12 +1304,16 @@ public static Task RemoveGroupingPoliciesAsync(this IEnforcer enforcer, /// /// /// The policy type, can be "g", "g2", "g3", .. - /// The "g" policy rule, policyType "g" is implicitly used. + /// The "g" policy rule, policyType "g" is implicitly used. /// Succeeds or not. public static bool RemoveNamedGroupingPolicies(this IEnforcer enforcer, string policyType, - IEnumerable> rules) => - enforcer.InternalRemovePolicies(PermConstants.Section.RoleSection, policyType, - Policy.ValuesListFrom(rules)); + IEnumerable> valuesList) + { + IPolicyStore policyStore = enforcer.Model.PolicyStoreHolder.PolicyStore; + int requiredCount = policyStore.GetRequiredValuesCount(PermConstants.Section.RoleSection, policyType); + return enforcer.InternalRemovePolicies(PermConstants.Section.RoleSection, policyType, + Policy.ValuesListFrom(valuesList, requiredCount)); + } /// /// Removes roles inheritance rule from the current @@ -1302,12 +1321,16 @@ public static bool RemoveNamedGroupingPolicies(this IEnforcer enforcer, string p /// /// /// The policy type, can be "g", "g2", "g3", .. - /// The "g" policy rule, policyType "g" is implicitly used. + /// The "g" policy rule, policyType "g" is implicitly used. /// Succeeds or not. - public static async Task RemoveNamedGroupingPoliciesAsync(this IEnforcer enforcer, string policyType, - IEnumerable> rules) => - await enforcer.InternalRemovePoliciesAsync(PermConstants.Section.RoleSection, policyType, - Policy.ValuesListFrom(rules)); + public static Task RemoveNamedGroupingPoliciesAsync(this IEnforcer enforcer, string policyType, + IEnumerable> valuesList) + { + IPolicyStore policyStore = enforcer.Model.PolicyStoreHolder.PolicyStore; + int requiredCount = policyStore.GetRequiredValuesCount(PermConstants.Section.RoleSection, policyType); + return enforcer.InternalRemovePoliciesAsync(PermConstants.Section.RoleSection, policyType, + Policy.ValuesListFrom(valuesList, requiredCount)); + } /// /// Removes a role inheritance rule from the current @@ -1319,7 +1342,7 @@ await enforcer.InternalRemovePoliciesAsync(PermConstants.Section.RoleSection, po /// Succeeds or not. public static bool RemoveFilteredGroupingPolicy(this IEnforcer enforcer, int fieldIndex, params string[] fieldValues) => - RemoveFilteredNamedGroupingPolicy(enforcer, PermConstants.DefaultGroupingPolicyType, fieldIndex, + enforcer.RemoveFilteredNamedGroupingPolicy(PermConstants.DefaultGroupingPolicyType, fieldIndex, fieldValues); /// @@ -1332,7 +1355,7 @@ public static bool RemoveFilteredGroupingPolicy(this IEnforcer enforcer, int fie /// Succeeds or not. public static Task RemoveFilteredGroupingPolicyAsync(this IEnforcer enforcer, int fieldIndex, params string[] fieldValues) => - RemoveFilteredNamedGroupingPolicyAsync(enforcer, PermConstants.DefaultGroupingPolicyType, fieldIndex, + enforcer.RemoveFilteredNamedGroupingPolicyAsync(PermConstants.DefaultGroupingPolicyType, fieldIndex, fieldValues); /// @@ -1356,11 +1379,10 @@ public static bool RemoveFilteredNamedGroupingPolicy(this IEnforcer enforcer, st /// The policy rule's start index to be matched. /// The field values to be matched, value "" means not to match this field. /// Succeeds or not. - public static async Task RemoveFilteredNamedGroupingPolicyAsync(this IEnforcer enforcer, - string policyType, - int fieldIndex, params string[] fieldValues) => - await enforcer.InternalRemoveFilteredPolicyAsync(PermConstants.Section.RoleSection, policyType, - fieldIndex, Policy.ValuesFrom(fieldValues)); + public static Task RemoveFilteredNamedGroupingPolicyAsync(this IEnforcer enforcer, + string policyType, int fieldIndex, params string[] fieldValues) => + enforcer.InternalRemoveFilteredPolicyAsync(PermConstants.Section.RoleSection, policyType, fieldIndex, + Policy.ValuesFrom(fieldValues)); #endregion diff --git a/Casbin/Extensions/ListExtension.cs b/Casbin/Extensions/ListExtension.cs new file mode 100644 index 0000000..d58768c --- /dev/null +++ b/Casbin/Extensions/ListExtension.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; + +namespace Casbin; + +internal static class ListExtension +{ + internal static bool TryGetValue(this IReadOnlyList list, int index, out T value) + { + if (index < 0 || index >= list.Count) + { + value = default; + return false; + } + + value = list[index]; + return true; + } + + internal static T GetValueOrDefault(this IReadOnlyList list, int index) => + list.TryGetValue(index, out T value) ? value : default; +} diff --git a/Casbin/Model/DefaultPolicyStore.Node.cs b/Casbin/Model/DefaultPolicyStore.Node.cs index 104e6a1..8c469e3 100644 --- a/Casbin/Model/DefaultPolicyStore.Node.cs +++ b/Casbin/Model/DefaultPolicyStore.Node.cs @@ -14,15 +14,7 @@ internal class Node public Node(PolicyAssertion assertion) => _assertion = assertion; public HashSet PolicyTextSet { get; } = new(); public ReaderWriterLockSlim Lock { get; } = new(); - - public void RefreshPolicyStringSet() - { - PolicyTextSet.Clear(); - foreach (IPolicyValues policy in GetPolicy()) - { - PolicyTextSet.Add(policy.ToText()); - } - } + public int RequiredValuesCount => _assertion.Tokens.Count; public Iterator Iterate() => new(this); @@ -48,10 +40,10 @@ public bool ValidatePolicy(IPolicyValues values) { if (_assertion.Section is PermConstants.Section.RoleSection) { - return _assertion.Tokens.Count <= values.Count; + return RequiredValuesCount <= values.Count; } - return _assertion.Tokens.Count == values.Count; + return RequiredValuesCount == values.Count; } public bool TryAddPolicy(IPolicyValues values) diff --git a/Casbin/Model/DefaultPolicyStore.cs b/Casbin/Model/DefaultPolicyStore.cs index 570b8ba..71d4377 100644 --- a/Casbin/Model/DefaultPolicyStore.cs +++ b/Casbin/Model/DefaultPolicyStore.cs @@ -34,6 +34,21 @@ public bool AddNode(string section, string type, PolicyAssertion policyAssertion public bool ContainsNode(string section, string policyType) => _nodesMap.TryGetValue(section, out IDictionary nodes) && nodes.ContainsKey(policyType); + public int GetRequiredValuesCount(string section, string policyType) => + GetNode(section, policyType).RequiredValuesCount; + + public bool ValidatePolicy(string section, string policyType, IPolicyValues values) + { + Node node = GetNode(section, policyType); + return node.ValidatePolicy(values); + } + + public bool ValidatePolicies(string section, string policyType, IReadOnlyList valuesList) + { + Node node = GetNode(section, policyType); + return valuesList.Count == 0 || valuesList.All(node.ValidatePolicy); + } + public PolicyScanner Scan(string section, string policyType) => new(GetNode(section, policyType).Iterate()); @@ -45,11 +60,12 @@ public IEnumerable GetPolicyTypes(string section) public IDictionary> GetPolicyTypesAllSections() { - Dictionary> res = new Dictionary>(); + Dictionary> res = new(); foreach (var keyValuePair in _nodesMap) { res.Add(keyValuePair.Key, keyValuePair.Value.Select(x => x.Key)); } + return res; } diff --git a/Casbin/Model/Policy.cs b/Casbin/Model/Policy.cs index cae8942..6403765 100644 --- a/Casbin/Model/Policy.cs +++ b/Casbin/Model/Policy.cs @@ -20,128 +20,135 @@ public static PolicyValues CreateValues(T1 value1, T2 va new(value1, value2, value3); public static PolicyValues - CreateValues(T1 value1, T2 value2, T3 value3, T4 value4) => - new(value1, value2, value3, value4); + CreateValues(T1 value1, T2 value2, T3 value3, T4 value4) => new(value1, value2, value3, value4); public static PolicyValues CreateValues(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5) => new(value1, value2, value3, value4, value5); public static PolicyValues CreateValues(T1 value1, T2 value2, - T3 value3, - T4 value4, T5 value5, T6 value6) => new(value1, value2, value3, value4, value5, value6); + T3 value3, T4 value4, T5 value5, T6 value6) => new(value1, value2, value3, value4, value5, value6); public static PolicyValues CreateValues(T1 value1, - T2 value2, - T3 value3, T4 value4, T5 value5, T6 value6, T7 value7) => + T2 value2, T3 value3, T4 value4, T5 value5, T6 value6, T7 value7) => new(value1, value2, value3, value4, value5, value6, value7); public static PolicyValues CreateValues(T1 value1, - T2 value2, - T3 value3, - T4 value4, T5 value5, T6 value6, T7 value7, T8 value8) => - new(value1, value2, value3, value4, value5, value6, value7, - value8); + T2 value2, T3 value3, T4 value4, T5 value5, T6 value6, T7 value7, T8 value8) => + new(value1, value2, value3, value4, value5, value6, value7, value8); public static PolicyValues CreateValues( - T1 value1, - T2 value2, T3 value3, - T4 value4, T5 value5, T6 value6, T7 value7, T8 value8, T9 value9) => - new(value1, value2, value3, value4, value5, value6, value7, - value8, value9); - - public static PolicyValues CreateValues( - T1 value1, T2 value2, T3 value3, - T4 value4, T5 value5, T6 value6, T7 value7, T8 value8, T9 value9, T10 value10) => - new(value1, value2, value3, value4, value5, value6, - value7, value8, value9, value10); - - public static PolicyValues CreateValues(T1 value1, T2 value2, T3 value3, - T4 value4, T5 value5, T6 value6, T7 value7, T8 value8, T9 value9, T10 value10, T11 value11) => - new(value1, value2, value3, value4, value5, value6, - value7, value8, value9, value10, value11); - - public static PolicyValues CreateValues(T1 value1, T2 value2, T3 value3, - T4 value4, T5 value5, T6 value6, T7 value7, T8 value8, T9 value9, T10 value10, T11 value11, T12 value12) => - new(value1, value2, value3, value4, value5, - value6, value7, value8, value9, value10, value11, value12); - - - internal static PolicyValues CreateValues(IReadOnlyList values, string value1) - => new(PolicyValues.ToText(values), value1, value1); - - internal static PolicyValues CreateValues(IReadOnlyList values, string value1, - string value2) - => new(PolicyValues.ToText(values), value1, value1, value2, value2); - - internal static PolicyValues CreateValues(IReadOnlyList values, string value1, - string value2, string value3) - => new(PolicyValues.ToText(values), value1, value1, value2, value2, value3, value3); - - internal static PolicyValues CreateValues(IReadOnlyList values, - string value1, - string value2, string value3, string value4) - => new(PolicyValues.ToText(values), value1, value1, value2, value2, value3, value3, value4, value4); - - internal static PolicyValues CreateValues(IReadOnlyList values, - string value1, string value2, string value3, string value4, string value5) - => new(PolicyValues.ToText(values), value1, value1, value2, value2, value3, value3, value4, value4, value5, - value5); - - internal static PolicyValues CreateValues( - IReadOnlyList values, - string value1, string value2, string value3, string value4, string value5, string value6) - => new(PolicyValues.ToText(values), value1, value1, value2, value2, value3, value3, value4, value4, value5, - value5, value6, - value6); - - internal static PolicyValues CreateValues( - IReadOnlyList values, string value1, string value2, string value3, string value4, string value5, - string value6, string value7) - => new(PolicyValues.ToText(values), value1, value1, value2, value2, value3, value3, value4, value4, value5, - value5, value6, - value6, value7, value7); + T1 value1, T2 value2, T3 value3, T4 value4, T5 value5, T6 value6, T7 value7, T8 value8, T9 value9) => + new(value1, value2, value3, value4, value5, value6, value7, value8, value9); + + public static PolicyValues + CreateValues(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5, + T6 value6, T7 value7, T8 value8, T9 value9, T10 value10) => + new(value1, value2, value3, value4, value5, value6, value7, value8, value9, value10); + + public static PolicyValues + CreateValues(T1 value1, T2 value2, T3 value3, T4 value4, + T5 value5, T6 value6, T7 value7, T8 value8, T9 value9, T10 value10, T11 value11) => + new(value1, value2, value3, value4, value5, value6, value7, value8, value9, value10, value11); + + public static PolicyValues + CreateValues(T1 value1, T2 value2, T3 value3, T4 value4, + T5 value5, T6 value6, T7 value7, T8 value8, T9 value9, T10 value10, T11 value11, T12 value12) => + new(value1, value2, value3, value4, value5, value6, value7, value8, value9, value10, value11, value12); public static IPolicyValues ValuesFrom(IReadOnlyList values) { return values.Count switch { - 1 => CreateValues(values, values[0]), - 2 => CreateValues(values, values[0], values[1]), - 3 => CreateValues(values, values[0], values[1], values[2]), - 4 => CreateValues(values, values[0], values[1], values[2], values[3]), - 5 => CreateValues(values, values[0], values[1], values[2], values[3], values[4]), - 6 => CreateValues(values, values[0], values[1], values[2], values[3], values[4], values[5]), - 7 => CreateValues(values, values[0], values[1], values[2], values[3], values[4], values[5], values[6]), - 8 => CreateValues(values[0], values[1], values[2], values[3], - values[4], values[5], values[6], values[7]), - 9 => CreateValues(values[0], values[1], values[2], values[3], - values[4], values[5], values[6], values[7], values[8]), - 10 => CreateValues(values[0], values[1], values[2], values[3], - values[4], values[5], values[6], values[7], values[8], - values[9]), - 11 => CreateValues(values[0], values[1], values[2], values[3], - values[4], values[5], values[6], values[7], values[8], - values[9], values[10]), - 12 => CreateValues(values[0], values[1], values[2], values[3], - values[4], values[5], values[6], values[7], values[8], - values[9], values[10], values[11]), + 1 => CreateValues(values[0] ?? string.Empty), + 2 => CreateValues(values[0] ?? string.Empty, values[1] ?? string.Empty), + 3 => CreateValues(values[0] ?? string.Empty, values[1] ?? string.Empty, values[2] ?? string.Empty), + 4 => CreateValues(values[0] ?? string.Empty, values[1] ?? string.Empty, values[2] ?? string.Empty, + values[3] ?? string.Empty), + 5 => CreateValues(values[0] ?? string.Empty, values[1] ?? string.Empty, values[2] ?? string.Empty, + values[3] ?? string.Empty, values[4] ?? string.Empty), + 6 => CreateValues(values[0] ?? string.Empty, values[1] ?? string.Empty, values[2] ?? string.Empty, + values[3] ?? string.Empty, values[4] ?? string.Empty, values[5] ?? string.Empty), + 7 => CreateValues(values[0] ?? string.Empty, values[1] ?? string.Empty, values[2] ?? string.Empty, + values[3] ?? string.Empty, values[4] ?? string.Empty, values[5] ?? string.Empty, + values[6] ?? string.Empty), + 8 => CreateValues(values[0] ?? string.Empty, values[1] ?? string.Empty, values[2] ?? string.Empty, + values[3] ?? string.Empty, values[4] ?? string.Empty, values[5] ?? string.Empty, + values[6] ?? string.Empty, values[7] ?? string.Empty), + 9 => CreateValues(values[0] ?? string.Empty, values[1] ?? string.Empty, values[2] ?? string.Empty, + values[3] ?? string.Empty, values[4] ?? string.Empty, values[5] ?? string.Empty, + values[6] ?? string.Empty, values[7] ?? string.Empty, values[8] ?? string.Empty), + 10 => CreateValues(values[0] ?? string.Empty, values[1] ?? string.Empty, values[2] ?? string.Empty, + values[3] ?? string.Empty, values[4] ?? string.Empty, values[5] ?? string.Empty, + values[6] ?? string.Empty, values[7] ?? string.Empty, values[8] ?? string.Empty, + values[9] ?? string.Empty), + 11 => CreateValues(values[0] ?? string.Empty, values[1] ?? string.Empty, values[2] ?? string.Empty, + values[3] ?? string.Empty, values[4] ?? string.Empty, values[5] ?? string.Empty, + values[6] ?? string.Empty, values[7] ?? string.Empty, values[8] ?? string.Empty, + values[9] ?? string.Empty, values[10] ?? string.Empty), + 12 => CreateValues(values[0] ?? string.Empty, values[1] ?? string.Empty, values[2] ?? string.Empty, + values[3] ?? string.Empty, values[4] ?? string.Empty, values[5] ?? string.Empty, + values[6] ?? string.Empty, values[7] ?? string.Empty, values[8] ?? string.Empty, + values[9] ?? string.Empty, values[10] ?? string.Empty, values[11] ?? string.Empty), _ => new StringListPolicyValues(values) }; } + public static IPolicyValues ValuesFrom(IReadOnlyList values, int requiredCount) => + requiredCount switch + { + 1 => CreateValues(values.GetValueOrDefault(0) ?? string.Empty), + 2 => CreateValues(values.GetValueOrDefault(0) ?? string.Empty, values.GetValueOrDefault(1) ?? string.Empty), + 3 => CreateValues(values.GetValueOrDefault(0) ?? string.Empty, values.GetValueOrDefault(1) ?? string.Empty, + values.GetValueOrDefault(2) ?? string.Empty), + 4 => CreateValues(values.GetValueOrDefault(0) ?? string.Empty, values.GetValueOrDefault(1) ?? string.Empty, + values.GetValueOrDefault(2) ?? string.Empty, values.GetValueOrDefault(3) ?? string.Empty), + 5 => CreateValues(values.GetValueOrDefault(0) ?? string.Empty, values.GetValueOrDefault(1) ?? string.Empty, + values.GetValueOrDefault(2) ?? string.Empty, values.GetValueOrDefault(3) ?? string.Empty, + values.GetValueOrDefault(4) ?? string.Empty), + 6 => CreateValues(values.GetValueOrDefault(0) ?? string.Empty, values.GetValueOrDefault(1) ?? string.Empty, + values.GetValueOrDefault(2) ?? string.Empty, values.GetValueOrDefault(3) ?? string.Empty, + values.GetValueOrDefault(4) ?? string.Empty, values.GetValueOrDefault(5) ?? string.Empty), + 7 => CreateValues(values.GetValueOrDefault(0) ?? string.Empty, values.GetValueOrDefault(1) ?? string.Empty, + values.GetValueOrDefault(2) ?? string.Empty, values.GetValueOrDefault(3) ?? string.Empty, + values.GetValueOrDefault(4) ?? string.Empty, values.GetValueOrDefault(5) ?? string.Empty, + values.GetValueOrDefault(6) ?? string.Empty), + 8 => CreateValues(values.GetValueOrDefault(0) ?? string.Empty, values.GetValueOrDefault(1) ?? string.Empty, + values.GetValueOrDefault(2) ?? string.Empty, values.GetValueOrDefault(3) ?? string.Empty, + values.GetValueOrDefault(4) ?? string.Empty, values.GetValueOrDefault(5) ?? string.Empty, + values.GetValueOrDefault(6) ?? string.Empty, values.GetValueOrDefault(7) ?? string.Empty), + 9 => CreateValues(values.GetValueOrDefault(0) ?? string.Empty, values.GetValueOrDefault(1) ?? string.Empty, + values.GetValueOrDefault(2) ?? string.Empty, values.GetValueOrDefault(3) ?? string.Empty, + values.GetValueOrDefault(4) ?? string.Empty, values.GetValueOrDefault(5) ?? string.Empty, + values.GetValueOrDefault(6) ?? string.Empty, values.GetValueOrDefault(7) ?? string.Empty, + values.GetValueOrDefault(8) ?? string.Empty), + 10 => CreateValues(values.GetValueOrDefault(0) ?? string.Empty, values.GetValueOrDefault(1) ?? string.Empty, + values.GetValueOrDefault(2) ?? string.Empty, values.GetValueOrDefault(3) ?? string.Empty, + values.GetValueOrDefault(4) ?? string.Empty, values.GetValueOrDefault(5) ?? string.Empty, + values.GetValueOrDefault(6) ?? string.Empty, values.GetValueOrDefault(7) ?? string.Empty, + values.GetValueOrDefault(8) ?? string.Empty, values.GetValueOrDefault(9) ?? string.Empty), + 11 => CreateValues(values.GetValueOrDefault(0) ?? string.Empty, values.GetValueOrDefault(1) ?? string.Empty, + values.GetValueOrDefault(2) ?? string.Empty, values.GetValueOrDefault(3) ?? string.Empty, + values.GetValueOrDefault(4) ?? string.Empty, values.GetValueOrDefault(5) ?? string.Empty, + values.GetValueOrDefault(6) ?? string.Empty, values.GetValueOrDefault(7) ?? string.Empty, + values.GetValueOrDefault(8) ?? string.Empty, values.GetValueOrDefault(9) ?? string.Empty, + values.GetValueOrDefault(10) ?? string.Empty), + 12 => CreateValues(values.GetValueOrDefault(0) ?? string.Empty, values.GetValueOrDefault(1) ?? string.Empty, + values.GetValueOrDefault(2) ?? string.Empty, values.GetValueOrDefault(3) ?? string.Empty, + values.GetValueOrDefault(4) ?? string.Empty, values.GetValueOrDefault(5) ?? string.Empty, + values.GetValueOrDefault(6) ?? string.Empty, values.GetValueOrDefault(7) ?? string.Empty, + values.GetValueOrDefault(8) ?? string.Empty, values.GetValueOrDefault(9) ?? string.Empty, + values.GetValueOrDefault(10) ?? string.Empty, values.GetValueOrDefault(11) ?? string.Empty), + _ => new StringListPolicyValues(values, requiredCount) + }; + public static IPolicyValues ValuesFrom(IEnumerable values) => ValuesFrom(values as IReadOnlyList ?? values.ToArray()); + public static IPolicyValues ValuesFrom(IEnumerable values, int requiredCount) => + ValuesFrom(values as IReadOnlyList ?? values.ToArray(), requiredCount); + public static IPolicyValues ValuesFrom(IPersistPolicy values) { - // Find the latest not empty value as the count. int count; if (string.IsNullOrWhiteSpace(values.Value12) is false) { @@ -218,15 +225,62 @@ public static IPolicyValues ValuesFrom(IPersistPolicy values) 12 => CreateValues(values.Value1, values.Value2, values.Value3, values.Value4, values.Value5, values.Value6, values.Value7, values.Value8, values.Value9, values.Value10, values.Value11, values.Value12), - _ => throw new ArgumentOutOfRangeException(nameof(count), count, null) + _ => throw new ArgumentOutOfRangeException(nameof(count), count, "Count must be between 1 and 12.") + }; + } + + public static IPolicyValues ValuesFrom(IPersistPolicy values, int requiredCount) => + requiredCount switch + { + 1 => CreateValues(values.Value1 ?? string.Empty), + 2 => CreateValues(values.Value1 ?? string.Empty, values.Value2 ?? string.Empty), + 3 => CreateValues(values.Value1 ?? string.Empty, values.Value2 ?? string.Empty, + values.Value3 ?? string.Empty), + 4 => CreateValues(values.Value1 ?? string.Empty, values.Value2 ?? string.Empty, + values.Value3 ?? string.Empty, values.Value4 ?? string.Empty), + 5 => CreateValues(values.Value1 ?? string.Empty, values.Value2 ?? string.Empty, + values.Value3 ?? string.Empty, values.Value4 ?? string.Empty, values.Value5 ?? string.Empty), + 6 => CreateValues(values.Value1 ?? string.Empty, values.Value2 ?? string.Empty, + values.Value3 ?? string.Empty, values.Value4 ?? string.Empty, values.Value5 ?? string.Empty, + values.Value6 ?? string.Empty), + 7 => CreateValues(values.Value1 ?? string.Empty, values.Value2 ?? string.Empty, + values.Value3 ?? string.Empty, values.Value4 ?? string.Empty, values.Value5 ?? string.Empty, + values.Value6 ?? string.Empty, values.Value7 ?? string.Empty), + 8 => CreateValues(values.Value1 ?? string.Empty, values.Value2 ?? string.Empty, + values.Value3 ?? string.Empty, values.Value4 ?? string.Empty, values.Value5 ?? string.Empty, + values.Value6 ?? string.Empty, values.Value7 ?? string.Empty, values.Value8 ?? string.Empty), + 9 => CreateValues(values.Value1 ?? string.Empty, values.Value2 ?? string.Empty, + values.Value3 ?? string.Empty, values.Value4 ?? string.Empty, values.Value5 ?? string.Empty, + values.Value6 ?? string.Empty, values.Value7 ?? string.Empty, values.Value8 ?? string.Empty, + values.Value9 ?? string.Empty), + 10 => CreateValues(values.Value1 ?? string.Empty, values.Value2 ?? string.Empty, + values.Value3 ?? string.Empty, values.Value4 ?? string.Empty, values.Value5 ?? string.Empty, + values.Value6 ?? string.Empty, values.Value7 ?? string.Empty, values.Value8 ?? string.Empty, + values.Value9 ?? string.Empty, values.Value10 ?? string.Empty), + 11 => CreateValues(values.Value1 ?? string.Empty, values.Value2 ?? string.Empty, + values.Value3 ?? string.Empty, values.Value4 ?? string.Empty, values.Value5 ?? string.Empty, + values.Value6 ?? string.Empty, values.Value7 ?? string.Empty, values.Value8 ?? string.Empty, + values.Value9 ?? string.Empty, values.Value10 ?? string.Empty, + values.Value11 ?? string.Empty), + 12 => CreateValues(values.Value1 ?? string.Empty, values.Value2 ?? string.Empty, + values.Value3 ?? string.Empty, values.Value4 ?? string.Empty, values.Value5 ?? string.Empty, + values.Value6 ?? string.Empty, values.Value7 ?? string.Empty, values.Value8 ?? string.Empty, + values.Value9 ?? string.Empty, values.Value10 ?? string.Empty, + values.Value11 ?? string.Empty, values.Value12 ?? string.Empty), + _ => throw new ArgumentOutOfRangeException(nameof(requiredCount), requiredCount, + "Required count must be between 1 and 12.") }; + + public static IReadOnlyList ValuesListFrom(IEnumerable> valuesList) + { + IEnumerable policies = valuesList.Select(values => ValuesFrom(values)); + return policies as IReadOnlyList ?? policies.ToArray(); } - public static IReadOnlyList ValuesListFrom(IEnumerable> rules) + public static IReadOnlyList ValuesListFrom(IEnumerable> valuesList, + int requiredCount) { - IEnumerable policies = rules.Select(ValuesFrom); + IEnumerable policies = valuesList.Select(values => ValuesFrom(values, requiredCount)); return policies as IReadOnlyList ?? policies.ToArray(); } } - - diff --git a/Casbin/Model/PolicyValues.cs b/Casbin/Model/PolicyValues.cs index fd4eea4..cc38277 100644 --- a/Casbin/Model/PolicyValues.cs +++ b/Casbin/Model/PolicyValues.cs @@ -6,38 +6,31 @@ namespace Casbin.Model; public record PolicyValues : IPolicyValues { - protected string Text; + private string _text; public static PolicyValues Empty { get; } = new(); public virtual int Count => 0; public virtual string this[int index] => throw new ArgumentOutOfRangeException(nameof(index)); public virtual IEnumerator GetEnumerator() => new PolicyEnumerator(this); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public string ToText() => Text ??= ToText((IEnumerable)this); + public string ToText() => _text ??= ToText(this); public bool Equals(IPolicyValues other) => Equals(this, other); internal static string ToText(T values) where T : IPolicyValues => string.Join(PermConstants.PolicySeparatorString, values); - internal static string ToText(IEnumerable values) - => string.Join(PermConstants.PolicySeparatorString, values); - internal static bool Equals(T values, T other) where T : IPolicyValues => values.Count == other.Count && values.ToText().Equals(other.ToText()); - internal static string ToStringValue(T value) => value as string ?? value.ToString(); + internal static string ToStringValue(T value) => + value is not null + ? value as string ?? value.ToString() + : string.Empty; } public record PolicyValues(T1 Value1) : PolicyValues { private string _stringValue1; - - internal PolicyValues(string text, T1 value1, string stringValue1) : this(value1) - { - _stringValue1 = stringValue1; - Text = text; - } - public override int Count => 1; public override string this[int index] => index switch @@ -52,15 +45,6 @@ internal PolicyValues(string text, T1 value1, string stringValue1) : this(value1 public record PolicyValues(T1 Value1, T2 Value2) : PolicyValues { private string _stringValue1, _stringValue2; - - internal PolicyValues(string text, T1 value1, string stringValue1, T2 value2, string stringValue2) : this(value1, - value2) - { - _stringValue1 = stringValue1; - _stringValue2 = stringValue2; - Text = text; - } - public override int Count => 2; public override string this[int index] => index switch @@ -76,16 +60,6 @@ internal PolicyValues(string text, T1 value1, string stringValue1, T2 value2, st public record PolicyValues(T1 Value1, T2 Value2, T3 Value3) : PolicyValues { private string _stringValue1, _stringValue2, _stringValue3; - - internal PolicyValues(string text, T1 value1, string stringValue1, T2 value2, string stringValue2, - T3 value3, string stringValue3) : this(value1, value2, value3) - { - _stringValue1 = stringValue1; - _stringValue2 = stringValue2; - _stringValue3 = stringValue3; - Text = text; - } - public override int Count => 3; public override string this[int index] => index switch @@ -102,17 +76,6 @@ internal PolicyValues(string text, T1 value1, string stringValue1, T2 value2, st public record PolicyValues(T1 Value1, T2 Value2, T3 Value3, T4 Value4) : PolicyValues { private string _stringValue1, _stringValue2, _stringValue3, _stringValue4; - - internal PolicyValues(string text, T1 value1, string stringValue1, T2 value2, string stringValue2, - T3 value3, string stringValue3, T4 value4, string stringValue4) : this(value1, value2, value3, value4) - { - _stringValue1 = stringValue1; - _stringValue2 = stringValue2; - _stringValue3 = stringValue3; - _stringValue4 = stringValue4; - Text = text; - } - public override int Count => 4; public override string this[int index] => index switch @@ -130,19 +93,6 @@ internal PolicyValues(string text, T1 value1, string stringValue1, T2 value2, st public record PolicyValues(T1 Value1, T2 Value2, T3 Value3, T4 Value4, T5 Value5) : PolicyValues { private string _stringValue1, _stringValue2, _stringValue3, _stringValue4, _stringValue5; - - internal PolicyValues(string text, T1 value1, string stringValue1, T2 value2, string stringValue2, - T3 value3, string stringValue3, T4 value4, string stringValue4, T5 value5, string stringValue5) - : this(value1, value2, value3, value4, value5) - { - _stringValue1 = stringValue1; - _stringValue2 = stringValue2; - _stringValue3 = stringValue3; - _stringValue4 = stringValue4; - _stringValue5 = stringValue5; - Text = text; - } - public override int Count => 5; public override string this[int index] => index switch @@ -162,20 +112,6 @@ public record PolicyValues (T1 Value1, T2 Value2, T3 Value3, T4 Value4, T5 Value5, T6 Value6) : PolicyValues { private string _stringValue1, _stringValue2, _stringValue3, _stringValue4, _stringValue5, _stringValue6; - - internal PolicyValues(string text, T1 value1, string stringValue1, T2 value2, string stringValue2, - T3 value3, string stringValue3, T4 value4, string stringValue4, T5 value5, string stringValue5, - T6 value6, string stringValue6) : this(value1, value2, value3, value4, value5, value6) - { - _stringValue1 = stringValue1; - _stringValue2 = stringValue2; - _stringValue3 = stringValue3; - _stringValue4 = stringValue4; - _stringValue5 = stringValue5; - _stringValue6 = stringValue6; - Text = text; - } - public override int Count => 6; public override string this[int index] => index switch @@ -204,21 +140,6 @@ public record PolicyValues(T1 Value1, T2 Value2, T3 _stringValue6, _stringValue7; - internal PolicyValues(string text, T1 value1, string stringValue1, T2 value2, string stringValue2, - T3 value3, string stringValue3, T4 value4, string stringValue4, T5 value5, string stringValue5, - T6 value6, string stringValue6, T7 value7, string stringValue7) : this(value1, value2, value3, value4, value5, - value6, value7) - { - _stringValue1 = stringValue1; - _stringValue2 = stringValue2; - _stringValue3 = stringValue3; - _stringValue4 = stringValue4; - _stringValue5 = stringValue5; - _stringValue6 = stringValue6; - _stringValue7 = stringValue7; - Text = text; - } - public override int Count => 7; public override string this[int index] => index switch @@ -393,11 +314,24 @@ internal record StringListPolicyValues : PolicyValues { private readonly IReadOnlyList _values; - public StringListPolicyValues(IReadOnlyList values) => _values = values; + public StringListPolicyValues(IReadOnlyList values) + { + _values = values; + Count = values.Count; + } + + public StringListPolicyValues(IReadOnlyList values, int requiredCount) + { + _values = values; + Count = requiredCount; + } + + public override int Count { get; } - public override int Count => _values.Count; - public override string this[int index] => _values[index]; - public override IEnumerator GetEnumerator() => _values.GetEnumerator(); + public override string this[int index] => _values.GetValueOrDefault(index); + + public override IEnumerator GetEnumerator() => + new PolicyEnumerator(this); } internal struct PolicyEnumerator : IEnumerator where T : IPolicyValues @@ -421,5 +355,3 @@ public void Dispose() public bool MoveNext() => ++_index < _value.Count; public void Reset() => _index = -1; } - - diff --git a/Casbin/Persist/Adapter/File/FileAdapter.cs b/Casbin/Persist/Adapter/File/FileAdapter.cs index 0f200c4..53605ef 100644 --- a/Casbin/Persist/Adapter/File/FileAdapter.cs +++ b/Casbin/Persist/Adapter/File/FileAdapter.cs @@ -39,7 +39,8 @@ public void LoadPolicy(IPolicyStore store) IEnumerable policies = ReadPersistPolicy(OriginalPath); foreach (IPersistPolicy policy in policies) { - IPolicyValues values = Policy.ValuesFrom(policy); + int requiredCount = store.GetRequiredValuesCount(policy.Section, policy.Type); + IPolicyValues values = Policy.ValuesFrom(policy, requiredCount); store.AddPolicy(policy.Section, policy.Type, values); } } @@ -49,7 +50,8 @@ public void LoadPolicy(IPolicyStore store) IEnumerable policies = ReadPersistPolicy(_inputStream); foreach (IPersistPolicy policy in policies) { - IPolicyValues values = Policy.ValuesFrom(policy); + int requiredCount = store.GetRequiredValuesCount(policy.Section, policy.Type); + IPolicyValues values = Policy.ValuesFrom(policy, requiredCount); store.AddPolicy(policy.Section, policy.Type, values); } } @@ -63,7 +65,8 @@ public async Task LoadPolicyAsync(IPolicyStore store) IAsyncEnumerable policies = ReadPersistPolicyAsync(OriginalPath); await foreach (IPersistPolicy policy in policies) { - IPolicyValues values = Policy.ValuesFrom(policy); + int requiredCount = store.GetRequiredValuesCount(policy.Section, policy.Type); + IPolicyValues values = Policy.ValuesFrom(policy, requiredCount); store.AddPolicy(policy.Section, policy.Type, values); } } @@ -73,7 +76,8 @@ public async Task LoadPolicyAsync(IPolicyStore store) IAsyncEnumerable policies = ReadPersistPolicyAsync(_inputStream); await foreach (IPersistPolicy policy in policies) { - IPolicyValues values = Policy.ValuesFrom(policy); + int requiredCount = store.GetRequiredValuesCount(policy.Section, policy.Type); + IPolicyValues values = Policy.ValuesFrom(policy, requiredCount); store.AddPolicy(policy.Section, policy.Type, values); } } @@ -86,7 +90,8 @@ public async Task LoadPolicyAsync(IPolicyStore store) var policies = await ReadPersistPolicyAsync(OriginalPath); foreach (IPersistPolicy policy in policies) { - IPolicyValues values = Policy.ValuesFrom(policy); + int requiredCount = store.GetRequiredValuesCount(policy.Section, policy.Type); + IPolicyValues values = Policy.ValuesFrom(policy, requiredCount); store.AddPolicy(policy.Section, policy.Type, values); } } @@ -96,7 +101,8 @@ public async Task LoadPolicyAsync(IPolicyStore store) var policies = await ReadPersistPolicyAsync(_inputStream); foreach (IPersistPolicy policy in policies) { - IPolicyValues values = Policy.ValuesFrom(policy); + int requiredCount = store.GetRequiredValuesCount(policy.Section, policy.Type); + IPolicyValues values = Policy.ValuesFrom(policy, requiredCount); store.AddPolicy(policy.Section, policy.Type, values); } } @@ -237,9 +243,9 @@ private void LoadFilteredPolicyFile(IPolicyStore store, IPolicyFilter filter) policies = filter.Apply(policies.AsQueryable()); foreach (IPersistPolicy policy in policies) { - string section = policy.Section; - IPolicyValues values = Policy.ValuesFrom(policy); - store.AddPolicy(section, policy.Type, values); + int requiredCount = store.GetRequiredValuesCount(policy.Section, policy.Type); + IPolicyValues values = Policy.ValuesFrom(policy, requiredCount); + store.AddPolicy(policy.Section, policy.Type, values); } IsFiltered = true; @@ -267,7 +273,7 @@ private static IEnumerable ReadPersistPolicy(string filePath) TrimOptions = TrimOptions.Trim, IgnoreBlankLines = true, BadDataFound = null, - WhiteSpaceChars = new []{' ', '\t'} + WhiteSpaceChars = new[] { ' ', '\t' } }); while (parser.Read()) @@ -295,7 +301,7 @@ private static IEnumerable ReadPersistPolicy(System.IO.Stream st TrimOptions = TrimOptions.Trim, IgnoreBlankLines = true, BadDataFound = null, - WhiteSpaceChars = new []{' ', '\t'} + WhiteSpaceChars = new[] { ' ', '\t' } }); while (parser.Read()) @@ -330,7 +336,7 @@ private static async IAsyncEnumerable ReadPersistPolicyAsync(str TrimOptions = TrimOptions.Trim, IgnoreBlankLines = true, BadDataFound = null, - WhiteSpaceChars = new []{' ', '\t'} + WhiteSpaceChars = new[] { ' ', '\t' } }); while (await parser.ReadAsync()) @@ -391,7 +397,7 @@ private static async IAsyncEnumerable ReadPersistPolicyAsync(Sys TrimOptions = TrimOptions.Trim, IgnoreBlankLines = true, BadDataFound = null, - WhiteSpaceChars = new []{' ', '\t'} + WhiteSpaceChars = new[] { ' ', '\t' } }); while (await parser.ReadAsync()) diff --git a/Casbin/Persist/Adapter/Stream/StreamFilteredAdapter.cs b/Casbin/Persist/Adapter/Stream/StreamFilteredAdapter.cs index 09a5691..96b6461 100644 --- a/Casbin/Persist/Adapter/Stream/StreamFilteredAdapter.cs +++ b/Casbin/Persist/Adapter/Stream/StreamFilteredAdapter.cs @@ -42,9 +42,9 @@ private void LoadFilteredPolicyFile(IPolicyStore store, IPolicyFilter filter) policies = filter.Apply(policies.AsQueryable()); foreach (IPersistPolicy policy in policies) { - string section = policy.Section; - IPolicyValues values = Policy.ValuesFrom(policy); - store.AddPolicy(section, policy.Type, values); + int requiredCount = store.GetRequiredValuesCount(policy.Section, policy.Type); + IPolicyValues values = Policy.ValuesFrom(policy, requiredCount); + store.AddPolicy(policy.Section, policy.Type, values); } IsFiltered = true;