Skip to content

Commit

Permalink
feat: add keyGet function and correponding test.
Browse files Browse the repository at this point in the history
  • Loading branch information
AsakusaRinne committed Aug 4, 2022
1 parent aa73b71 commit 723e0dd
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 0 deletions.
19 changes: 19 additions & 0 deletions Casbin.UnitTests/UtilTests/BuiltInFunctionTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,19 @@ public class BuiltInFunctionTest
new object[] { "/topic/edit/123s", "/topic/delete/[0-9]+", false }
};

public static IEnumerable<object[]> KeyGetTestData = new[]
{
new object[] { "/foo", "/foo", "" },
new object[] { "/foo", "/foo*", "" },
new object[] { "/foo", "/foo/*", "" },
new object[] { "/foo/bar", "/foo", "" },
new object[] { "/foo/bar", "/foo*", "/bar" },
new object[] { "/foo/bar", "/foo/*", "bar" },
new object[] { "/foobar", "/foo", "" },
new object[] { "/foobar", "/foo*", "bar" },
new object[] { "/foobar", "/foo/*", "" }
};

public static IEnumerable<object[]> keyMatchTestData = new[]
{
new object[] { "/foo", "/foo", true }, new object[] { "/foo", "/foo*", true },
Expand Down Expand Up @@ -140,6 +153,12 @@ public void TestRegexMatch(string key1, string key2, bool expectedResult) =>
Assert.Equal(expectedResult,
BuiltInFunctions.RegexMatch(key1, key2));

[Theory]
[MemberData(nameof(KeyGetTestData))]
public void TestKeyGet(string key1, string key2, string expectedResult) =>
Assert.Equal(expectedResult,
BuiltInFunctions.KeyGet(key1, key2));

[Theory]
[MemberData(nameof(keyMatchTestData))]
public void TestKeyMatch(string key1, string key2, bool expectedResult) =>
Expand Down
1 change: 1 addition & 0 deletions Casbin/Model/FunctionMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ internal static FunctionMap LoadFunctionMap()
FunctionDict = new Dictionary<string, Delegate>()
};

map.AddFunction("keyGet", BuiltInFunctions.KeyGet);
map.AddFunction("keyMatch", BuiltInFunctions.KeyMatch);
map.AddFunction("keyMatch2", BuiltInFunctions.KeyMatch2);
map.AddFunction("keyMatch3", BuiltInFunctions.KeyMatch3);
Expand Down
22 changes: 22 additions & 0 deletions Casbin/Util/BuiltInFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,28 @@ public static class BuiltInFunctions
private static readonly Regex s_keyMatch4Regex = new(@"\{([^/]+)\}");
private delegate bool GFunction(string subject1, string subject2, string domain = null);

/// <summary>
/// KeyGet returns the matched part
/// For example, "/foo/bar/foo" matches "/foo/*"
/// "bar/foo" will been returned
/// </summary>
/// <param name="key1">The first argument.</param>
/// <param name="key2">The second argument.</param>
/// <returns>Whether key1 matches key2.</returns>
public static string KeyGet(string key1, string key2)
{
int m = key1.Length, n = key2.Length;
if(m < n) return "";
var span1 = key1.AsSpan();
var span2 = key2.AsSpan();
for (int i = 0; i < n; i++)
{
if(span1[i] != span2[i])
return span2[i] == '*' ? span1.Slice(i, m - i).ToString() : "";
}
return "";
}

/// <summary>
/// Determines whether key1 matches the pattern of key2 (similar to RESTful path),
/// key2 can contain a *. For example, "/foo/bar" matches "/foo/*".
Expand Down

0 comments on commit 723e0dd

Please sign in to comment.