diff --git a/Casbin.UnitTests/ModelTests/EnforcerTest.cs b/Casbin.UnitTests/ModelTests/EnforcerTest.cs index 9c123bb..47baed1 100644 --- a/Casbin.UnitTests/ModelTests/EnforcerTest.cs +++ b/Casbin.UnitTests/ModelTests/EnforcerTest.cs @@ -1,9 +1,9 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using System.Text; using System.Threading.Tasks; using Casbin.Adapter.File; +using Casbin.Adapter.Stream; using Casbin.Model; using Casbin.Persist; using Casbin.Rbac; @@ -73,10 +73,10 @@ public void TestEnforceWithoutAutoLoadPolicy() FileAdapter a = new("examples/keymatch_policy.csv"); - IEnforcer e = DefaultEnforcer.Create(m, a, options => { options.AutoLoadPolicy = false; }); + IEnforcer e = new Enforcer(m, a, options => { options.AutoLoadPolicy = false; }); Assert.Empty(e.GetPolicy()); - e = DefaultEnforcer.Create(m, a); + e = new Enforcer(m, a); Assert.NotEmpty(e.GetPolicy()); } @@ -257,19 +257,11 @@ public void TestInOperator() _testModelFixture._rbacInOperatorModelText, _testModelFixture._rbacInOperatorPolicyText)); - TestEnforce(e, new - { - Name = "Alice", - Amount = 5100, - Roles = new string[] { "Manager", "DepartmentDirector" } - }, "authorization", "grant", true); + TestEnforce(e, new { Name = "Alice", Amount = 5100, Roles = new[] { "Manager", "DepartmentDirector" } }, + "authorization", "grant", true); - TestEnforce(e, new - { - Name = "Alice", - Amount = 5100, - Roles = new string[] { "DepartmentDirector" } - }, "authorization", "grant", false); + TestEnforce(e, new { Name = "Alice", Amount = 5100, Roles = new[] { "DepartmentDirector" } }, + "authorization", "grant", false); } [Fact] @@ -354,16 +346,16 @@ public void TestRbacBatchEnforceInMemory() IEnumerable<(RequestValues, bool)> testCases = new (RequestValues, bool)[] - { - (Request.CreateValues("alice", "data1", "read"), true), - (Request.CreateValues("alice", "data1", "write"), false), - (Request.CreateValues("alice", "data2", "read"), true), - (Request.CreateValues("alice", "data2", "write"), true), - (Request.CreateValues("bob", "data1", "read"), false), - (Request.CreateValues("bob", "data1", "write"), false), - (Request.CreateValues("bob", "data2", "read"), false), - (Request.CreateValues("bob", "data2", "write"), true) - }; + { + (Request.CreateValues("alice", "data1", "read"), true), + (Request.CreateValues("alice", "data1", "write"), false), + (Request.CreateValues("alice", "data2", "read"), true), + (Request.CreateValues("alice", "data2", "write"), true), + (Request.CreateValues("bob", "data1", "read"), false), + (Request.CreateValues("bob", "data1", "write"), false), + (Request.CreateValues("bob", "data2", "read"), false), + (Request.CreateValues("bob", "data2", "write"), true) + }; TestBatchEnforce(e, testCases); } @@ -388,16 +380,16 @@ public void TestRbacParallelBatchEnforceInMemory() IEnumerable<(RequestValues, bool)> testCases = new (RequestValues, bool)[] - { - (Request.CreateValues("alice", "data1", "read"), true), - (Request.CreateValues("alice", "data1", "write"), false), - (Request.CreateValues("alice", "data2", "read"), true), - (Request.CreateValues("alice", "data2", "write"), true), - (Request.CreateValues("bob", "data1", "read"), false), - (Request.CreateValues("bob", "data1", "write"), false), - (Request.CreateValues("bob", "data2", "read"), false), - (Request.CreateValues("bob", "data2", "write"), true) - }; + { + (Request.CreateValues("alice", "data1", "read"), true), + (Request.CreateValues("alice", "data1", "write"), false), + (Request.CreateValues("alice", "data2", "read"), true), + (Request.CreateValues("alice", "data2", "write"), true), + (Request.CreateValues("bob", "data1", "read"), false), + (Request.CreateValues("bob", "data1", "write"), false), + (Request.CreateValues("bob", "data2", "read"), false), + (Request.CreateValues("bob", "data2", "write"), true) + }; TestParallelBatchEnforce(e, testCases); } @@ -450,16 +442,16 @@ public void TestRbacBatchEnforceInMemoryAsync() IEnumerable<(RequestValues, bool)> testCases = new (RequestValues, bool)[] - { - (Request.CreateValues("alice", "data1", "read"), true), - (Request.CreateValues("alice", "data1", "write"), false), - (Request.CreateValues("alice", "data2", "read"), true), - (Request.CreateValues("alice", "data2", "write"), true), - (Request.CreateValues("bob", "data1", "read"), false), - (Request.CreateValues("bob", "data1", "write"), false), - (Request.CreateValues("bob", "data2", "read"), false), - (Request.CreateValues("bob", "data2", "write"), true) - }; + { + (Request.CreateValues("alice", "data1", "read"), true), + (Request.CreateValues("alice", "data1", "write"), false), + (Request.CreateValues("alice", "data2", "read"), true), + (Request.CreateValues("alice", "data2", "write"), true), + (Request.CreateValues("bob", "data1", "read"), false), + (Request.CreateValues("bob", "data1", "write"), false), + (Request.CreateValues("bob", "data2", "read"), false), + (Request.CreateValues("bob", "data2", "write"), true) + }; TestBatchEnforceAsync(e, testCases); } @@ -1178,16 +1170,16 @@ public void TestBatchEnforceWithMatcherApi() IEnumerable<(RequestValues, bool)> testCases = new (RequestValues, bool)[] - { - (Request.CreateValues("alice", "data1", "read"), false), - (Request.CreateValues("alice", "data1", "write"), false), - (Request.CreateValues("alice", "data2", "read"), false), - (Request.CreateValues("alice", "data2", "write"), true), - (Request.CreateValues("bob", "data1", "read"), true), - (Request.CreateValues("bob", "data1", "write"), false), - (Request.CreateValues("bob", "data2", "read"), false), - (Request.CreateValues("bob", "data2", "write"), false) - }; + { + (Request.CreateValues("alice", "data1", "read"), false), + (Request.CreateValues("alice", "data1", "write"), false), + (Request.CreateValues("alice", "data2", "read"), false), + (Request.CreateValues("alice", "data2", "write"), true), + (Request.CreateValues("bob", "data1", "read"), true), + (Request.CreateValues("bob", "data1", "write"), false), + (Request.CreateValues("bob", "data2", "read"), false), + (Request.CreateValues("bob", "data2", "write"), false) + }; e.TestBatchEnforceWithMatcher(matcher, testCases); } @@ -1200,16 +1192,16 @@ public void TestBatchEnforceWithMatcherParallel() IEnumerable<(RequestValues, bool)> testCases = new (RequestValues, bool)[] - { - (Request.CreateValues("alice", "data1", "read"), false), - (Request.CreateValues("alice", "data1", "write"), false), - (Request.CreateValues("alice", "data2", "read"), false), - (Request.CreateValues("alice", "data2", "write"), true), - (Request.CreateValues("bob", "data1", "read"), true), - (Request.CreateValues("bob", "data1", "write"), false), - (Request.CreateValues("bob", "data2", "read"), false), - (Request.CreateValues("bob", "data2", "write"), false) - }; + { + (Request.CreateValues("alice", "data1", "read"), false), + (Request.CreateValues("alice", "data1", "write"), false), + (Request.CreateValues("alice", "data2", "read"), false), + (Request.CreateValues("alice", "data2", "write"), true), + (Request.CreateValues("bob", "data1", "read"), true), + (Request.CreateValues("bob", "data1", "write"), false), + (Request.CreateValues("bob", "data2", "read"), false), + (Request.CreateValues("bob", "data2", "write"), false) + }; e.TestBatchEnforceWithMatcherParallel(matcher, testCases); } @@ -1238,16 +1230,16 @@ public void TestBatchEnforceWithMatcherApiAsync() IEnumerable<(RequestValues, bool)> testCases = new (RequestValues, bool)[] - { - (Request.CreateValues("alice", "data1", "read"), false), - (Request.CreateValues("alice", "data1", "write"), false), - (Request.CreateValues("alice", "data2", "read"), false), - (Request.CreateValues("alice", "data2", "write"), true), - (Request.CreateValues("bob", "data1", "read"), true), - (Request.CreateValues("bob", "data1", "write"), false), - (Request.CreateValues("bob", "data2", "read"), false), - (Request.CreateValues("bob", "data2", "write"), false) - }; + { + (Request.CreateValues("alice", "data1", "read"), false), + (Request.CreateValues("alice", "data1", "write"), false), + (Request.CreateValues("alice", "data2", "read"), false), + (Request.CreateValues("alice", "data2", "write"), true), + (Request.CreateValues("bob", "data1", "read"), true), + (Request.CreateValues("bob", "data1", "write"), false), + (Request.CreateValues("bob", "data2", "read"), false), + (Request.CreateValues("bob", "data2", "write"), false) + }; TestBatchEnforceWithMatcherAsync(e, matcher, testCases); } @@ -1288,3 +1280,5 @@ await e.TestEnforceExWithMatcherAsync(matcher, "bob", "data1", "read", #endregion } + + diff --git a/Casbin/Abstractions/IEnforcer.cs b/Casbin/Abstractions/IEnforcer.cs index a31edf3..4d2f8d5 100644 --- a/Casbin/Abstractions/IEnforcer.cs +++ b/Casbin/Abstractions/IEnforcer.cs @@ -22,18 +22,6 @@ namespace Casbin /// public interface IEnforcer { - public class EnforcerOptions - { - public bool Enabled { get; set; } = true; - public bool EnabledCache { get; set; } = true; - - public bool AutoBuildRoleLinks { get; set; } = true; - public bool AutoNotifyWatcher { get; set; } = true; - public bool AutoCleanEnforceCache { get; set; } = true; - public bool AutoLoadPolicy { get; set; } = true; - public Filter AutoLoadPolicyFilter { get; set; } = null; - } - /// /// Decides whether a "subject" can access a "object" with the operation /// "action", input parameters are usually: (sub, obj, act). @@ -88,7 +76,6 @@ public BatchEnforceAsyncResults BatchEnforceAsync(EnforceContext conte #region Options - public EnforcerOptions Options { get; set; } public bool Enabled { get; set; } public bool EnabledCache { get; set; } public bool AutoBuildRoleLinks { get; set; } diff --git a/Casbin/Abstractions/Persist/IFilteredAdapter.cs b/Casbin/Abstractions/Persist/IFilteredAdapter.cs index b591040..7d4f301 100644 --- a/Casbin/Abstractions/Persist/IFilteredAdapter.cs +++ b/Casbin/Abstractions/Persist/IFilteredAdapter.cs @@ -7,8 +7,8 @@ public interface IFilteredAdapter { bool IsFiltered { get; } - void LoadFilteredPolicy(IPolicyStore store, Filter filter); + void LoadFilteredPolicy(IPolicyStore store, IPolicyFilter filter); - Task LoadFilteredPolicyAsync(IPolicyStore store, Filter filter); + Task LoadFilteredPolicyAsync(IPolicyStore store, IPolicyFilter filter); } } diff --git a/Casbin/Adapter/File/FileAdapter.cs b/Casbin/Adapter/File/FileAdapter.cs index a068a25..09aa3fa 100644 --- a/Casbin/Adapter/File/FileAdapter.cs +++ b/Casbin/Adapter/File/FileAdapter.cs @@ -8,155 +8,155 @@ using Casbin.Model; using Casbin.Persist; -namespace Casbin.Adapter.File +namespace Casbin.Adapter.File; + +public class FileAdapter : IEpochAdapter { - public class FileAdapter : IEpochAdapter + private readonly StreamReader _byteArrayInputStream; + private readonly bool _readOnly; + protected readonly string FilePath; + + public FileAdapter(string filePath) => FilePath = filePath; + + public FileAdapter(System.IO.Stream inputStream) { - private readonly StreamReader _byteArrayInputStream; - private readonly bool _readOnly; - protected readonly string FilePath; + _readOnly = true; + try + { + _byteArrayInputStream = new StreamReader(inputStream); + } + catch (IOException e) + { + throw new IOException("File adapter init error", e); + } + } - public FileAdapter(string filePath) + public void LoadPolicy(IPolicyStore model) + { + if (string.IsNullOrWhiteSpace(FilePath) is false) { - FilePath = filePath; + using StreamReader sr = new StreamReader(new FileStream( + FilePath, FileMode.Open, FileAccess.Read, FileShare.Read)); + LoadPolicyLine(model, sr); } - public FileAdapter(Stream inputStream) + if (_byteArrayInputStream is not null) { - _readOnly = true; - try - { - _byteArrayInputStream = new StreamReader(inputStream); - } - catch (IOException e) - { - throw new IOException("File adapter init error", e); - } + LoadPolicyLine(model, _byteArrayInputStream); } + } - public void LoadPolicy(IPolicyStore model) + public async Task LoadPolicyAsync(IPolicyStore store) + { + if (string.IsNullOrWhiteSpace(FilePath) is false) { - if (string.IsNullOrWhiteSpace(FilePath) is false) - { - using var sr = new StreamReader(new FileStream( - FilePath, FileMode.Open, FileAccess.Read, FileShare.Read)); - LoadPolicyData(model, sr); - } - - if (_byteArrayInputStream is not null) - { - LoadPolicyData(model, _byteArrayInputStream); - } + using StreamReader sr = new StreamReader(new FileStream( + FilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); + await LoadPolicyLineAsync(store, sr); + Debug.WriteLine("xxx"); } - public async Task LoadPolicyAsync(IPolicyStore store) + if (_byteArrayInputStream is not null) { - if (string.IsNullOrWhiteSpace(FilePath) is false) - { - using var sr = new StreamReader(new FileStream( - FilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); - await LoadPolicyDataAsync(store, sr); - Debug.WriteLine("xxx"); - } - - if (_byteArrayInputStream is not null) - { - await LoadPolicyDataAsync(store, _byteArrayInputStream); - } + await LoadPolicyLineAsync(store, _byteArrayInputStream); } + } - public void SavePolicy(IPolicyStore store) + public void SavePolicy(IPolicyStore store) + { + if (_byteArrayInputStream != null && _readOnly) { - if (_byteArrayInputStream != null && _readOnly) - { - throw new Exception("Store file can not write, because use inputStream is readOnly"); - } - - if (string.IsNullOrWhiteSpace(FilePath)) - { - throw new ArgumentException("Invalid file path, file path cannot be empty"); - } - - var policy = ConvertToPolicyStrings(store); - SavePolicyFile(string.Join("\n", policy)); + throw new Exception("Store file can not write, because use inputStream is readOnly"); } - public Task SavePolicyAsync(IPolicyStore store) + if (string.IsNullOrWhiteSpace(FilePath)) { - if (_byteArrayInputStream != null && _readOnly) - { - throw new Exception("Store file can not write, because use inputStream is readOnly"); - } - - if (string.IsNullOrWhiteSpace(FilePath)) - { - throw new ArgumentException("Invalid file path, file path cannot be empty"); - } - - var policy = ConvertToPolicyStrings(store); - return SavePolicyFileAsync(string.Join("\n", policy)); + throw new ArgumentException("Invalid file path, file path cannot be empty"); } - private static IEnumerable GetModelPolicy(IPolicyStore store, string section) + IEnumerable policy = ConvertToPolicyStrings(store); + SavePolicyFile(string.Join("\n", policy)); + } + + public Task SavePolicyAsync(IPolicyStore store) + { + if (_byteArrayInputStream != null && _readOnly) { - var policy = new List(); - foreach (KeyValuePair> kv in store.GetPolicyAllType(section)) - { - string key = kv.Key; - IEnumerable value = kv.Value; - policy.AddRange(value.Select(p => $"{key}, {p.ToText()}")); - } - - return policy; + throw new Exception("Store file can not write, because use inputStream is readOnly"); } - private static void LoadPolicyData(IPolicyStore store, StreamReader inputStream) + if (string.IsNullOrWhiteSpace(FilePath)) { - while (inputStream.EndOfStream is false) - { - string line = inputStream.ReadLine(); - store.TryLoadPolicyLine(line); - } + throw new ArgumentException("Invalid file path, file path cannot be empty"); } - private static async Task LoadPolicyDataAsync(IPolicyStore store, StreamReader inputStream) + IEnumerable policy = ConvertToPolicyStrings(store); + return SavePolicyFileAsync(string.Join("\n", policy)); + } + + private static IEnumerable GetModelPolicy(IPolicyStore store, string section) + { + List policy = new List(); + foreach (KeyValuePair> kv in store.GetPolicyAllType(section)) { - while (inputStream.EndOfStream is false) - { - string line = await inputStream.ReadLineAsync(); - store.TryLoadPolicyLine(line); - } + string key = kv.Key; + IEnumerable value = kv.Value; + policy.AddRange(value.Select(p => $"{key}, {p.ToText()}")); } - private static IEnumerable ConvertToPolicyStrings(IPolicyStore store) + return policy; + } + + private static void LoadPolicyLine(IPolicyStore store, StreamReader inputStream) + { + while (inputStream.EndOfStream is false) { - var policy = new List(); - if (store.ContainsNodes(PermConstants.Section.PolicySection)) - { - policy.AddRange(GetModelPolicy(store, PermConstants.Section.PolicySection)); - } - - if (store.ContainsNodes(PermConstants.Section.RoleSection)) - { - policy.AddRange(GetModelPolicy(store, PermConstants.Section.RoleSection)); - } - - return policy; + string line = inputStream.ReadLine(); + store.TryLoadPolicyLine(line); } + } + + private static async Task LoadPolicyLineAsync(IPolicyStore store, StreamReader inputStream) + { + while (inputStream.EndOfStream is false) + { + string line = await inputStream.ReadLineAsync(); + store.TryLoadPolicyLine(line); + } + } - private void SavePolicyFile(string text) + private static IEnumerable ConvertToPolicyStrings(IPolicyStore store) + { + List policy = new List(); + if (store.ContainsNodes(PermConstants.Section.PolicySection)) { - System.IO.File.WriteAllText(FilePath, text, Encoding.UTF8); + policy.AddRange(GetModelPolicy(store, PermConstants.Section.PolicySection)); } - private async Task SavePolicyFileAsync(string text) + if (store.ContainsNodes(PermConstants.Section.RoleSection)) { - text = text ?? string.Empty; - byte[] content = Encoding.UTF8.GetBytes(text); + policy.AddRange(GetModelPolicy(store, PermConstants.Section.RoleSection)); + } + + return policy; + } + + private void SavePolicyFile(string text) => System.IO.File.WriteAllText(FilePath, text, Encoding.UTF8); + + private async Task SavePolicyFileAsync(string text) + { + text ??= string.Empty; + byte[] content = Encoding.UTF8.GetBytes(text); +#if !NETFRAMEWORK && !NETSTANDARD2_0 + await using FileStream fs = new( + FilePath, FileMode.Create, FileAccess.Write, + FileShare.None, 4096, true); +#else using var fs = new FileStream( FilePath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 4096, useAsync: true); - await fs.WriteAsync(content, 0, content.Length); - } +#endif + await fs.WriteAsync(content, 0, content.Length); } } + diff --git a/Casbin/Adapter/File/FileFilteredAdapter.cs b/Casbin/Adapter/File/FileFilteredAdapter.cs index 8f11a61..fc6b9fb 100644 --- a/Casbin/Adapter/File/FileFilteredAdapter.cs +++ b/Casbin/Adapter/File/FileFilteredAdapter.cs @@ -6,133 +6,107 @@ using Casbin.Model; using Casbin.Persist; -namespace Casbin.Adapter.File +namespace Casbin.Adapter.File; + +public class FileFilteredAdapter : FileAdapter, IFilteredAdapter { - public class FileFilteredAdapter : FileAdapter, IFilteredAdapter + public FileFilteredAdapter(string filePath) : base(filePath) { - public bool IsFiltered { get; private set; } + } - public FileFilteredAdapter(string filePath) : base(filePath) - { - } + public FileFilteredAdapter(System.IO.Stream inputStream) : base(inputStream) + { + } - public FileFilteredAdapter(Stream inputStream) : base(inputStream) - { - } + public bool IsFiltered { get; private set; } - public void LoadFilteredPolicy(IPolicyStore store, Filter filter) + public void LoadFilteredPolicy(IPolicyStore store, IPolicyFilter filter) + { + if (filter is null) { - if (filter is null) - { - LoadPolicy(store); - return; - } - - if (string.IsNullOrWhiteSpace(FilePath)) - { - throw new InvalidOperationException("invalid file path, file path cannot be empty"); - } - - LoadFilteredPolicyFile(store, filter); + LoadPolicy(store); + return; } - public Task LoadFilteredPolicyAsync(IPolicyStore store, Filter filter) + if (string.IsNullOrWhiteSpace(FilePath)) { - if (filter is null) - { - return LoadPolicyAsync(store); - } - - if (string.IsNullOrWhiteSpace(FilePath)) - { - throw new InvalidOperationException("invalid file path, file path cannot be empty"); - } - - return LoadFilteredPolicyFileAsync(store, filter); + throw new InvalidOperationException("invalid file path, file path cannot be empty"); } - private void LoadFilteredPolicyFile(IPolicyStore store, Filter filter) + LoadFilteredPolicyFile(store, filter); + } + + public Task LoadFilteredPolicyAsync(IPolicyStore store, IPolicyFilter filter) + { + if (filter is null) { - var reader = new StreamReader(new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); - while (reader.EndOfStream is false) - { - string line = reader.ReadLine()?.Trim(); - if (string.IsNullOrWhiteSpace(line) || FilterLine(line, filter)) - { - return; - } - store.TryLoadPolicyLine(line); - } - IsFiltered = true; + return LoadPolicyAsync(store); } - private async Task LoadFilteredPolicyFileAsync(IPolicyStore store, Filter filter) + if (string.IsNullOrWhiteSpace(FilePath)) { - var reader = new StreamReader(new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); - while (reader.EndOfStream is false) - { - string line = (await reader.ReadLineAsync())?.Trim(); - if (string.IsNullOrWhiteSpace(line) || FilterLine(line, filter)) - { - return; - } - store.TryLoadPolicyLine(line); - } - IsFiltered = true; + throw new InvalidOperationException("invalid file path, file path cannot be empty"); } - private static bool FilterLine(string line, Filter filter) - { - if (filter == null) - { - return false; - } + return LoadFilteredPolicyFileAsync(store, filter); + } - string[] p = line.Split(','); - if (p.Length == 0) - { - return true; - } + public void LoadFilteredPolicy(IPolicyStore store, Filter filter) + { + IPolicyFilter policyFilter = filter; + LoadFilteredPolicy(store, policyFilter); + } - IEnumerable filterSlice = new List(); - switch (p[0].Trim()) - { - case PermConstants.DefaultPolicyType: - filterSlice = filter.P; - break; - case PermConstants.DefaultGroupingPolicyType: - filterSlice = filter.G; - break; - } + public Task LoadFilteredPolicyAsync(IPolicyStore store, Filter filter) + { + IPolicyFilter policyFilter = filter; + return LoadFilteredPolicyAsync(store, policyFilter); + } - return FilterWords(p, filterSlice); + private void LoadFilteredPolicyFile(IPolicyStore store, IPolicyFilter filter) + { + IEnumerable policies = ReadPersistantPolicy(FilePath); + policies = filter.ApplyFilter(policies.AsQueryable()); + foreach (IPersistantPolicy policy in policies) + { + string section = policy.Type.Substring(0, 1); + store.AddPolicy(section, policy.Type, policy.Values); } - private static bool FilterWords(string[] line, IEnumerable filter) - { - string[] filterArray = filter.ToArray(); - int length = filterArray.Length; + IsFiltered = true; + } + + private Task LoadFilteredPolicyFileAsync(IPolicyStore store, IPolicyFilter filter) + { + LoadFilteredPolicyFile(store, filter); +#if NET452 + return Task.FromResult(true); +#else + return Task.CompletedTask; +#endif + } - if (line.Length < length + 1) + private static IEnumerable ReadPersistantPolicy(string filePath) + { + using StreamReader reader = new(new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); + while (reader.EndOfStream is false) + { + string line = reader.ReadLine(); + if (string.IsNullOrWhiteSpace(line)) { - return true; + continue; } - bool skipLine = false; - for (int i = 0; i < length; i++) + if (line.StartsWith("/") || line.StartsWith("#")) { - string current = filterArray.ElementAt(i).Trim(); - string next = filterArray.ElementAt(i + 1); - - if (string.IsNullOrEmpty(current) || current == next) - { - continue; - } - - skipLine = true; - break; + continue; } - return skipLine; + + string[] tokens = line.Split(PermConstants.PolicySeparatorChar).Select(x => x.Trim()).ToArray(); + string type = tokens[0]; + IPolicyValues values = Policy.ValuesFrom(tokens.Skip(1)); + yield return new PersistantPolicy(type, values); } } } + diff --git a/Casbin/Adapter/Stream/StreamAdapter.cs b/Casbin/Adapter/Stream/StreamAdapter.cs index 2a27a14..03f6793 100644 --- a/Casbin/Adapter/Stream/StreamAdapter.cs +++ b/Casbin/Adapter/Stream/StreamAdapter.cs @@ -1,152 +1,137 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Linq; -using System.Text; using System.Threading.Tasks; using Casbin.Model; using Casbin.Persist; -namespace Casbin.Adapter.File +namespace Casbin.Adapter.Stream; + +internal class StreamAdapter : IEpochAdapter { - public class StreamAdapter : IEpochAdapter + protected readonly System.IO.Stream InputStream; + protected readonly System.IO.Stream OutputStream; + + public StreamAdapter(System.IO.Stream inputStream, System.IO.Stream outputStream) + { + InputStream = inputStream; + OutputStream = outputStream; + } + + public void LoadPolicy(IPolicyStore store) { - protected readonly Stream _byteArrayInputStream; - protected readonly Stream _byteArrayOutputStream; - public StreamAdapter(Stream inputStream, Stream outputStream) + using StreamReader streamReader = new StreamReader(InputStream); + if (InputStream is not null) { - _byteArrayInputStream = inputStream; - _byteArrayOutputStream = outputStream; + LoadPolicyData(store, streamReader); } + } - public void LoadPolicy(IPolicyStore store) + public async Task LoadPolicyAsync(IPolicyStore store) + { + using StreamReader streamReader = new StreamReader(InputStream); + if (InputStream is not null) { - try - { - var streamReader = new StreamReader(_byteArrayInputStream); - if (_byteArrayInputStream is not null) - { - LoadPolicyData(store, streamReader); - } - streamReader.Dispose(); - } - catch (Exception) - { - - } + await LoadPolicyDataAsync(store, streamReader); } + } - public async Task LoadPolicyAsync(IPolicyStore store) + public void SavePolicy(IPolicyStore store) + { + if (OutputStream is null) { - try - { - var streamReader = new StreamReader(_byteArrayInputStream); - if (_byteArrayInputStream is not null) - { - await LoadPolicyDataAsync(store, streamReader); - } - streamReader.Dispose(); - } - catch (Exception) - { - - } + throw new Exception("Store file can not write, because use outputStream has not been set."); } - public void SavePolicy(IPolicyStore store) - { - if (_byteArrayOutputStream is null) - { - throw new Exception("Store file can not write, because use outputStream has not been set."); - } + IEnumerable policy = ConvertToPolicyStrings(store); + SavePolicyFile(string.Join("\n", policy)); + } - var policy = ConvertToPolicyStrings(store); - SavePolicyFile(string.Join("\n", policy)); + public Task SavePolicyAsync(IPolicyStore store) + { + if (OutputStream is null) + { + throw new Exception("Store file can not write, because use outputStream has not been set."); } - public Task SavePolicyAsync(IPolicyStore store) + IEnumerable policy = ConvertToPolicyStrings(store); + return SavePolicyFileAsync(string.Join("\n", policy)); + } + + private static IEnumerable GetModelPolicy(IPolicyStore store, string section) + { + List policy = new List(); + foreach (KeyValuePair> kv in store.GetPolicyAllType(section)) { - if (_byteArrayOutputStream is null) - { - throw new Exception("Store file can not write, because use outputStream has not been set."); - } + string key = kv.Key; + IEnumerable value = kv.Value; + policy.AddRange(value.Select(p => $"{key}, {p.ToText()}")); + } + + return policy; + } - var policy = ConvertToPolicyStrings(store); - return SavePolicyFileAsync(string.Join("\n", policy)); + private static void LoadPolicyData(IPolicyStore store, StreamReader inputStream) + { + if (inputStream.EndOfStream is true) + { + inputStream.BaseStream.Position = 0; } - private static IEnumerable GetModelPolicy(IPolicyStore store, string section) + while (inputStream.EndOfStream is false) { - var policy = new List(); - foreach (var kv in store.GetPolicyAllType(section)) - { - var key = kv.Key; - var value = kv.Value; - policy.AddRange(value.Select(p => $"{key}, {p.ToText()}")); - } - - return policy; + string line = inputStream.ReadLine(); + store.TryLoadPolicyLine(line); } + } - private static void LoadPolicyData(IPolicyStore store, StreamReader inputStream) + private static async Task LoadPolicyDataAsync(IPolicyStore store, StreamReader inputStream) + { + if (inputStream.EndOfStream is true) { - if (inputStream.EndOfStream is true) - { - inputStream.BaseStream.Position = 0; - } - while (inputStream.EndOfStream is false) - { - string line = inputStream.ReadLine(); - store.TryLoadPolicyLine(line); - } + inputStream.BaseStream.Position = 0; } - private static async Task LoadPolicyDataAsync(IPolicyStore store, StreamReader inputStream) + while (inputStream.EndOfStream is false) { - if (inputStream.EndOfStream is true) - { - inputStream.BaseStream.Position = 0; - } - while (inputStream.EndOfStream is false) - { - string line = await inputStream.ReadLineAsync(); - store.TryLoadPolicyLine(line); - } + string line = await inputStream.ReadLineAsync(); + store.TryLoadPolicyLine(line); } + } - private static IEnumerable ConvertToPolicyStrings(IPolicyStore store) + private static IEnumerable ConvertToPolicyStrings(IPolicyStore store) + { + List policy = new List(); + if (store.ContainsNodes(PermConstants.Section.PolicySection)) { - var policy = new List(); - if (store.ContainsNodes(PermConstants.Section.PolicySection)) - { - policy.AddRange(GetModelPolicy(store, PermConstants.Section.PolicySection)); - } - - if (store.ContainsNodes(PermConstants.Section.RoleSection)) - { - policy.AddRange(GetModelPolicy(store, PermConstants.Section.RoleSection)); - } - - return policy; + policy.AddRange(GetModelPolicy(store, PermConstants.Section.PolicySection)); } - private void SavePolicyFile(string text) + if (store.ContainsNodes(PermConstants.Section.RoleSection)) { - var streamWriter = new StreamWriter(_byteArrayOutputStream); + policy.AddRange(GetModelPolicy(store, PermConstants.Section.RoleSection)); + } + + return policy; + } + + private void SavePolicyFile(string text) + { + StreamWriter streamWriter = new StreamWriter(OutputStream); #if (NET6_0 || NET5_0 || NETCOREAPP3_1) streamWriter.Write(text.AsSpan()); #else - streamWriter.Write(text.ToCharArray()); + streamWriter.Write(text.ToCharArray()); #endif - streamWriter.Dispose(); - } + streamWriter.Dispose(); + } - private async Task SavePolicyFileAsync(string text) - { - var streamWriter = new StreamWriter(_byteArrayOutputStream); - await streamWriter.WriteAsync(text); - streamWriter.Dispose(); - } + private async Task SavePolicyFileAsync(string text) + { + StreamWriter streamWriter = new StreamWriter(OutputStream); + await streamWriter.WriteAsync(text); + streamWriter.Dispose(); } } + diff --git a/Casbin/Adapter/Stream/StreamFilteredAdapter.cs b/Casbin/Adapter/Stream/StreamFilteredAdapter.cs index 60ffd2c..e872541 100644 --- a/Casbin/Adapter/Stream/StreamFilteredAdapter.cs +++ b/Casbin/Adapter/Stream/StreamFilteredAdapter.cs @@ -1,124 +1,86 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using Casbin.Model; using Casbin.Persist; -namespace Casbin.Adapter.File +namespace Casbin.Adapter.Stream; + +internal class StreamFilteredAdapter : StreamAdapter, IFilteredAdapter { - public class StreamFilteredAdapter : StreamAdapter, IFilteredAdapter + public StreamFilteredAdapter(System.IO.Stream inputStream, System.IO.Stream outputStream) : base(inputStream, + outputStream) { - public bool IsFiltered { get; private set; } + } - public StreamFilteredAdapter(Stream inputStream, Stream outputStream) : base(inputStream, outputStream) - { - } + public bool IsFiltered { get; private set; } - public void LoadFilteredPolicy(IPolicyStore store, Filter filter) + public void LoadFilteredPolicy(IPolicyStore store, IPolicyFilter filter) + { + if (filter is null) { - if (filter is null) - { - LoadPolicy(store); - return; - } - - LoadFilteredPolicyFile(store, filter); + LoadPolicy(store); + return; } - public Task LoadFilteredPolicyAsync(IPolicyStore store, Filter filter) - { - if (filter is null) - { - return LoadPolicyAsync(store); - } - - return LoadFilteredPolicyFileAsync(store, filter); - } + LoadFilteredPolicyFile(store, filter); + } - private void LoadFilteredPolicyFile(IPolicyStore store, Filter filter) + public Task LoadFilteredPolicyAsync(IPolicyStore store, IPolicyFilter filter) + { + if (filter is null) { - var reader = new StreamReader(_byteArrayInputStream); - while (reader.EndOfStream is false) - { - string line = reader.ReadLine()?.Trim(); - if (string.IsNullOrWhiteSpace(line) || FilterLine(line, filter)) - { - return; - } - store.TryLoadPolicyLine(line); - } - IsFiltered = true; + return LoadPolicyAsync(store); } - private async Task LoadFilteredPolicyFileAsync(IPolicyStore store, Filter filter) - { - var reader = new StreamReader(_byteArrayInputStream); - while (reader.EndOfStream is false) - { - string line = (await reader.ReadLineAsync())?.Trim(); - if (string.IsNullOrWhiteSpace(line) || FilterLine(line, filter)) - { - return; - } - store.TryLoadPolicyLine(line); - } - IsFiltered = true; - } + return LoadFilteredPolicyFileAsync(store, filter); + } - private static bool FilterLine(string line, Filter filter) + private void LoadFilteredPolicyFile(IPolicyStore store, IPolicyFilter filter) + { + IEnumerable policies = ReadPersistantPolicy(InputStream); + policies = filter.ApplyFilter(policies.AsQueryable()); + foreach (IPersistantPolicy policy in policies) { - if (filter == null) - { - return false; - } - - string[] p = line.Split(','); - if (p.Length == 0) - { - return true; - } + string section = policy.Type.Substring(0, 1); + store.AddPolicy(section, policy.Type, policy.Values); + } - IEnumerable filterSlice = new List(); - switch (p[0].Trim()) - { - case PermConstants.DefaultPolicyType: - filterSlice = filter.P; - break; - case PermConstants.DefaultGroupingPolicyType: - filterSlice = filter.G; - break; - } + IsFiltered = true; + } - return FilterWords(p, filterSlice); - } + private Task LoadFilteredPolicyFileAsync(IPolicyStore store, IPolicyFilter filter) + { + LoadFilteredPolicyFile(store, filter); +#if NET452 + return Task.FromResult(true); +#else + return Task.CompletedTask; +#endif + } - private static bool FilterWords(string[] line, IEnumerable filter) + private static IEnumerable ReadPersistantPolicy(System.IO.Stream inputStream) + { + using StreamReader reader = new(inputStream); + while (reader.EndOfStream is false) { - string[] filterArray = filter.ToArray(); - int length = filterArray.Length; - - if (line.Length < length + 1) + string line = reader.ReadLine(); + if (string.IsNullOrWhiteSpace(line)) { - return true; + continue; } - bool skipLine = false; - for (int i = 0; i < length; i++) + if (line.StartsWith("/") || line.StartsWith("#")) { - string current = filterArray.ElementAt(i).Trim(); - string next = filterArray.ElementAt(i + 1); - - if (string.IsNullOrEmpty(current) || current == next) - { - continue; - } - - skipLine = true; - break; + continue; } - return skipLine; + + string[] tokens = line.Split(PermConstants.PolicySeparatorChar).Select(x => x.Trim()).ToArray(); + string type = tokens[0]; + IPolicyValues values = Policy.ValuesFrom(tokens.Skip(1)); + yield return new PersistantPolicy(type, values); } } } + diff --git a/Casbin/DefaultEnforcer.cs b/Casbin/DefaultEnforcer.cs deleted file mode 100644 index cf633ba..0000000 --- a/Casbin/DefaultEnforcer.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using Casbin.Model; -using Casbin.Persist; - -namespace Casbin -{ - public static class DefaultEnforcer - { - public static IEnforcer Create(IReadOnlyAdapter adapter = null, Action optionSettings = null) - { - return new Enforcer(DefaultModel.Create(), adapter, optionSettings); - } - - public static IEnforcer Create(string modelPath, string policyPath, Action optionSettings = null) - { - return new Enforcer(modelPath, policyPath, optionSettings); - } - - public static IEnforcer Create(string modelPath, IReadOnlyAdapter adapter = null, Action optionSettings = null) - { - return new Enforcer(modelPath, adapter, optionSettings); - } - - public static IEnforcer Create(IModel model, IReadOnlyAdapter adapter = null, Action optionSettings = null) - { - return new Enforcer(model, adapter, optionSettings); - } - } -} diff --git a/Casbin/Enforcer.Internal.cs b/Casbin/Enforcer.Internal.cs index e498ccd..c7d58dc 100644 --- a/Casbin/Enforcer.Internal.cs +++ b/Casbin/Enforcer.Internal.cs @@ -333,3 +333,5 @@ private static string RewriteInOperator(in EnforceContext context, string expres return expressionString; } } + + diff --git a/Casbin/Enforcer.cs b/Casbin/Enforcer.cs index 54b92a5..ae7b827 100644 --- a/Casbin/Enforcer.cs +++ b/Casbin/Enforcer.cs @@ -18,33 +18,42 @@ public Enforcer() { } - public Enforcer(string modelPath, string policyPath, Action optionSettings = null) + public Enforcer(string modelPath, string policyPath, Action optionSettings = null) : this(modelPath, new FileAdapter(policyPath), optionSettings) { } - public Enforcer(string modelPath, IReadOnlyAdapter adapter = null, Action optionSettings = null) + public Enforcer(string modelPath, IReadOnlyAdapter adapter = null, + Action optionSettings = null) : this(DefaultModel.CreateFromFile(modelPath), adapter, optionSettings) { } - public Enforcer(IModel model, IReadOnlyAdapter adapter = null, Action optionSettings = null) + public Enforcer(IModel model, IReadOnlyAdapter adapter = null, Action optionSettings = null) { - if(optionSettings is not null) + EnforcerOptions options = new(); + if (optionSettings is not null) { - optionSettings(Options); + optionSettings(options); } + + Enabled = options.Enabled; + EnabledCache = options.EnabledCache; + AutoNotifyWatcher = options.AutoNotifyWatcher; + AutoBuildRoleLinks = options.AutoBuildRoleLinks; + AutoCleanEnforceCache = options.AutoCleanEnforceCache; + this.SetModel(model); if (adapter is not null) { this.SetAdapter(adapter); } - if (Options.AutoLoadPolicy is true) + if (options.AutoLoadPolicy) { - if(Adapter is IFilteredAdapter && Options.AutoLoadPolicyFilter is not null) + if (Adapter is IFilteredAdapter && options.AutoLoadPolicyFilter is not null) { - this.LoadFilteredPolicy(Options.AutoLoadPolicyFilter); + this.LoadFilteredPolicy(options.AutoLoadPolicyFilter); } else { @@ -57,12 +66,11 @@ public Enforcer(IModel model, IReadOnlyAdapter adapter = null, Action Options.Enabled; set => Options.Enabled = value; } - public bool EnabledCache { get => Options.EnabledCache; set => Options.EnabledCache = value; } - public bool AutoBuildRoleLinks { get => Options.AutoBuildRoleLinks; set => Options.AutoBuildRoleLinks = value; } - public bool AutoNotifyWatcher { get => Options.AutoNotifyWatcher; set => Options.AutoNotifyWatcher = value; } - public bool AutoCleanEnforceCache { get => Options.AutoCleanEnforceCache; set => Options.AutoCleanEnforceCache = value; } + public bool Enabled { get; set; } + public bool EnabledCache { get; set; } + public bool AutoBuildRoleLinks { get; set; } + public bool AutoNotifyWatcher { get; set; } + public bool AutoCleanEnforceCache { get; set; } #endregion @@ -115,12 +123,12 @@ public bool Enforce(EnforceContext context, TRequest requestValues) wh return InternalEnforce(in context, in requestValues); } - if (Options.Enabled is false) + if (Enabled is false) { return true; } - if (Options.EnabledCache) + if (EnabledCache) { if (EnforceCache.TryGetResult(requestValues, out bool cachedResult)) { @@ -133,7 +141,7 @@ public bool Enforce(EnforceContext context, TRequest requestValues) wh bool result = InternalEnforce(in context, in requestValues); - if (Options.EnabledCache) + if (EnabledCache) { EnforceCache.TrySetResult(requestValues, result); } @@ -159,12 +167,12 @@ public async Task EnforceAsync(EnforceContext context, TRequest return await InternalEnforceAsync(context, requestValues); } - if (Options.Enabled is false) + if (Enabled is false) { return true; } - if (Options.EnabledCache) + if (EnabledCache) { bool? cachedResult = await EnforceCache.TryGetResultAsync(requestValues); if (cachedResult.HasValue) @@ -179,7 +187,7 @@ public async Task EnforceAsync(EnforceContext context, TRequest context.HandleOptionAndCached = true; bool result = await InternalEnforceAsync(context, requestValues); - if (Options.EnabledCache) + if (EnabledCache) { await EnforceCache.TrySetResultAsync(requestValues, result); } diff --git a/Casbin/Extensions/Enforcer/EnforcerExtension.cs b/Casbin/Extensions/Enforcer/EnforcerExtension.cs index 6f2db3d..6f18bcb 100644 --- a/Casbin/Extensions/Enforcer/EnforcerExtension.cs +++ b/Casbin/Extensions/Enforcer/EnforcerExtension.cs @@ -42,7 +42,7 @@ public static void LoadModel(this IEnforcer enforcer) /// public static IEnforcer EnableEnforce(this IEnforcer enforcer, bool enable) { - enforcer.Options.Enabled = enable; + enforcer.Enabled = enable; return enforcer; } @@ -66,7 +66,7 @@ public static IEnforcer EnableAutoSave(this IEnforcer enforcer, bool autoSave) /// Whether to automatically build the role links. public static IEnforcer EnableAutoBuildRoleLinks(this IEnforcer enforcer, bool autoBuildRoleLinks) { - enforcer.Options.AutoBuildRoleLinks = autoBuildRoleLinks; + enforcer.AutoBuildRoleLinks = autoBuildRoleLinks; return enforcer; } @@ -78,19 +78,19 @@ public static IEnforcer EnableAutoBuildRoleLinks(this IEnforcer enforcer, bool a /// Whether to automatically notify watcher. public static IEnforcer EnableAutoNotifyWatcher(this IEnforcer enforcer, bool autoNotifyWatcher) { - enforcer.Options.AutoNotifyWatcher = autoNotifyWatcher; + enforcer.AutoNotifyWatcher = autoNotifyWatcher; return enforcer; } public static IEnforcer EnableCache(this IEnforcer enforcer, bool enableCache) { - enforcer.Options.EnabledCache = enableCache; + enforcer.EnabledCache = enableCache; return enforcer; } public static IEnforcer EnableAutoCleanEnforceCache(this IEnforcer enforcer, bool autoCleanEnforceCache) { - enforcer.Options.AutoCleanEnforceCache = autoCleanEnforceCache; + enforcer.AutoCleanEnforceCache = autoCleanEnforceCache; return enforcer; } @@ -186,7 +186,7 @@ public static bool LoadPolicy(this IEnforcer enforcer) enforcer.ClearCache(); enforcer.Model.SortPolicy(); - if (enforcer.Options.AutoBuildRoleLinks) + if (enforcer.AutoBuildRoleLinks) { enforcer.BuildRoleLinks(); } @@ -207,7 +207,7 @@ public static async Task LoadPolicyAsync(this IEnforcer enforcer) enforcer.ClearCache(); enforcer.Model.SortPolicy(); - if (enforcer.Options.AutoBuildRoleLinks) + if (enforcer.AutoBuildRoleLinks) { enforcer.BuildRoleLinks(); } @@ -221,7 +221,7 @@ public static async Task LoadPolicyAsync(this IEnforcer enforcer) /// /// The filter used to specify which type of policy should be loaded. /// - public static bool LoadFilteredPolicy(this IEnforcer enforcer, Filter filter) + public static bool LoadFilteredPolicy(this IEnforcer enforcer, IPolicyFilter filter) { bool result = enforcer.Model.LoadFilteredPolicy(filter); if (result is false) @@ -229,7 +229,7 @@ public static bool LoadFilteredPolicy(this IEnforcer enforcer, Filter filter) return false; } - if (enforcer.Options.AutoBuildRoleLinks) + if (enforcer.AutoBuildRoleLinks) { enforcer.BuildRoleLinks(); } @@ -251,7 +251,7 @@ public static async Task LoadFilteredPolicyAsync(this IEnforcer enforcer, return false; } - if (enforcer.Options.AutoBuildRoleLinks) + if (enforcer.AutoBuildRoleLinks) { enforcer.BuildRoleLinks(); } @@ -336,7 +336,7 @@ public static void SetRoleManager(this IEnforcer enforcer, IRoleManager roleMana public static void SetRoleManager(this IEnforcer enforcer, string roleType, IRoleManager roleManager) { enforcer.Model.SetRoleManager(roleType, roleManager); - if (enforcer.Options.AutoBuildRoleLinks) + if (enforcer.AutoBuildRoleLinks) { enforcer.BuildRoleLinks(); } diff --git a/Casbin/Extensions/Enforcer/InternalEnforcerExtension.Events.cs b/Casbin/Extensions/Enforcer/InternalEnforcerExtension.Events.cs index 8b3fccf..cbd6c86 100644 --- a/Casbin/Extensions/Enforcer/InternalEnforcerExtension.Events.cs +++ b/Casbin/Extensions/Enforcer/InternalEnforcerExtension.Events.cs @@ -71,7 +71,7 @@ internal static void TryBuildIncrementalRoleLinks(this IEnforcer enforcer, Polic internal static void TryCleanEnforceCache(this IEnforcer enforcer) { - if (enforcer.Options.AutoCleanEnforceCache) + if (enforcer.AutoCleanEnforceCache) { enforcer.ClearCache(); } @@ -80,7 +80,7 @@ internal static void TryCleanEnforceCache(this IEnforcer enforcer) internal static void TryNotifyPolicyChanged(this IEnforcer enforcer, PolicyChangedMessage message) { // ReSharper disable once InvertIf - if (enforcer.Options.AutoNotifyWatcher && enforcer.Watcher is not null) + if (enforcer.AutoNotifyWatcher && enforcer.Watcher is not null) { WatcherHolder holder = enforcer.Model.WatcherHolder; if (holder.WatcherEx is not null) @@ -105,7 +105,7 @@ internal static void TryNotifyPolicyChanged(this IEnforcer enforcer, PolicyChang internal static async Task TryNotifyPolicyChangedAsync(this IEnforcer enforcer, PolicyChangedMessage message) { - if (enforcer.Options.AutoNotifyWatcher && enforcer.Watcher is not null) + if (enforcer.AutoNotifyWatcher && enforcer.Watcher is not null) { WatcherHolder holder = enforcer.Model.WatcherHolder; if (holder.WatcherEx is not null) diff --git a/Casbin/Extensions/Model/ModelExtension.cs b/Casbin/Extensions/Model/ModelExtension.cs index 83073fd..d0e8b59 100644 --- a/Casbin/Extensions/Model/ModelExtension.cs +++ b/Casbin/Extensions/Model/ModelExtension.cs @@ -92,7 +92,7 @@ public static async Task LoadPolicyAsync(this IModel model) return true; } - public static bool LoadFilteredPolicy(this IModel model, Filter filter) + public static bool LoadFilteredPolicy(this IModel model, IPolicyFilter filter) { if (model.AdapterHolder.FilteredAdapter is null) { @@ -103,7 +103,7 @@ public static bool LoadFilteredPolicy(this IModel model, Filter filter) return true; } - public static async Task LoadFilteredPolicyAsync(this IModel model, Filter filter) + public static async Task LoadFilteredPolicyAsync(this IModel model, IPolicyFilter filter) { if (model.AdapterHolder.FilteredAdapter is null) { diff --git a/Casbin/Persist/Filter.cs b/Casbin/Persist/Filter.cs index 8487bb5..7a648cd 100644 --- a/Casbin/Persist/Filter.cs +++ b/Casbin/Persist/Filter.cs @@ -1,11 +1,59 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Linq; +using Casbin.Model; -namespace Casbin.Persist +namespace Casbin.Persist; + +[Obsolete("Please use PolicyFilter instead")] +public class Filter : IPolicyFilter { - public class Filter + private readonly PolicyFilter _filter; + + public Filter() => _filter = this; + + public IEnumerable G { get; set; } + + public IEnumerable P { get; set; } + + public IQueryable ApplyFilter(IQueryable policies) => + _filter is not null ? _filter.ApplyFilter(policies) : policies; + + public static implicit operator PolicyFilter(Filter filter) { - public IEnumerable G { get; set; } + if (filter is null) + { + return PolicyFilter.Empty; + } - public IEnumerable P { get; set; } + if (filter.P is null && filter.G is null) + { + return PolicyFilter.Empty; + } + + if (filter.P is not null && filter.G is not null) + { + PolicyFilter filterP = new(PermConstants.DefaultPolicyType, 0, + Policy.CreateValues(filter.P)); + PolicyFilter filterG = new(PermConstants.DefaultGroupingPolicyType, 0, + Policy.CreateValues(filter.G)); + return filterP.Or(filterG) as PolicyFilter; + } + + if (filter.P is not null) + { + return new PolicyFilter(PermConstants.DefaultPolicyType, 0, + Policy.CreateValues(filter.P)); + } + + if (filter.G is not null) + { + return new PolicyFilter(PermConstants.DefaultPolicyType, 0, + Policy.CreateValues(filter.P)); + } + + return PolicyFilter.Empty; } } + +