From 766bf05585acd01125ff0d17cafcbfdbb44707ae Mon Sep 17 00:00:00 2001 From: Jan-Pieter George Date: Fri, 4 Aug 2023 01:05:27 -0700 Subject: [PATCH] fix: Ensure tab characters in policy files are parsed as white-space (#324) * fix: Ensure tab characters in policy files are parsed as white-space * tests: Add unit tests --- Casbin.UnitTests/Fixtures/TestModelFixture.cs | 5 +++++ Casbin.UnitTests/ModelTests/ModelTest.cs | 9 +++++++++ Casbin.UnitTests/examples/tabs_model.conf | 15 +++++++++++++++ Casbin.UnitTests/examples/tabs_policy.csv | 1 + .../Extensions/Persist/PolicyStoreExtension.cs | 3 ++- Casbin/Persist/Adapter/File/FileAdapter.cs | 18 ++++++++++++------ 6 files changed, 44 insertions(+), 7 deletions(-) create mode 100644 Casbin.UnitTests/examples/tabs_model.conf create mode 100644 Casbin.UnitTests/examples/tabs_policy.csv diff --git a/Casbin.UnitTests/Fixtures/TestModelFixture.cs b/Casbin.UnitTests/Fixtures/TestModelFixture.cs index bee9063..55e449e 100644 --- a/Casbin.UnitTests/Fixtures/TestModelFixture.cs +++ b/Casbin.UnitTests/Fixtures/TestModelFixture.cs @@ -31,6 +31,8 @@ public class TestModelFixture //https://github.com/casbin/Casbin.NET/issues/310 internal readonly string _commaAndQuotationsModelText = ReadTestFile("comma_quotations_model.conf"); internal readonly string _commaAndQuotationsPolicyText = ReadTestFile("comma_quotations_policy.csv"); + internal readonly string _tabsModelText = ReadTestFile("tabs_model.conf"); + internal readonly string _tabsPolicyText = ReadTestFile("tabs_policy.csv"); internal readonly string _ipMatchModelText = ReadTestFile("ipmatch_model.conf"); internal readonly string _ipMatchPolicyText = ReadTestFile("ipmatch_policy.csv"); internal readonly string _keyMatch2ModelText = ReadTestFile("keymatch2_model.conf"); @@ -152,6 +154,9 @@ public IModel GetNewRbacWithResourceRoleTestModel() => public IModel GetNewCommaAndQuotationsModel() => GetNewTestModel(_commaAndQuotationsModelText, _commaAndQuotationsPolicyText); + public IModel GetNewTabsModel() => + GetNewTestModel(_tabsModelText, _tabsPolicyText); + public static IModel GetNewTestModel(string modelText) => DefaultModel.CreateFromText(modelText); public static IModel GetNewTestModel(string modelText, string policyText) => diff --git a/Casbin.UnitTests/ModelTests/ModelTest.cs b/Casbin.UnitTests/ModelTests/ModelTest.cs index 647cd47..c6398c3 100644 --- a/Casbin.UnitTests/ModelTests/ModelTest.cs +++ b/Casbin.UnitTests/ModelTests/ModelTest.cs @@ -644,6 +644,15 @@ public void TestModelWithCommaAndQuotations() TestEnforce(e, "cindy", "\"\"Muti Quotations Test\"", "Get", false); } + [Fact] + public void TestModelWithTabs() + { + Enforcer e = new Enforcer(_testModelFixture.GetNewTabsModel()); + e.AddRoleForUserInDomain("/user/john", "admin", "/tenant/1"); + + Assert.True(e.Enforce("/user/john", "/tenant/1", "/tenant/1/resource", "Write")); + } + [Fact] public void TestRbacTokensWithSubstringRelation() { diff --git a/Casbin.UnitTests/examples/tabs_model.conf b/Casbin.UnitTests/examples/tabs_model.conf new file mode 100644 index 0000000..9c3d29b --- /dev/null +++ b/Casbin.UnitTests/examples/tabs_model.conf @@ -0,0 +1,15 @@ +[request_definition] +r = a, b, c, d + +[policy_definition] +p = a, b, c, d +#p = wallet, ecosystem, resource, action + +[role_definition] +g = _, _, _ + +[policy_effect] +e = some(where (p.eft == allow)) + +[matchers] +m = (keyMatch2(r.a, p.a) || g(r.a, p.a, r.b)) && keyMatch2(r.c, p.c) && keyMatch(r.d, p.d) && keyMatch2(r.b, p.b) && keyGet2(r.b, p.b, "id") == keyGet2(r.c, p.c, "id") diff --git a/Casbin.UnitTests/examples/tabs_policy.csv b/Casbin.UnitTests/examples/tabs_policy.csv new file mode 100644 index 0000000..5e7ad20 --- /dev/null +++ b/Casbin.UnitTests/examples/tabs_policy.csv @@ -0,0 +1 @@ +p, admin, /tenant/:id, /tenant/:id/*, * diff --git a/Casbin/Extensions/Persist/PolicyStoreExtension.cs b/Casbin/Extensions/Persist/PolicyStoreExtension.cs index 481f182..9d062cf 100644 --- a/Casbin/Extensions/Persist/PolicyStoreExtension.cs +++ b/Casbin/Extensions/Persist/PolicyStoreExtension.cs @@ -29,7 +29,8 @@ public static bool TryLoadPolicyLine(this IPolicyStore store, string line) HasHeaderRecord = false, TrimOptions = TrimOptions.Trim, IgnoreBlankLines = true, - BadDataFound = null + BadDataFound = null, + WhiteSpaceChars = new []{' ', '\t'} }); if (parser.Read() is false) { diff --git a/Casbin/Persist/Adapter/File/FileAdapter.cs b/Casbin/Persist/Adapter/File/FileAdapter.cs index 3108a69..0f200c4 100644 --- a/Casbin/Persist/Adapter/File/FileAdapter.cs +++ b/Casbin/Persist/Adapter/File/FileAdapter.cs @@ -266,7 +266,8 @@ private static IEnumerable ReadPersistPolicy(string filePath) HasHeaderRecord = false, TrimOptions = TrimOptions.Trim, IgnoreBlankLines = true, - BadDataFound = null + BadDataFound = null, + WhiteSpaceChars = new []{' ', '\t'} }); while (parser.Read()) @@ -293,7 +294,8 @@ private static IEnumerable ReadPersistPolicy(System.IO.Stream st HasHeaderRecord = false, TrimOptions = TrimOptions.Trim, IgnoreBlankLines = true, - BadDataFound = null + BadDataFound = null, + WhiteSpaceChars = new []{' ', '\t'} }); while (parser.Read()) @@ -327,7 +329,8 @@ private static async IAsyncEnumerable ReadPersistPolicyAsync(str HasHeaderRecord = false, TrimOptions = TrimOptions.Trim, IgnoreBlankLines = true, - BadDataFound = null + BadDataFound = null, + WhiteSpaceChars = new []{' ', '\t'} }); while (await parser.ReadAsync()) @@ -355,7 +358,8 @@ private static async Task> ReadPersistPolicyAsync(st HasHeaderRecord = false, TrimOptions = TrimOptions.Trim, IgnoreBlankLines = true, - BadDataFound = null + BadDataFound = null, + WhiteSpaceChars = new []{' ', '\t'} }); var list = new List(); while (await parser.ReadAsync()) @@ -386,7 +390,8 @@ private static async IAsyncEnumerable ReadPersistPolicyAsync(Sys HasHeaderRecord = false, TrimOptions = TrimOptions.Trim, IgnoreBlankLines = true, - BadDataFound = null + BadDataFound = null, + WhiteSpaceChars = new []{' ', '\t'} }); while (await parser.ReadAsync()) @@ -413,7 +418,8 @@ private static async Task> ReadPersistPolicyAsync(Sy HasHeaderRecord = false, TrimOptions = TrimOptions.Trim, IgnoreBlankLines = true, - BadDataFound = null + BadDataFound = null, + WhiteSpaceChars = new []{' ', '\t'} }); var list = new List(); while (await parser.ReadAsync())