Skip to content

Commit

Permalink
feat: fix different ways of building role links when domain patterns …
Browse files Browse the repository at this point in the history
…are enabled (casbin#352)

* Better (?) way of building role links when domain patterns are enabled.

* fix: skip current domain as those links are already handled elsewhere
  • Loading branch information
imf-code authored Apr 27, 2024
1 parent c340c97 commit 5a358a4
Showing 1 changed file with 108 additions and 9 deletions.
117 changes: 108 additions & 9 deletions Casbin/Rbac/DefaultRoleManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -230,15 +230,6 @@ private bool HasLinkInDomain(string name1, string name2, string domain)
public virtual void AddLink(string name1, string name2, string domain = null)
{
domain ??= _defaultDomain;
if (HasDomainPattern)
{
foreach (string matchDomain in GetPatternDomains(domain))
{
AddLinkInDomain(name1, name2, matchDomain);
}
_cachedAllDomains = null;
return;
}
_cachedAllDomains = null;
AddLinkInDomain(name1, name2, domain);
}
Expand All @@ -249,10 +240,25 @@ private void AddLinkInDomain(string name1, string name2, string domain)
? _defaultRoles
: _allDomains.GetOrAdd(domain, new ConcurrentDictionary<string, Role>());

bool role1IsNew = roles.ContainsKey(name1) is false;
bool role2IsNew = roles.ContainsKey(name2) is false;

Role role1 = roles.GetOrAdd(name1, new Role(name1, domain));
Role role2 = roles.GetOrAdd(name2, new Role(name2, domain));
role1.AddRole(role2);

if (HasDomainPattern)
{
if (role1IsNew)
{
AddLinksFromMatchingDomains(role1);
}
if (role2IsNew)
{
AddLinksToMatchingDomains(role2);
}
}

if (HasPattern is false)
{
return;
Expand All @@ -276,6 +282,87 @@ private void AddLinkInDomain(string name1, string name2, string domain)
}
}

private void AddLinksFromMatchingDomains(Role role)
{
if (HasDomainPattern is false)
{
return;
}

IEnumerable<string> matchingDomains = GetMatchingDomains(role.Domain);

foreach (string domain in matchingDomains)
{
if (domain == role.Domain || _allDomains.TryGetValue(domain, out var matchingDomain) is false)
{
continue;
}

if (HasPattern is false)
{
if (matchingDomain.TryGetValue(role.Name, out var matchingRole) && role != matchingRole)
{
matchingRole.AddRole(role);
};
continue;
}

var roleNames = matchingDomain.Keys;
foreach (string roleName in roleNames)
{
if (MatchingFunc(roleName, role.Name) is false)
{
continue;
}
if (matchingDomain.TryGetValue(roleName, out var matchingRole) && role != matchingRole)
{
matchingRole.AddRole(role);
}
}
}
}

private void AddLinksToMatchingDomains(Role role)
{
if (HasDomainPattern is false)
{
return;
}

IEnumerable<string> matchingDomains = GetPatternDomains(role.Domain);

foreach (string domain in matchingDomains)
{
if (domain == role.Domain || _allDomains.TryGetValue(domain, out var matchingDomain) is false)
{
continue;
}

if (HasPattern is false)
{
if (matchingDomain.TryGetValue(role.Name, out var matchingRole) && role != matchingRole)
{
role.AddRole(matchingRole);
};
continue;
}

var roleNames = matchingDomain.Keys;
foreach (string roleName in roleNames)
{
if (MatchingFunc(role.Name, roleName) is false)
{
continue;
}
if (matchingDomain.TryGetValue(roleName, out var matchingRole) && matchingRole != role)
{
role.AddRole(matchingRole);
}
}

}
}

public virtual void DeleteLink(string name1, string name2, string domain = null)
{
domain ??= _defaultDomain;
Expand Down Expand Up @@ -321,5 +408,17 @@ private IEnumerable<string> GetPatternDomains(string domain)
}
return matchDomains;
}

private IEnumerable<string> GetMatchingDomains(string domainPattern)
{
List<string> matchDomains = new() { domainPattern };
_cachedAllDomains ??= _allDomains.Keys;
if (HasDomainPattern)
{
matchDomains.AddRange(_cachedAllDomains.Where(key =>
DomainMatchingFunc(key, domainPattern) && key != domainPattern));
}
return matchDomains;
}
}
}

0 comments on commit 5a358a4

Please sign in to comment.