diff --git a/Casbin.Benchmark/TestHelper.cs b/Casbin.Benchmark/TestHelper.cs index 95f70c4..83874ba 100644 --- a/Casbin.Benchmark/TestHelper.cs +++ b/Casbin.Benchmark/TestHelper.cs @@ -6,7 +6,7 @@ public static class TestHelper { public static string GetTestFilePath(string fileName) { - return Path.Combine("examples", fileName); + return Path.Combine("Examples", fileName); } } } diff --git a/Casbin.UnitTests/Casbin.UnitTests.csproj b/Casbin.UnitTests/Casbin.UnitTests.csproj index fa89d12..3ada8fd 100644 --- a/Casbin.UnitTests/Casbin.UnitTests.csproj +++ b/Casbin.UnitTests/Casbin.UnitTests.csproj @@ -4,7 +4,7 @@ net9.0;net8.0;net7.0;net6.0;net5.0;netcoreapp3.1;net462;net461;net452 full false - 10.0 + latest false diff --git a/Casbin.UnitTests/examples/abac_comment.conf b/Casbin.UnitTests/Examples/abac_comment.conf similarity index 100% rename from Casbin.UnitTests/examples/abac_comment.conf rename to Casbin.UnitTests/Examples/abac_comment.conf diff --git a/Casbin.UnitTests/examples/abac_model.conf b/Casbin.UnitTests/Examples/abac_model.conf similarity index 100% rename from Casbin.UnitTests/examples/abac_model.conf rename to Casbin.UnitTests/Examples/abac_model.conf diff --git a/Casbin.UnitTests/examples/abac_rule_model.conf b/Casbin.UnitTests/Examples/abac_rule_model.conf similarity index 100% rename from Casbin.UnitTests/examples/abac_rule_model.conf rename to Casbin.UnitTests/Examples/abac_rule_model.conf diff --git a/Casbin.UnitTests/examples/abac_rule_policy.csv b/Casbin.UnitTests/Examples/abac_rule_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/abac_rule_policy.csv rename to Casbin.UnitTests/Examples/abac_rule_policy.csv diff --git a/Casbin.UnitTests/examples/abac_with_dynamic_value_type_model.conf b/Casbin.UnitTests/Examples/abac_with_dynamic_value_type_model.conf similarity index 100% rename from Casbin.UnitTests/examples/abac_with_dynamic_value_type_model.conf rename to Casbin.UnitTests/Examples/abac_with_dynamic_value_type_model.conf diff --git a/Casbin.UnitTests/examples/abac_with_dynamic_value_type_policy.csv b/Casbin.UnitTests/Examples/abac_with_dynamic_value_type_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/abac_with_dynamic_value_type_policy.csv rename to Casbin.UnitTests/Examples/abac_with_dynamic_value_type_policy.csv diff --git a/Casbin.UnitTests/examples/backslash_feed_model.conf b/Casbin.UnitTests/Examples/backslash_feed_model.conf similarity index 100% rename from Casbin.UnitTests/examples/backslash_feed_model.conf rename to Casbin.UnitTests/Examples/backslash_feed_model.conf diff --git a/Casbin.UnitTests/examples/backslash_feed_policy.csv b/Casbin.UnitTests/Examples/backslash_feed_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/backslash_feed_policy.csv rename to Casbin.UnitTests/Examples/backslash_feed_policy.csv diff --git a/Casbin.UnitTests/examples/basic_inverse_policy.csv b/Casbin.UnitTests/Examples/basic_inverse_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/basic_inverse_policy.csv rename to Casbin.UnitTests/Examples/basic_inverse_policy.csv diff --git a/Casbin.UnitTests/examples/basic_model.conf b/Casbin.UnitTests/Examples/basic_model.conf similarity index 100% rename from Casbin.UnitTests/examples/basic_model.conf rename to Casbin.UnitTests/Examples/basic_model.conf diff --git a/Casbin.UnitTests/examples/basic_policy.csv b/Casbin.UnitTests/Examples/basic_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/basic_policy.csv rename to Casbin.UnitTests/Examples/basic_policy.csv diff --git a/Casbin.UnitTests/examples/basic_policy_for_async_adapter_test.csv b/Casbin.UnitTests/Examples/basic_policy_for_async_adapter_test.csv similarity index 100% rename from Casbin.UnitTests/examples/basic_policy_for_async_adapter_test.csv rename to Casbin.UnitTests/Examples/basic_policy_for_async_adapter_test.csv diff --git a/Casbin.UnitTests/examples/basic_with_root_model.conf b/Casbin.UnitTests/Examples/basic_with_root_model.conf similarity index 100% rename from Casbin.UnitTests/examples/basic_with_root_model.conf rename to Casbin.UnitTests/Examples/basic_with_root_model.conf diff --git a/Casbin.UnitTests/examples/basic_without_resources_model.conf b/Casbin.UnitTests/Examples/basic_without_resources_model.conf similarity index 100% rename from Casbin.UnitTests/examples/basic_without_resources_model.conf rename to Casbin.UnitTests/Examples/basic_without_resources_model.conf diff --git a/Casbin.UnitTests/examples/basic_without_resources_policy.csv b/Casbin.UnitTests/Examples/basic_without_resources_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/basic_without_resources_policy.csv rename to Casbin.UnitTests/Examples/basic_without_resources_policy.csv diff --git a/Casbin.UnitTests/examples/basic_without_users_model.conf b/Casbin.UnitTests/Examples/basic_without_users_model.conf similarity index 100% rename from Casbin.UnitTests/examples/basic_without_users_model.conf rename to Casbin.UnitTests/Examples/basic_without_users_model.conf diff --git a/Casbin.UnitTests/examples/basic_without_users_policy.csv b/Casbin.UnitTests/Examples/basic_without_users_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/basic_without_users_policy.csv rename to Casbin.UnitTests/Examples/basic_without_users_policy.csv diff --git a/Casbin.UnitTests/examples/comma_quotations_model.conf b/Casbin.UnitTests/Examples/comma_quotations_model.conf similarity index 100% rename from Casbin.UnitTests/examples/comma_quotations_model.conf rename to Casbin.UnitTests/Examples/comma_quotations_model.conf diff --git a/Casbin.UnitTests/examples/comma_quotations_policy.csv b/Casbin.UnitTests/Examples/comma_quotations_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/comma_quotations_policy.csv rename to Casbin.UnitTests/Examples/comma_quotations_policy.csv diff --git a/Casbin.UnitTests/examples/group_with_domain_model.conf b/Casbin.UnitTests/Examples/group_with_domain_model.conf similarity index 100% rename from Casbin.UnitTests/examples/group_with_domain_model.conf rename to Casbin.UnitTests/Examples/group_with_domain_model.conf diff --git a/Casbin.UnitTests/examples/group_with_domain_policy.csv b/Casbin.UnitTests/Examples/group_with_domain_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/group_with_domain_policy.csv rename to Casbin.UnitTests/Examples/group_with_domain_policy.csv diff --git a/Casbin.UnitTests/examples/ipmatch_model.conf b/Casbin.UnitTests/Examples/ipmatch_model.conf similarity index 100% rename from Casbin.UnitTests/examples/ipmatch_model.conf rename to Casbin.UnitTests/Examples/ipmatch_model.conf diff --git a/Casbin.UnitTests/examples/ipmatch_policy.csv b/Casbin.UnitTests/Examples/ipmatch_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/ipmatch_policy.csv rename to Casbin.UnitTests/Examples/ipmatch_policy.csv diff --git a/Casbin.UnitTests/examples/keymatch2_model.conf b/Casbin.UnitTests/Examples/keymatch2_model.conf similarity index 100% rename from Casbin.UnitTests/examples/keymatch2_model.conf rename to Casbin.UnitTests/Examples/keymatch2_model.conf diff --git a/Casbin.UnitTests/examples/keymatch2_policy.csv b/Casbin.UnitTests/Examples/keymatch2_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/keymatch2_policy.csv rename to Casbin.UnitTests/Examples/keymatch2_policy.csv diff --git a/Casbin.UnitTests/examples/keymatch_custom_model.conf b/Casbin.UnitTests/Examples/keymatch_custom_model.conf similarity index 100% rename from Casbin.UnitTests/examples/keymatch_custom_model.conf rename to Casbin.UnitTests/Examples/keymatch_custom_model.conf diff --git a/Casbin.UnitTests/examples/keymatch_model.conf b/Casbin.UnitTests/Examples/keymatch_model.conf similarity index 100% rename from Casbin.UnitTests/examples/keymatch_model.conf rename to Casbin.UnitTests/Examples/keymatch_model.conf diff --git a/Casbin.UnitTests/examples/keymatch_policy.csv b/Casbin.UnitTests/Examples/keymatch_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/keymatch_policy.csv rename to Casbin.UnitTests/Examples/keymatch_policy.csv diff --git a/Casbin.UnitTests/examples/multiple_type_model.conf b/Casbin.UnitTests/Examples/multiple_type_model.conf similarity index 100% rename from Casbin.UnitTests/examples/multiple_type_model.conf rename to Casbin.UnitTests/Examples/multiple_type_model.conf diff --git a/Casbin.UnitTests/examples/multiple_type_policy.csv b/Casbin.UnitTests/Examples/multiple_type_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/multiple_type_policy.csv rename to Casbin.UnitTests/Examples/multiple_type_policy.csv diff --git a/Casbin.UnitTests/examples/priority_explicit_deny_override_model.conf b/Casbin.UnitTests/Examples/priority_explicit_deny_override_model.conf similarity index 100% rename from Casbin.UnitTests/examples/priority_explicit_deny_override_model.conf rename to Casbin.UnitTests/Examples/priority_explicit_deny_override_model.conf diff --git a/Casbin.UnitTests/examples/priority_explicit_deny_override_policy.csv b/Casbin.UnitTests/Examples/priority_explicit_deny_override_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/priority_explicit_deny_override_policy.csv rename to Casbin.UnitTests/Examples/priority_explicit_deny_override_policy.csv diff --git a/Casbin.UnitTests/examples/priority_explicit_model.conf b/Casbin.UnitTests/Examples/priority_explicit_model.conf similarity index 100% rename from Casbin.UnitTests/examples/priority_explicit_model.conf rename to Casbin.UnitTests/Examples/priority_explicit_model.conf diff --git a/Casbin.UnitTests/examples/priority_explicit_policy.csv b/Casbin.UnitTests/Examples/priority_explicit_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/priority_explicit_policy.csv rename to Casbin.UnitTests/Examples/priority_explicit_policy.csv diff --git a/Casbin.UnitTests/examples/priority_indeterminate_policy.csv b/Casbin.UnitTests/Examples/priority_indeterminate_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/priority_indeterminate_policy.csv rename to Casbin.UnitTests/Examples/priority_indeterminate_policy.csv diff --git a/Casbin.UnitTests/examples/priority_model.conf b/Casbin.UnitTests/Examples/priority_model.conf similarity index 100% rename from Casbin.UnitTests/examples/priority_model.conf rename to Casbin.UnitTests/Examples/priority_model.conf diff --git a/Casbin.UnitTests/examples/priority_policy.csv b/Casbin.UnitTests/Examples/priority_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/priority_policy.csv rename to Casbin.UnitTests/Examples/priority_policy.csv diff --git a/Casbin.UnitTests/examples/rbac_comment.conf b/Casbin.UnitTests/Examples/rbac_comment.conf similarity index 100% rename from Casbin.UnitTests/examples/rbac_comment.conf rename to Casbin.UnitTests/Examples/rbac_comment.conf diff --git a/Casbin.UnitTests/examples/rbac_in_operator_model.conf b/Casbin.UnitTests/Examples/rbac_in_operator_model.conf similarity index 100% rename from Casbin.UnitTests/examples/rbac_in_operator_model.conf rename to Casbin.UnitTests/Examples/rbac_in_operator_model.conf diff --git a/Casbin.UnitTests/examples/rbac_in_operator_policy.csv b/Casbin.UnitTests/Examples/rbac_in_operator_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/rbac_in_operator_policy.csv rename to Casbin.UnitTests/Examples/rbac_in_operator_policy.csv diff --git a/Casbin.UnitTests/examples/rbac_model.conf b/Casbin.UnitTests/Examples/rbac_model.conf similarity index 100% rename from Casbin.UnitTests/examples/rbac_model.conf rename to Casbin.UnitTests/Examples/rbac_model.conf diff --git a/Casbin.UnitTests/examples/rbac_multiple_eval_model.conf b/Casbin.UnitTests/Examples/rbac_multiple_eval_model.conf similarity index 100% rename from Casbin.UnitTests/examples/rbac_multiple_eval_model.conf rename to Casbin.UnitTests/Examples/rbac_multiple_eval_model.conf diff --git a/Casbin.UnitTests/examples/rbac_multiple_eval_policy.csv b/Casbin.UnitTests/Examples/rbac_multiple_eval_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/rbac_multiple_eval_policy.csv rename to Casbin.UnitTests/Examples/rbac_multiple_eval_policy.csv diff --git a/Casbin.UnitTests/examples/rbac_multiple_rolemanager_model.conf b/Casbin.UnitTests/Examples/rbac_multiple_rolemanager_model.conf similarity index 100% rename from Casbin.UnitTests/examples/rbac_multiple_rolemanager_model.conf rename to Casbin.UnitTests/Examples/rbac_multiple_rolemanager_model.conf diff --git a/Casbin.UnitTests/examples/rbac_multiple_rolemanager_policy.csv b/Casbin.UnitTests/Examples/rbac_multiple_rolemanager_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/rbac_multiple_rolemanager_policy.csv rename to Casbin.UnitTests/Examples/rbac_multiple_rolemanager_policy.csv diff --git a/Casbin.UnitTests/examples/rbac_policy.csv b/Casbin.UnitTests/Examples/rbac_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/rbac_policy.csv rename to Casbin.UnitTests/Examples/rbac_policy.csv diff --git a/Casbin.UnitTests/examples/rbac_policy_for_async_watcher_test.csv b/Casbin.UnitTests/Examples/rbac_policy_for_async_watcher_test.csv similarity index 100% rename from Casbin.UnitTests/examples/rbac_policy_for_async_watcher_test.csv rename to Casbin.UnitTests/Examples/rbac_policy_for_async_watcher_test.csv diff --git a/Casbin.UnitTests/examples/rbac_policy_for_watcher_test.csv b/Casbin.UnitTests/Examples/rbac_policy_for_watcher_test.csv similarity index 100% rename from Casbin.UnitTests/examples/rbac_policy_for_watcher_test.csv rename to Casbin.UnitTests/Examples/rbac_policy_for_watcher_test.csv diff --git a/Casbin.UnitTests/examples/rbac_with_deny_model.conf b/Casbin.UnitTests/Examples/rbac_with_deny_model.conf similarity index 100% rename from Casbin.UnitTests/examples/rbac_with_deny_model.conf rename to Casbin.UnitTests/Examples/rbac_with_deny_model.conf diff --git a/Casbin.UnitTests/examples/rbac_with_deny_policy.csv b/Casbin.UnitTests/Examples/rbac_with_deny_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/rbac_with_deny_policy.csv rename to Casbin.UnitTests/Examples/rbac_with_deny_policy.csv diff --git a/Casbin.UnitTests/examples/rbac_with_domains_model.conf b/Casbin.UnitTests/Examples/rbac_with_domains_model.conf similarity index 100% rename from Casbin.UnitTests/examples/rbac_with_domains_model.conf rename to Casbin.UnitTests/Examples/rbac_with_domains_model.conf diff --git a/Casbin.UnitTests/examples/rbac_with_domains_policy.csv b/Casbin.UnitTests/Examples/rbac_with_domains_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/rbac_with_domains_policy.csv rename to Casbin.UnitTests/Examples/rbac_with_domains_policy.csv diff --git a/Casbin.UnitTests/examples/rbac_with_domains_policy2.csv b/Casbin.UnitTests/Examples/rbac_with_domains_policy2.csv similarity index 100% rename from Casbin.UnitTests/examples/rbac_with_domains_policy2.csv rename to Casbin.UnitTests/Examples/rbac_with_domains_policy2.csv diff --git a/Casbin.UnitTests/examples/rbac_with_hierarchy_policy.csv b/Casbin.UnitTests/Examples/rbac_with_hierarchy_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/rbac_with_hierarchy_policy.csv rename to Casbin.UnitTests/Examples/rbac_with_hierarchy_policy.csv diff --git a/Casbin.UnitTests/examples/rbac_with_hierarchy_with_domains_policy.csv b/Casbin.UnitTests/Examples/rbac_with_hierarchy_with_domains_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/rbac_with_hierarchy_with_domains_policy.csv rename to Casbin.UnitTests/Examples/rbac_with_hierarchy_with_domains_policy.csv diff --git a/Casbin.UnitTests/examples/rbac_with_index_matcher_model.conf b/Casbin.UnitTests/Examples/rbac_with_index_matcher_model.conf similarity index 100% rename from Casbin.UnitTests/examples/rbac_with_index_matcher_model.conf rename to Casbin.UnitTests/Examples/rbac_with_index_matcher_model.conf diff --git a/Casbin.UnitTests/examples/rbac_with_index_matcher_policy.csv b/Casbin.UnitTests/Examples/rbac_with_index_matcher_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/rbac_with_index_matcher_policy.csv rename to Casbin.UnitTests/Examples/rbac_with_index_matcher_policy.csv diff --git a/Casbin.UnitTests/examples/rbac_with_not_deny_model.conf b/Casbin.UnitTests/Examples/rbac_with_not_deny_model.conf similarity index 100% rename from Casbin.UnitTests/examples/rbac_with_not_deny_model.conf rename to Casbin.UnitTests/Examples/rbac_with_not_deny_model.conf diff --git a/Casbin.UnitTests/examples/rbac_with_resource_roles_model.conf b/Casbin.UnitTests/Examples/rbac_with_resource_roles_model.conf similarity index 100% rename from Casbin.UnitTests/examples/rbac_with_resource_roles_model.conf rename to Casbin.UnitTests/Examples/rbac_with_resource_roles_model.conf diff --git a/Casbin.UnitTests/examples/rbac_with_resource_roles_policy.csv b/Casbin.UnitTests/Examples/rbac_with_resource_roles_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/rbac_with_resource_roles_policy.csv rename to Casbin.UnitTests/Examples/rbac_with_resource_roles_policy.csv diff --git a/Casbin.UnitTests/examples/saa_model.conf b/Casbin.UnitTests/Examples/saa_model.conf similarity index 100% rename from Casbin.UnitTests/examples/saa_model.conf rename to Casbin.UnitTests/Examples/saa_model.conf diff --git a/Casbin.UnitTests/examples/saa_rbac_policy.csv b/Casbin.UnitTests/Examples/saa_rbac_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/saa_rbac_policy.csv rename to Casbin.UnitTests/Examples/saa_rbac_policy.csv diff --git a/Casbin.UnitTests/examples/subject_priority_model.conf b/Casbin.UnitTests/Examples/subject_priority_model.conf similarity index 100% rename from Casbin.UnitTests/examples/subject_priority_model.conf rename to Casbin.UnitTests/Examples/subject_priority_model.conf diff --git a/Casbin.UnitTests/examples/subject_priority_model_with_domain.conf b/Casbin.UnitTests/Examples/subject_priority_model_with_domain.conf similarity index 100% rename from Casbin.UnitTests/examples/subject_priority_model_with_domain.conf rename to Casbin.UnitTests/Examples/subject_priority_model_with_domain.conf diff --git a/Casbin.UnitTests/examples/subject_priority_policy.csv b/Casbin.UnitTests/Examples/subject_priority_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/subject_priority_policy.csv rename to Casbin.UnitTests/Examples/subject_priority_policy.csv diff --git a/Casbin.UnitTests/examples/subject_priority_policy_with_domain.csv b/Casbin.UnitTests/Examples/subject_priority_policy_with_domain.csv similarity index 100% rename from Casbin.UnitTests/examples/subject_priority_policy_with_domain.csv rename to Casbin.UnitTests/Examples/subject_priority_policy_with_domain.csv diff --git a/Casbin.UnitTests/examples/support_count_model.conf b/Casbin.UnitTests/Examples/support_count_model.conf similarity index 100% rename from Casbin.UnitTests/examples/support_count_model.conf rename to Casbin.UnitTests/Examples/support_count_model.conf diff --git a/Casbin.UnitTests/examples/tabs_model.conf b/Casbin.UnitTests/Examples/tabs_model.conf similarity index 100% rename from Casbin.UnitTests/examples/tabs_model.conf rename to Casbin.UnitTests/Examples/tabs_model.conf diff --git a/Casbin.UnitTests/examples/tabs_policy.csv b/Casbin.UnitTests/Examples/tabs_policy.csv similarity index 100% rename from Casbin.UnitTests/examples/tabs_policy.csv rename to Casbin.UnitTests/Examples/tabs_policy.csv diff --git a/Casbin.UnitTests/examples/tokens_with_substring_relation_abac.conf b/Casbin.UnitTests/Examples/tokens_with_substring_relation_abac.conf similarity index 100% rename from Casbin.UnitTests/examples/tokens_with_substring_relation_abac.conf rename to Casbin.UnitTests/Examples/tokens_with_substring_relation_abac.conf diff --git a/Casbin.UnitTests/examples/tokens_with_substring_relation_abac.csv b/Casbin.UnitTests/Examples/tokens_with_substring_relation_abac.csv similarity index 100% rename from Casbin.UnitTests/examples/tokens_with_substring_relation_abac.csv rename to Casbin.UnitTests/Examples/tokens_with_substring_relation_abac.csv diff --git a/Casbin.UnitTests/examples/tokens_with_substring_relation_rbac.conf b/Casbin.UnitTests/Examples/tokens_with_substring_relation_rbac.conf similarity index 100% rename from Casbin.UnitTests/examples/tokens_with_substring_relation_rbac.conf rename to Casbin.UnitTests/Examples/tokens_with_substring_relation_rbac.conf diff --git a/Casbin.UnitTests/examples/tokens_with_substring_relation_rbac.csv b/Casbin.UnitTests/Examples/tokens_with_substring_relation_rbac.csv similarity index 100% rename from Casbin.UnitTests/examples/tokens_with_substring_relation_rbac.csv rename to Casbin.UnitTests/Examples/tokens_with_substring_relation_rbac.csv diff --git a/Casbin.UnitTests/GenericTests/GenericFunctionTest.cs b/Casbin.UnitTests/GenericTests/GenericFunctionTest.cs new file mode 100644 index 0000000..0b46474 --- /dev/null +++ b/Casbin.UnitTests/GenericTests/GenericFunctionTest.cs @@ -0,0 +1,69 @@ +using System; +using Casbin.Model; +using Casbin.UnitTests.Util; +using DynamicExpresso; +using Xunit; + +namespace Casbin.UnitTests.GenericTests; + +public class GenericFunctionTest +{ + [Fact] + public void TestGenericFunction() + { + Interpreter interpreter = new(); + RequestValues r = Request.CreateValues("A", 1); + PolicyValues p = Policy.CreateValues("A", 1); + interpreter.SetFunction("equal", new Func( + (a, b) => a == b) + ); + interpreter.SetFunction("equal", new Func( + (a, b) => a == b) + ); + + Func, PolicyValues, bool> func1 = + ExpressionUtil.Compile(interpreter, "equal(r.Value2, p.Value2) && equal(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))); + } + +#if !NET452 + [Fact] + public void TestGenericFunctionModel() + { + Enforcer e = new Enforcer(DefaultModel.NewModelFromText( + """ + [request_definition] + r = obj1, obj2 + + [policy_definition] + p = _ + + [policy_effect] + e = some(where (p.eft == allow)) + + [matchers] + m = max(r.obj1, r.obj2) > 2 + """)); + + e.AddFunction("max", new Func( + // ReSharper disable once ConvertClosureToMethodGroup + (a, b) => Math.Max(a, b) + )); + Assert.True(e.Enforce(1, 3)); + Assert.False(e.Enforce(1, 2)); + Assert.False(e.Enforce("1", "111")); + + e.AddFunction("max", new Func( + (a, b) => Math.Max(a.Length, b.Length) + )); + Assert.True(e.Enforce(1, 3)); + Assert.False(e.Enforce(1, 2)); + Assert.True(e.Enforce("1", "111")); + } +#endif + +} diff --git a/Casbin.UnitTests/GenericTests/GenericMatcherTest.cs b/Casbin.UnitTests/GenericTests/GenericMatcherTest.cs index e533c3b..fce505a 100644 --- a/Casbin.UnitTests/GenericTests/GenericMatcherTest.cs +++ b/Casbin.UnitTests/GenericTests/GenericMatcherTest.cs @@ -1,5 +1,7 @@ using System; +using Casbin.Evaluation; using Casbin.Model; +using Casbin.UnitTests.Util; using DynamicExpresso; using Xunit; @@ -10,11 +12,12 @@ public class GenericMatcherTest [Fact] public void TestGenericMatcher() { + Interpreter interpreter = new(); 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); + Func, PolicyValues, bool> func1 = + ExpressionUtil.Compile(interpreter, "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))); @@ -22,25 +25,15 @@ public void TestGenericMatcher() 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); + Func, PolicyValues, bool> func2 = + ExpressionUtil.Compile(interpreter, "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"))); } - private static Func Compile - ( - string expressionText, - string requestType, in TRequest r, - string policyType, in TPolicy p) - where TRequest : struct, IRequestValues where TPolicy : IPolicyValues - { - Interpreter interpreter = new(); - return interpreter.ParseAsDelegate>( - expressionText, requestType, policyType - ); - } + + } diff --git a/Casbin.UnitTests/ModelTests/EnforcerTest.cs b/Casbin.UnitTests/ModelTests/EnforcerTest.cs index 64eb87b..5b00b17 100644 --- a/Casbin.UnitTests/ModelTests/EnforcerTest.cs +++ b/Casbin.UnitTests/ModelTests/EnforcerTest.cs @@ -69,7 +69,7 @@ public void TestEnforceWithoutAutoLoadPolicy() m.AddDef("e", "e", "some(where (p.eft == allow))"); m.AddDef("m", "m", "r.sub == p.sub && keyMatch(r.obj, p.obj) && regexMatch(r.act, p.act)"); - FileAdapter a = new("examples/keymatch_policy.csv"); + FileAdapter a = new("Examples/keymatch_policy.csv"); IEnforcer e = new Enforcer(m, a, new EnforcerOptions { AutoLoadPolicy = false }); Assert.Empty(e.GetPolicy()); @@ -118,7 +118,7 @@ public void TestKeyMatchModelInMemory() m.AddDef("e", "e", "some(where (p.eft == allow))"); m.AddDef("m", "m", "r.sub == p.sub && keyMatch(r.obj, p.obj) && regexMatch(r.act, p.act)"); - FileAdapter a = new("examples/keymatch_policy.csv"); + FileAdapter a = new("Examples/keymatch_policy.csv"); Enforcer e = new(m, a); @@ -179,7 +179,7 @@ public async Task TestKeyMatchModelInMemoryAsync() m.AddDef("e", "e", "some(where (p.eft == allow))"); m.AddDef("m", "m", "r.sub == p.sub && keyMatch(r.obj, p.obj) && regexMatch(r.act, p.act)"); - FileAdapter a = new("examples/keymatch_policy.csv"); + FileAdapter a = new("Examples/keymatch_policy.csv"); Enforcer e = new(m, a); @@ -240,7 +240,7 @@ public void TestKeyMatchModelInMemoryDeny() m.AddDef("e", "e", "!some(where (p.eft == deny))"); m.AddDef("m", "m", "r.sub == p.sub && keyMatch(r.obj, p.obj) && regexMatch(r.act, p.act)"); - FileAdapter a = new("examples/keymatch_policy.csv"); + FileAdapter a = new("Examples/keymatch_policy.csv"); Enforcer e = new(m, a); @@ -671,7 +671,7 @@ public void TestInitEmpty() m.AddDef("e", "e", "some(where (p.eft == allow))"); m.AddDef("m", "m", "r.sub == p.sub && keyMatch(r.obj, p.obj) && regexMatch(r.act, p.act)"); - FileAdapter a = new("examples/keymatch_policy.csv"); + FileAdapter a = new("Examples/keymatch_policy.csv"); e.SetModel(m); e.SetAdapter(a); @@ -691,7 +691,7 @@ public async Task TestInitEmptyAsync() m.AddDef("e", "e", "some(where (p.eft == allow))"); m.AddDef("m", "m", "r.sub == p.sub && keyMatch(r.obj, p.obj) && regexMatch(r.act, p.act)"); - FileAdapter a = new("examples/keymatch_policy.csv"); + FileAdapter a = new("Examples/keymatch_policy.csv"); e.SetModel(m); e.SetAdapter(a); @@ -711,7 +711,7 @@ public void TestInitEmptyByInputStream() m.AddDef("e", "e", "some(where (p.eft == allow))"); m.AddDef("m", "m", "r.sub == p.sub && keyMatch(r.obj, p.obj) && regexMatch(r.act, p.act)"); - using (FileStream fs = new("examples/keymatch_policy.csv", FileMode.Open, FileAccess.Read, + using (FileStream fs = new("Examples/keymatch_policy.csv", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { FileAdapter a = new(fs); @@ -734,7 +734,7 @@ public async Task TestInitEmptyByInputStreamAsync() m.AddDef("e", "e", "some(where (p.eft == allow))"); m.AddDef("m", "m", "r.sub == p.sub && keyMatch(r.obj, p.obj) && regexMatch(r.act, p.act)"); - using (FileStream fs = new("examples/keymatch_policy.csv", FileMode.Open, FileAccess.Read, + using (FileStream fs = new("Examples/keymatch_policy.csv", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { FileAdapter a = new(fs); @@ -753,7 +753,7 @@ public async Task TestInitEmptyByInputStreamAsync() [Fact] public void TestReloadPolicy() { - Enforcer e = new("examples/rbac_model.conf", "examples/rbac_policy.csv"); + Enforcer e = new("Examples/rbac_model.conf", "Examples/rbac_policy.csv"); e.LoadPolicy(); TestGetPolicy(e, @@ -764,7 +764,7 @@ public void TestReloadPolicy() [Fact] public async Task TestReloadPolicyAsync() { - Enforcer e = new("examples/rbac_model.conf", "examples/rbac_policy.csv"); + Enforcer e = new("Examples/rbac_model.conf", "Examples/rbac_policy.csv"); await e.LoadPolicyAsync(); TestGetPolicy(e, @@ -775,7 +775,7 @@ public async Task TestReloadPolicyAsync() [Fact] public void TestSavePolicy() { - Enforcer e = new("examples/rbac_model.conf", "examples/rbac_policy.csv"); + Enforcer e = new("Examples/rbac_model.conf", "Examples/rbac_policy.csv"); e.SavePolicy(); } @@ -783,7 +783,7 @@ public void TestSavePolicy() [Fact] public async Task TestSavePolicyAsync() { - Enforcer e = new("examples/rbac_model.conf", "examples/rbac_policy.csv"); + Enforcer e = new("Examples/rbac_model.conf", "Examples/rbac_policy.csv"); await e.SavePolicyAsync(); } @@ -791,7 +791,7 @@ public async Task TestSavePolicyAsync() [Fact] public void TestSavePolicyWithoutBasicModel() { - Enforcer e = new("examples/basic_model.conf", "examples/basic_policy.csv"); + Enforcer e = new("Examples/basic_model.conf", "Examples/basic_policy.csv"); e.SavePolicy(); } @@ -799,7 +799,7 @@ public void TestSavePolicyWithoutBasicModel() [Fact] public async Task TestSavePolicyWithoutBasicModelAsync() { - Enforcer e = new("examples/basic_model.conf", "examples/basic_policy.csv"); + Enforcer e = new("Examples/basic_model.conf", "Examples/basic_policy.csv"); await e.SavePolicyAsync(); } @@ -807,7 +807,7 @@ public async Task TestSavePolicyWithoutBasicModelAsync() [Fact] public void TestClearPolicy() { - Enforcer e = new("examples/rbac_model.conf", "examples/rbac_policy.csv"); + Enforcer e = new("Examples/rbac_model.conf", "Examples/rbac_policy.csv"); e.ClearPolicy(); } @@ -819,7 +819,7 @@ public void TestClearPolicy() [Fact] public void TestEnableEnforce() { - Enforcer e = new("examples/basic_model.conf", "examples/basic_policy.csv"); + Enforcer e = new("Examples/basic_model.conf", "Examples/basic_policy.csv"); e.EnableEnforce(false); TestEnforce(e, "alice", "data1", "read", true); @@ -846,7 +846,7 @@ public void TestEnableEnforce() [Fact] public void TestEnableLog() { - Enforcer e = new("examples/basic_model.conf", "examples/basic_policy.csv") + Enforcer e = new("Examples/basic_model.conf", "Examples/basic_policy.csv") { Logger = new MockLogger(_testOutputHelper) }; @@ -875,7 +875,7 @@ public void TestEnableLog() [Fact] public void TestEnableAutoSave() { - Enforcer e = new("examples/basic_model.conf", "examples/basic_policy.csv"); + Enforcer e = new("Examples/basic_model.conf", "Examples/basic_policy.csv"); e.EnableAutoSave(false); // Because AutoSave is disabled, the policy change only affects the policy in Casbin enforcer, @@ -914,7 +914,7 @@ public void TestEnableAutoSave() [Fact] public async Task TestEnableAutoSaveAsync() { - Enforcer e = new("examples/basic_model.conf", "examples/basic_policy_for_async_adapter_test.csv"); + Enforcer e = new("Examples/basic_model.conf", "Examples/basic_policy_for_async_adapter_test.csv"); e.EnableAutoSave(false); // Because AutoSave is disabled, the policy change only affects the policy in Casbin enforcer, @@ -953,8 +953,8 @@ public async Task TestEnableAutoSaveAsync() [Fact] public void TestInitWithAdapter() { - FileAdapter adapter = new("examples/basic_policy.csv"); - Enforcer e = new("examples/basic_model.conf", adapter); + FileAdapter adapter = new("Examples/basic_policy.csv"); + Enforcer e = new("Examples/basic_model.conf", adapter); TestEnforce(e, "alice", "data1", "read", true); TestEnforce(e, "alice", "data1", "write", false); @@ -969,7 +969,7 @@ public void TestInitWithAdapter() [Fact] public void TestRoleLinks() { - Enforcer e = new("examples/rbac_model.conf"); + Enforcer e = new("Examples/rbac_model.conf"); e.EnableAutoBuildRoleLinks(false); e.BuildRoleLinks(); e.Enforce("user501", "data9", "read"); @@ -978,8 +978,8 @@ public void TestRoleLinks() [Fact] public void TestGetAndSetModel() { - Enforcer e = new("examples/basic_model.conf", "examples/basic_policy.csv"); - Enforcer e2 = new("examples/basic_with_root_model.conf", "examples/basic_policy.csv"); + Enforcer e = new("Examples/basic_model.conf", "Examples/basic_policy.csv"); + Enforcer e2 = new("Examples/basic_with_root_model.conf", "Examples/basic_policy.csv"); TestEnforce(e, "root", "data1", "read", false); @@ -991,8 +991,8 @@ public void TestGetAndSetModel() [Fact] public void TestGetAndSetAdapterInMem() { - Enforcer e = new("examples/basic_model.conf", "examples/basic_policy.csv"); - Enforcer e2 = new("examples/basic_model.conf", "examples/basic_inverse_policy.csv"); + Enforcer e = new("Examples/basic_model.conf", "Examples/basic_policy.csv"); + Enforcer e2 = new("Examples/basic_model.conf", "Examples/basic_inverse_policy.csv"); TestEnforce(e, "alice", "data1", "read", true); TestEnforce(e, "alice", "data1", "write", false); @@ -1008,8 +1008,8 @@ public void TestGetAndSetAdapterInMem() [Fact] public async Task TestGetAndSetAdapterInMemAsync() { - Enforcer e = new("examples/basic_model.conf", "examples/basic_policy_for_async_adapter_test.csv"); - Enforcer e2 = new("examples/basic_model.conf", "examples/basic_inverse_policy.csv"); + Enforcer e = new("Examples/basic_model.conf", "Examples/basic_policy_for_async_adapter_test.csv"); + Enforcer e2 = new("Examples/basic_model.conf", "Examples/basic_inverse_policy.csv"); await TestEnforceAsync(e, "alice", "data1", "read", true); await TestEnforceAsync(e, "alice", "data1", "write", false); @@ -1025,11 +1025,11 @@ public async Task TestGetAndSetAdapterInMemAsync() [Fact] public void TestSetAdapterFromFile() { - Enforcer e = new("examples/basic_model.conf"); + Enforcer e = new("Examples/basic_model.conf"); TestEnforce(e, "alice", "data1", "read", false); - FileAdapter a = new("examples/basic_policy.csv"); + FileAdapter a = new("Examples/basic_policy.csv"); e.SetAdapter(a); e.LoadPolicy(); TestEnforce(e, "alice", "data1", "read", true); @@ -1046,11 +1046,11 @@ public void TestSetAdapterFromFile() [Fact] public async Task TestSetAdapterFromFileAsync() { - Enforcer e = new("examples/basic_model.conf"); + Enforcer e = new("Examples/basic_model.conf"); await TestEnforceAsync(e, "alice", "data1", "read", false); - FileAdapter a = new("examples/basic_policy_for_async_adapter_test.csv"); + FileAdapter a = new("Examples/basic_policy_for_async_adapter_test.csv"); e.SetAdapter(a); await e.LoadPolicyAsync(); await TestEnforceAsync(e, "alice", "data1", "read", true); diff --git a/Casbin.UnitTests/ModelTests/RbacApiTest.cs b/Casbin.UnitTests/ModelTests/RbacApiTest.cs index 036e224..32834db 100644 --- a/Casbin.UnitTests/ModelTests/RbacApiTest.cs +++ b/Casbin.UnitTests/ModelTests/RbacApiTest.cs @@ -423,8 +423,8 @@ public void TestGetImplicitPermissionsForUserWithDomain() TestGetImplicitPermissions(e, "alice", AsList( AsList("alice", "domain1", "data2", "read"), - AsList("role:writer", "domain1", "data1", "write"), - AsList("role:reader", "domain1", "data1", "read")), + AsList("role:reader", "domain1", "data1", "read"), + AsList("role:writer", "domain1", "data1", "write")), "domain1"); } diff --git a/Casbin.UnitTests/RbacTests/GroupRoleManagerTest.cs b/Casbin.UnitTests/RbacTests/GroupRoleManagerTest.cs index 57067be..f0d309d 100644 --- a/Casbin.UnitTests/RbacTests/GroupRoleManagerTest.cs +++ b/Casbin.UnitTests/RbacTests/GroupRoleManagerTest.cs @@ -9,7 +9,7 @@ public class GroupRoleManagerTest [Fact] public void TestGroupRoleManager() { - Enforcer e = new("examples/group_with_domain_model.conf", "examples/group_with_domain_policy.csv"); + Enforcer e = new("Examples/group_with_domain_model.conf", "Examples/group_with_domain_policy.csv"); GroupRoleManager roleManager = new(10); e.SetRoleManager("g", roleManager); e.SetRoleManager("g2", roleManager); diff --git a/Casbin.UnitTests/Util/ExpressionUtil.cs b/Casbin.UnitTests/Util/ExpressionUtil.cs new file mode 100644 index 0000000..090eb25 --- /dev/null +++ b/Casbin.UnitTests/Util/ExpressionUtil.cs @@ -0,0 +1,20 @@ +using System; +using Casbin.Model; +using DynamicExpresso; + +namespace Casbin.UnitTests.Util; + +public static class ExpressionUtil +{ + public static Func Compile + ( + Interpreter interpreter, string expressionText, + string requestType, in TRequest r, + string policyType, in TPolicy p) + where TRequest : struct, IRequestValues where TPolicy : IPolicyValues + { + return interpreter.ParseAsDelegate>( + expressionText, requestType, policyType + ); + } +} diff --git a/Casbin/EnforceView.cs b/Casbin/EnforceView.cs index 21c0b32..74a1cce 100644 --- a/Casbin/EnforceView.cs +++ b/Casbin/EnforceView.cs @@ -127,13 +127,11 @@ public static string TransformMatcher(in EnforceView view, string matcher) Regex reg = new Regex(perfix + $@"{view.RequestType}\.{tokenPair.Key}" + suffix); matcher = reg.Replace(matcher, $"{view.RequestType}[{tokenPair.Value}]"); } - foreach (KeyValuePair tokenPair in view.PolicyAssertion.Tokens) { Regex reg = new Regex(perfix + $@"{view.PolicyType}\.{tokenPair.Key}" + suffix); matcher = reg.Replace(matcher, $"{view.PolicyType}[{tokenPair.Value}]"); } - return matcher; } @@ -142,13 +140,11 @@ public static string TransformMatcher(in EnforceView view, string matcher) Regex reg = new Regex(perfix + $@"{view.RequestType}\.{tokenPair.Key}" + suffix); matcher = reg.Replace(matcher, $"{view.RequestType}.Value{tokenPair.Value + 1}"); } - 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}"); } - return matcher; } } diff --git a/Casbin/Extensions/Enforcer/ManagementEnforcerExtension.cs b/Casbin/Extensions/Enforcer/ManagementEnforcerExtension.cs index 502d819..43b373e 100644 --- a/Casbin/Extensions/Enforcer/ManagementEnforcerExtension.cs +++ b/Casbin/Extensions/Enforcer/ManagementEnforcerExtension.cs @@ -14,17 +14,14 @@ public static class ManagementEnforcerExtension /// /// The name of the new function. /// The function. - public static void AddFunction(this IEnforcer enforcer, string name, Delegate function) => + public static void AddFunction(this IEnforcer enforcer, string name, T function) where T : Delegate + { enforcer.Model.ExpressionHandler.SetFunction(name, function); - - /// - /// Adds a customized function. - /// - /// - /// The name of the new function. - /// The function. - public static void AddFunction(this IEnforcer enforcer, string name, Func function) => - AddFunction(enforcer, name, (Delegate)function); + if (enforcer.AutoCleanEnforceCache) + { + enforcer.ClearCache(); + } + } #region "p" (Store) Management diff --git a/Casbin/Extensions/Enforcer/RbacEnforcerExtension.cs b/Casbin/Extensions/Enforcer/RbacEnforcerExtension.cs index 9821121..b5ddfe2 100644 --- a/Casbin/Extensions/Enforcer/RbacEnforcerExtension.cs +++ b/Casbin/Extensions/Enforcer/RbacEnforcerExtension.cs @@ -523,19 +523,17 @@ public static IEnumerable GetImplicitRolesForUser(this IEnforcer enforce foreach (string role in roles) { - if (roleSet.Contains(role)) + if (roleSet.Add(role)) { - continue; + queue.Enqueue(role); } - - roleSet.Add(role); - queue.Enqueue(role); } } } - roleSet.Remove(name); - return roleSet; + var roleList = roleSet.ToList(); + roleList.Sort(); + return roleList; } ///