Skip to content

Commit

Permalink
feat: add keyGet2 and corresponding test. (#280)
Browse files Browse the repository at this point in the history
  • Loading branch information
AsakusaRinne authored Aug 29, 2022
1 parent b7a4412 commit d2d245f
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 0 deletions.
40 changes: 40 additions & 0 deletions Casbin.UnitTests/UtilTests/BuiltInFunctionTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,40 @@ public class BuiltInFunctionTest
new object[] { "/foobar", "/foo/*", "" }
};

public static IEnumerable<object[]> KeyGet2TestData = new[]
{
new object[] { "/foo", "/foo", "id", ""},
new object[] { "/foo", "/foo*", "id", ""},
new object[] { "/foo", "/foo/*", "id", ""},
new object[] { "/foo/bar", "/foo", "id", ""},
new object[] { "/foo/bar", "/foo*", "id", ""}, // different with KeyMatch.
new object[] { "/foo/bar", "/foo/*", "id", ""},
new object[] { "/foobar", "/foo", "id", ""},
new object[] { "/foobar", "/foo*", "id", ""}, // different with KeyMatch.
new object[] { "/foobar", "/foo/*", "id", ""},

new object[] { "/", "/:resource", "resource", ""},
new object[] { "/resource1", "/:resource", "resource", "resource1"},
new object[] { "/myid", "/:id/using/:resId", "id", ""},
new object[] { "/myid/using/myresid", "/:id/using/:resId", "id", "myid"},
new object[] { "/myid/using/myresid", "/:id/using/:resId", "resId", "myresid"},

new object[] { "/proxy/myid", "/proxy/:id/*", "id", ""},
new object[] { "/proxy/myid/", "/proxy/:id/*", "id", "myid"},
new object[] { "/proxy/myid/res", "/proxy/:id/*", "id", "myid"},
new object[] { "/proxy/myid/res/res2", "/proxy/:id/*", "id", "myid"},
new object[] { "/proxy/myid/res/res2/res3", "/proxy/:id/*", "id", "myid"},
new object[] { "/proxy/myid/res/res2/res3", "/proxy/:id/res/*", "id", "myid"},
new object[] { "/proxy/", "/proxy/:id/*", "id", ""},

new object[] { "/alice", "/:id", "id", "alice"},
new object[] { "/alice/all", "/:id/all", "id", "alice"},
new object[] { "/alice", "/:id/all", "id", ""},
new object[] { "/alice/all", "/:id", "id", ""},

new object[] { "/alice/all", "/:/all", "", ""}
};

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

[Theory]
[MemberData(nameof(KeyGet2TestData))]
public void TestKeyGet2(string key1, string key2, string pathVar, string expectedResult) =>
Assert.Equal(expectedResult,
BuiltInFunctions.KeyGet2(key1, key2, pathVar));

[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 @@ -21,6 +21,7 @@ internal static FunctionMap LoadFunctionMap()
};

map.AddFunction("keyGet", BuiltInFunctions.KeyGet);
map.AddFunction("keyGet2", BuiltInFunctions.KeyGet2);
map.AddFunction("keyMatch", BuiltInFunctions.KeyMatch);
map.AddFunction("keyMatch2", BuiltInFunctions.KeyMatch2);
map.AddFunction("keyMatch3", BuiltInFunctions.KeyMatch3);
Expand Down
33 changes: 33 additions & 0 deletions Casbin/Util/BuiltInFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,39 @@ public static string KeyGet(string key1, string key2)
return "";
}

/// <summary>
/// KeyGet2 returns value matched pattern
/// For example, "/resource1" matches "/:resource"
/// if the pathVar == "resource", then "resource1" will be returned
/// </summary>
/// <param name="key1">The first argument.</param>
/// <param name="key2">The second argument.</param>
/// /// <param name="pathVar">The path variable.</param>
/// <returns>Whether key1 matches key2.</returns>
public static string KeyGet2(string key1, string key2, string pathVar)
{
var replacedKey2 = key2.Replace("/*", "/.*");
var regex1 = new Regex(@":[^/]+");
var keys = regex1.Matches(replacedKey2);
replacedKey2 = regex1.Replace(replacedKey2, @"([^/]+)");
replacedKey2 = "^" + replacedKey2 + "$";
var regex2 = new Regex(replacedKey2);
var values = regex2.Matches(key1);
if(values.Count == 0)
{
return "";
}
var pathVarSpan = pathVar.AsSpan();
for (int i = 0; i < keys.Count; i++)
{
if(keys[i].Value.AsSpan(1).SequenceEqual(pathVarSpan))
{
return values[0].Groups[i+1].Value;
}
}
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 d2d245f

Please sign in to comment.