Skip to content

Commit

Permalink
Merge pull request #155 from Sagilio/fix#154
Browse files Browse the repository at this point in the history
feat: Support multiple role manager
  • Loading branch information
hsluoyz authored Apr 7, 2021
2 parents 670cb83 + 043c023 commit a029861
Show file tree
Hide file tree
Showing 8 changed files with 172 additions and 55 deletions.
5 changes: 3 additions & 2 deletions NetCasbin.UnitTest/GroupRoleManagerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ public class GroupRoleManagerTest
public void TestGroupRoleManager()
{
var e = new Enforcer("examples/group_with_domain_model.conf", "examples/group_with_domain_policy.csv");
e.SetRoleManager(new GroupRoleManager(10));
var roleManager = new GroupRoleManager(10);
e.SetRoleManager("g", roleManager);
e.SetRoleManager("g2", roleManager);
e.BuildRoleLinks();

TestDomainEnforce(e, "alice", "domain1", "data1", "read", true);
}
}
Expand Down
23 changes: 17 additions & 6 deletions NetCasbin/CoreEnforcer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,10 @@ public class CoreEnforcer : ICoreEnforcer

protected IAdapter adapter;
protected IWatcher watcher;
protected IRoleManager roleManager;
protected bool autoSave;
protected bool autoBuildRoleLinks;
protected bool autoNotifyWatcher;
protected bool autoCleanEnforceCache = true;

internal IExpressionHandler ExpressionHandler { get; private set; }

private bool _enableCache;
Expand All @@ -47,7 +45,6 @@ public class CoreEnforcer : ICoreEnforcer

protected void Initialize()
{
roleManager = new DefaultRoleManager(10);
_effector = new DefaultEffector();
watcher = null;

Expand Down Expand Up @@ -169,7 +166,22 @@ public void SetWatcher(IWatcher watcher, bool useAsync = true)
/// <param name="roleManager"></param>
public void SetRoleManager(IRoleManager roleManager)
{
this.roleManager = roleManager;
SetRoleManager(PermConstants.DefaultRoleType, roleManager);
}

/// <summary>
/// Sets the current role manager.
/// </summary>
/// <param name="roleType"></param>
/// <param name="roleManager"></param>
public void SetRoleManager(string roleType, IRoleManager roleManager)
{
Assertion assertion = model.GetExistAssertion(PermConstants.Section.RoleSection, roleType);
assertion.RoleManager = roleManager;
if (autoBuildRoleLinks)
{
assertion.BuildRoleLinks();
}
}

/// <summary>
Expand Down Expand Up @@ -393,8 +405,7 @@ public void EnableAutoCleanEnforceCache(bool autoCleanEnforceCache)
/// </summary>
public void BuildRoleLinks()
{
roleManager.Clear();
model.BuildRoleLinks(roleManager);
model.BuildRoleLinks();
}

/// <summary>
Expand Down
41 changes: 29 additions & 12 deletions NetCasbin/Enforcer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -507,11 +507,7 @@ public Task<bool> DeletePermissionsForUserAsync(string user)
[Obsolete("This api will be removed in next mainline version. please use the another overwrite.")]
public List<string> GetImplicitRolesForUser(string name, params string[] domain)
{
var roles = roleManager.GetRoles(name, domain);
var res = new List<string>();
res.AddRange(roles);
res.AddRange(roles.SelectMany(x => GetImplicitRolesForUser(x, domain)));
return res;
return domain.Length is 0 ? GetImplicitRolesForUser(name) : GetImplicitRolesForUser(name, domain[0]);
}

/// <summary>
Expand All @@ -523,13 +519,34 @@ public List<string> GetImplicitRolesForUser(string name, params string[] domain)
/// <returns></returns>
public List<string> GetImplicitRolesForUser(string name, string domain = null)
{
var roles = domain is null
? roleManager.GetRoles(name)
: roleManager.GetRoles(name, domain);
var result = new List<string>();
result.AddRange(roles);
result.AddRange(roles.SelectMany(x => GetImplicitRolesForUser(x, domain)));
return result;
HashSet<string> roleSet = new() {name};
Queue<string> queue = new();
queue.Enqueue(name);

while (queue.Count is not 0)
{
string nowRole = queue.Dequeue();
foreach (var assertion in model.Model[PermConstants.Section.RoleSection].Values)
{
var roles = domain is null
? assertion.RoleManager.GetRoles(nowRole)
: assertion.RoleManager.GetRoles(nowRole, domain);

foreach (string role in roles)
{
if (roleSet.Contains(role))
{
continue;
}

roleSet.Add(role);
queue.Enqueue(role);
}
}
}

roleSet.Remove(name);
return roleSet.ToList();
}

/// <summary>
Expand Down
32 changes: 32 additions & 0 deletions NetCasbin/Extensions/EnforcerExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;
using NetCasbin.Model;

namespace NetCasbin.Extensions
{
public static class EnforcerExtension
{
public static Enforcer AddMatchingFunc(this Enforcer enforcer, Func<string, string, bool> func)
{
enforcer.AddNamedMatchingFunc(PermConstants.DefaultRoleType, func);
return enforcer;
}

public static Enforcer AddDomainMatchingFunc(this Enforcer enforcer, Func<string, string, bool> func)
{
enforcer.AddNamedDomainMatchingFunc(PermConstants.DefaultRoleType, func);
return enforcer;
}

public static Enforcer AddNamedMatchingFunc(this Enforcer enforcer, string roleType, Func<string, string, bool> func)
{
enforcer.GetModel().GetNamedRoleManger(roleType).AddMatchingFunc(func);
return enforcer;
}

public static Enforcer AddNamedDomainMatchingFunc(this Enforcer enforcer, string roleType, Func<string, string, bool> func)
{
enforcer.GetModel().GetNamedRoleManger(roleType).AddMatchingFunc(func);
return enforcer;
}
}
}
19 changes: 19 additions & 0 deletions NetCasbin/Extensions/ModelExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using NetCasbin.Model;
using NetCasbin.Rbac;

namespace NetCasbin.Extensions
{
public static class ModelExtension
{
internal static IRoleManager GetRoleManger(this Model.Model model)
{
return model.GetNamedRoleManger(PermConstants.DefaultRoleType);
}

internal static IRoleManager GetNamedRoleManger(this Model.Model model, string roleType)
{
return model.GetExistAssertion(PermConstants.Section.RoleSection, roleType).RoleManager;
}
}
}
16 changes: 8 additions & 8 deletions NetCasbin/InternalEnforcer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ protected bool InternalAddPolicy(string sec, string ptype, List<string> rule)

if (sec.Equals(PermConstants.Section.RoleSection))
{
model.BuildIncrementalRoleLink(roleManager, PolicyOperation.PolicyAdd,
model.BuildIncrementalRoleLink(PolicyOperation.PolicyAdd,
sec, ptype, rule);
ExpressionHandler.SetGFunctions();
}
Expand Down Expand Up @@ -93,7 +93,7 @@ protected async Task<bool> InternalAddPolicyAsync(string sec, string ptype, List

if (sec.Equals(PermConstants.Section.RoleSection))
{
model.BuildIncrementalRoleLink(roleManager, PolicyOperation.PolicyAdd,
model.BuildIncrementalRoleLink(PolicyOperation.PolicyAdd,
sec, ptype, rule);
ExpressionHandler.SetGFunctions();
}
Expand Down Expand Up @@ -139,7 +139,7 @@ protected bool InternalAddPolicies(string sec, string ptype, IEnumerable<List<st

if (sec.Equals(PermConstants.Section.RoleSection))
{
model.BuildIncrementalRoleLinks(roleManager, PolicyOperation.PolicyAdd,
model.BuildIncrementalRoleLinks(PolicyOperation.PolicyAdd,
sec, ptype, ruleArray);
ExpressionHandler.SetGFunctions();
}
Expand Down Expand Up @@ -186,7 +186,7 @@ protected async Task<bool> InternalAddPoliciesAsync(string sec, string ptype, IE

if (sec.Equals(PermConstants.Section.RoleSection))
{
model.BuildIncrementalRoleLinks(roleManager, PolicyOperation.PolicyAdd,
model.BuildIncrementalRoleLinks(PolicyOperation.PolicyAdd,
sec, ptype, ruleArray);
ExpressionHandler.SetGFunctions();
}
Expand Down Expand Up @@ -230,7 +230,7 @@ protected bool InternalRemovePolicy(string sec, string ptype, List<string> rule)

if (sec.Equals(PermConstants.Section.RoleSection))
{
model.BuildIncrementalRoleLink(roleManager, PolicyOperation.PolicyRemove,
model.BuildIncrementalRoleLink(PolicyOperation.PolicyRemove,
sec, ptype, rule);
ExpressionHandler.SetGFunctions();
}
Expand Down Expand Up @@ -274,7 +274,7 @@ protected async Task<bool> InternalRemovePolicyAsync(string sec, string ptype, L

if (sec.Equals(PermConstants.Section.RoleSection))
{
model.BuildIncrementalRoleLink(roleManager, PolicyOperation.PolicyRemove,
model.BuildIncrementalRoleLink(PolicyOperation.PolicyRemove,
sec, ptype, rule);
ExpressionHandler.SetGFunctions();
}
Expand Down Expand Up @@ -320,7 +320,7 @@ protected bool InternalRemovePolicies(string sec, string ptype, IEnumerable<List

if (sec.Equals(PermConstants.Section.RoleSection))
{
model.BuildIncrementalRoleLinks(roleManager, PolicyOperation.PolicyRemove,
model.BuildIncrementalRoleLinks(PolicyOperation.PolicyRemove,
sec, ptype, ruleArray);
ExpressionHandler.SetGFunctions();
}
Expand Down Expand Up @@ -366,7 +366,7 @@ protected async Task<bool> InternalRemovePoliciesAsync(string sec, string ptype,

if (sec.Equals(PermConstants.Section.RoleSection))
{
model.BuildIncrementalRoleLinks(roleManager, PolicyOperation.PolicyRemove,
model.BuildIncrementalRoleLinks(PolicyOperation.PolicyRemove,
sec, ptype, ruleArray);
ExpressionHandler.SetGFunctions();
}
Expand Down
25 changes: 11 additions & 14 deletions NetCasbin/Model/Assertion.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using NetCasbin.Rbac;
using NetCasbin.Util;

Expand All @@ -18,7 +19,7 @@ public class Assertion

public IDictionary<string, int> Tokens { set; get; }

public IRoleManager RoleManager { get; private set; }
public IRoleManager RoleManager { get; internal set; }

public List<List<string>> Policy { set; get; }

Expand All @@ -28,7 +29,7 @@ public Assertion()
{
Policy = new List<List<string>>();
PolicyStringSet = new HashSet<string>();
RoleManager = new DefaultRoleManager(0);
RoleManager = new DefaultRoleManager(10);
}

public void RefreshPolicyStringSet()
Expand All @@ -40,23 +41,19 @@ public void RefreshPolicyStringSet()
}
}

internal void BuildIncrementalRoleLink(IRoleManager roleManager,
PolicyOperation policyOperation, IEnumerable<string> rule)
internal void BuildIncrementalRoleLink(PolicyOperation policyOperation, IEnumerable<string> rule)
{
RoleManager = roleManager;
int count = Value.Count(c => c is '_');
if (count < 2)
{
throw new InvalidOperationException("the number of \"_\" in role definition should be at least 2.");
}

BuildRoleLink(roleManager, count, policyOperation, rule);
BuildRoleLink(count, policyOperation, rule);
}

internal void BuildIncrementalRoleLinks(IRoleManager roleManager,
PolicyOperation policyOperation, IEnumerable<IEnumerable<string>> rules)
internal void BuildIncrementalRoleLinks(PolicyOperation policyOperation, IEnumerable<IEnumerable<string>> rules)
{
RoleManager = roleManager;
int count = Value.Count(c => c is '_');
if (count < 2)
{
Expand All @@ -65,13 +62,12 @@ internal void BuildIncrementalRoleLinks(IRoleManager roleManager,

foreach (var rule in rules)
{
BuildRoleLink(roleManager, count, policyOperation, rule);
BuildRoleLink(count, policyOperation, rule);
}
}

public void BuildRoleLinks(IRoleManager roleManager)
public void BuildRoleLinks()
{
RoleManager = roleManager;
int count = Value.Count(c => c is '_');
if (count < 2)
{
Expand All @@ -80,13 +76,14 @@ public void BuildRoleLinks(IRoleManager roleManager)

foreach (var rule in Policy)
{
BuildRoleLink(roleManager, count, PolicyOperation.PolicyAdd, rule);
BuildRoleLink(count, PolicyOperation.PolicyAdd, rule);
}
}

private static void BuildRoleLink(IRoleManager roleManager, int groupPolicyCount,
private void BuildRoleLink(int groupPolicyCount,
PolicyOperation policyOperation, IEnumerable<string> rule)
{
var roleManager = RoleManager;
List<string> ruleEnum = rule as List<string> ?? rule.ToList();
int ruleCount = ruleEnum.Count;

Expand Down
Loading

0 comments on commit a029861

Please sign in to comment.