From c7651f813d44bdbbefc2d36f94d06e8b7367c59a Mon Sep 17 00:00:00 2001 From: Kyle Dodson Date: Mon, 22 Sep 2025 15:55:26 -0700 Subject: [PATCH 1/2] fix: implement IPolicyFilter in PolicyFilter --- Casbin.UnitTests/PersistTests/AdapterTest.cs | 126 +++++++++++++++++++ Casbin/Persist/PolicyFilter.cs | 2 +- 2 files changed, 127 insertions(+), 1 deletion(-) diff --git a/Casbin.UnitTests/PersistTests/AdapterTest.cs b/Casbin.UnitTests/PersistTests/AdapterTest.cs index 784691f..86459f2 100644 --- a/Casbin.UnitTests/PersistTests/AdapterTest.cs +++ b/Casbin.UnitTests/PersistTests/AdapterTest.cs @@ -1,5 +1,7 @@ using System.IO; using System.Threading.Tasks; +using Casbin.Model; +using Casbin.Persist; using Casbin.Persist.Adapter.File; using Casbin.Persist.Adapter.Stream; using Casbin.Persist.Adapter.Text; @@ -49,6 +51,46 @@ public async Task TestFileAdapterAsync() Assert.True(await e.EnforceAsync("bob", "data2", "write")); } + [Fact] + public void TestFilteredFileAdapter() + { + Enforcer e = new("Examples/basic_model.conf"); + Assert.False(e.Enforce("alice", "data1", "read")); + + FileAdapter a = new("Examples/basic_policy.csv"); + e.SetAdapter(a); + e.LoadFilteredPolicy(new PolicyFilter(PermConstants.DefaultPolicyType, 0, Policy.ValuesFrom(["bob"]))); + + Assert.False(e.Enforce("alice", "data1", "read")); // because "alice" is not in the filtered policy + Assert.False(e.Enforce("alice", "data1", "write")); + Assert.False(e.Enforce("alice", "data2", "read")); + Assert.False(e.Enforce("alice", "data2", "write")); + Assert.False(e.Enforce("bob", "data1", "read")); + Assert.False(e.Enforce("bob", "data1", "write")); + Assert.False(e.Enforce("bob", "data2", "read")); + Assert.True(e.Enforce("bob", "data2", "write")); + } + + [Fact] + public async Task TestFilteredFileAdapterAsync() + { + Enforcer e = new("Examples/basic_model.conf"); + Assert.False(await e.EnforceAsync("alice", "data1", "read")); + + FileAdapter a = new("Examples/basic_policy.csv"); + e.SetAdapter(a); + await e.LoadFilteredPolicyAsync(new PolicyFilter(PermConstants.DefaultPolicyType, 0, Policy.ValuesFrom(["bob"]))); + + Assert.False(await e.EnforceAsync("alice", "data1", "read")); // because "alice" is not in the filtered policy + Assert.False(await e.EnforceAsync("alice", "data1", "write")); + Assert.False(await e.EnforceAsync("alice", "data2", "read")); + Assert.False(await e.EnforceAsync("alice", "data2", "write")); + Assert.False(await e.EnforceAsync("bob", "data1", "read")); + Assert.False(await e.EnforceAsync("bob", "data1", "write")); + Assert.False(await e.EnforceAsync("bob", "data2", "read")); + Assert.True(await e.EnforceAsync("bob", "data2", "write")); + } + [Fact] public void TestStreamAdapter() { @@ -89,6 +131,46 @@ public async Task TestStreamAdapterAsync() Assert.True(await e.EnforceAsync("bob", "data2", "write")); } + [Fact] + public void TestFilteredStreamAdapter() + { + Enforcer e = new("Examples/basic_model.conf"); + Assert.False(e.Enforce("alice", "data1", "read")); + + StreamAdapter a = new(File.OpenRead("Examples/basic_policy.csv")); + e.SetAdapter(a); + e.LoadFilteredPolicy(new PolicyFilter(PermConstants.DefaultPolicyType, 0, Policy.ValuesFrom(["bob"]))); + + Assert.False(e.Enforce("alice", "data1", "read")); // because "alice" is not in the filtered policy + Assert.False(e.Enforce("alice", "data1", "write")); + Assert.False(e.Enforce("alice", "data2", "read")); + Assert.False(e.Enforce("alice", "data2", "write")); + Assert.False(e.Enforce("bob", "data1", "read")); + Assert.False(e.Enforce("bob", "data1", "write")); + Assert.False(e.Enforce("bob", "data2", "read")); + Assert.True(e.Enforce("bob", "data2", "write")); + } + + [Fact] + public async Task TestFilteredStreamAdapterAsync() + { + Enforcer e = new("Examples/basic_model.conf"); + Assert.False(await e.EnforceAsync("alice", "data1", "read")); + + StreamAdapter a = new(File.OpenRead("Examples/basic_policy.csv")); + e.SetAdapter(a); + await e.LoadFilteredPolicyAsync(new PolicyFilter(PermConstants.DefaultPolicyType, 0, Policy.ValuesFrom(["bob"]))); + + Assert.False(await e.EnforceAsync("alice", "data1", "read")); // because "alice" is not in the filtered policy + Assert.False(await e.EnforceAsync("alice", "data1", "write")); + Assert.False(await e.EnforceAsync("alice", "data2", "read")); + Assert.False(await e.EnforceAsync("alice", "data2", "write")); + Assert.False(await e.EnforceAsync("bob", "data1", "read")); + Assert.False(await e.EnforceAsync("bob", "data1", "write")); + Assert.False(await e.EnforceAsync("bob", "data2", "read")); + Assert.True(await e.EnforceAsync("bob", "data2", "write")); + } + [Fact] public void TestTextAdapter() { @@ -132,4 +214,48 @@ public async Task TestTextAdapterAsync() Assert.False(await e.EnforceAsync("bob", "data2", "read")); Assert.True(await e.EnforceAsync("bob", "data2", "write")); } + + [Fact] + public void TestFilteredTextAdapter() + { + Enforcer e = new("Examples/basic_model.conf"); + Assert.False(e.Enforce("alice", "data1", "read")); + + TextAdapter a = new(File.ReadAllText("Examples/basic_policy.csv")); + e.SetAdapter(a); + e.LoadFilteredPolicy(new PolicyFilter(PermConstants.DefaultPolicyType, 0, Policy.ValuesFrom(["bob"]))); + + Assert.False(e.Enforce("alice", "data1", "read")); // because "alice" is not in the filtered policy + Assert.False(e.Enforce("alice", "data1", "write")); + Assert.False(e.Enforce("alice", "data2", "read")); + Assert.False(e.Enforce("alice", "data2", "write")); + Assert.False(e.Enforce("bob", "data1", "read")); + Assert.False(e.Enforce("bob", "data1", "write")); + Assert.False(e.Enforce("bob", "data2", "read")); + Assert.True(e.Enforce("bob", "data2", "write")); + } + + [Fact] + public async Task TestFilteredTextAdapterAsync() + { + Enforcer e = new("Examples/basic_model.conf"); + Assert.False(await e.EnforceAsync("alice", "data1", "read")); + +#if NET452 || NET461 || NET462 + TextAdapter a = new(File.ReadAllText("Examples/basic_policy.csv")); +#else + TextAdapter a = new(await File.ReadAllTextAsync("Examples/basic_policy.csv")); +#endif + e.SetAdapter(a); + await e.LoadFilteredPolicyAsync(new PolicyFilter(PermConstants.DefaultPolicyType, 0, Policy.ValuesFrom(["bob"]))); + + Assert.False(await e.EnforceAsync("alice", "data1", "read")); // because "alice" is not in the filtered policy + Assert.False(await e.EnforceAsync("alice", "data1", "write")); + Assert.False(await e.EnforceAsync("alice", "data2", "read")); + Assert.False(await e.EnforceAsync("alice", "data2", "write")); + Assert.False(await e.EnforceAsync("bob", "data1", "read")); + Assert.False(await e.EnforceAsync("bob", "data1", "write")); + Assert.False(await e.EnforceAsync("bob", "data2", "read")); + Assert.True(await e.EnforceAsync("bob", "data2", "write")); + } } diff --git a/Casbin/Persist/PolicyFilter.cs b/Casbin/Persist/PolicyFilter.cs index 9dad1dd..8a51917 100644 --- a/Casbin/Persist/PolicyFilter.cs +++ b/Casbin/Persist/PolicyFilter.cs @@ -4,7 +4,7 @@ namespace Casbin.Persist; -public class PolicyFilter +public class PolicyFilter : IPolicyFilter { public static readonly PolicyFilter Empty = new(); private readonly int _fieldIndex; From c8cd5900aa1484727b177f4b7e8db89a9e09f86e Mon Sep 17 00:00:00 2001 From: Kyle Dodson Date: Tue, 23 Sep 2025 23:21:55 -0700 Subject: [PATCH 2/2] fix: dispose streams in unit tests --- Casbin.UnitTests/PersistTests/AdapterTest.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Casbin.UnitTests/PersistTests/AdapterTest.cs b/Casbin.UnitTests/PersistTests/AdapterTest.cs index 86459f2..87cb030 100644 --- a/Casbin.UnitTests/PersistTests/AdapterTest.cs +++ b/Casbin.UnitTests/PersistTests/AdapterTest.cs @@ -97,7 +97,8 @@ public void TestStreamAdapter() Enforcer e = new("Examples/basic_model.conf"); Assert.False(e.Enforce("alice", "data1", "read")); - StreamAdapter a = new(File.OpenRead("Examples/basic_policy.csv")); + using FileStream stream = File.OpenRead("Examples/basic_policy.csv"); + StreamAdapter a = new(stream); e.SetAdapter(a); e.LoadPolicy(); @@ -117,7 +118,8 @@ public async Task TestStreamAdapterAsync() Enforcer e = new("Examples/basic_model.conf"); Assert.False(await e.EnforceAsync("alice", "data1", "read")); - StreamAdapter a = new(File.OpenRead("Examples/basic_policy.csv")); + using FileStream stream = File.OpenRead("Examples/basic_policy.csv"); + StreamAdapter a = new(stream); e.SetAdapter(a); await e.LoadPolicyAsync(); @@ -137,7 +139,8 @@ public void TestFilteredStreamAdapter() Enforcer e = new("Examples/basic_model.conf"); Assert.False(e.Enforce("alice", "data1", "read")); - StreamAdapter a = new(File.OpenRead("Examples/basic_policy.csv")); + using FileStream stream = File.OpenRead("Examples/basic_policy.csv"); + StreamAdapter a = new(stream); e.SetAdapter(a); e.LoadFilteredPolicy(new PolicyFilter(PermConstants.DefaultPolicyType, 0, Policy.ValuesFrom(["bob"]))); @@ -157,7 +160,8 @@ public async Task TestFilteredStreamAdapterAsync() Enforcer e = new("Examples/basic_model.conf"); Assert.False(await e.EnforceAsync("alice", "data1", "read")); - StreamAdapter a = new(File.OpenRead("Examples/basic_policy.csv")); + using FileStream stream = File.OpenRead("Examples/basic_policy.csv"); + StreamAdapter a = new(stream); e.SetAdapter(a); await e.LoadFilteredPolicyAsync(new PolicyFilter(PermConstants.DefaultPolicyType, 0, Policy.ValuesFrom(["bob"])));