Skip to content

Commit 0e8693e

Browse files
committed
feat: correct KeyMatch5 to support wildcards and path parameters
1 parent c1a6d0b commit 0e8693e

2 files changed

Lines changed: 43 additions & 9 deletions

File tree

Casbin.UnitTests/UtilTests/BuiltInFunctionTest.cs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,34 @@ public class BuiltInFunctionTest
159159
["/parent?status=1&type=2", "/parent/child", false],
160160
["/parent/child/?status=1&type=2", "/parent/child/", true],
161161
["/parent/child/?status=1&type=2", "/parent/child", false],
162-
["/parent/child?status=1&type=2", "/parent/child/", false]
162+
["/parent/child?status=1&type=2", "/parent/child/", false],
163+
// wildcard *
164+
["/foo", "/foo", true],
165+
["/foo", "/foo*", true],
166+
["/foo", "/foo/*", false],
167+
["/foo/bar", "/foo", false],
168+
["/foo/bar", "/foo*", false],
169+
["/foo/bar", "/foo/*", true],
170+
["/foobar", "/foo", false],
171+
["/foobar", "/foo*", false],
172+
["/foobar", "/foo/*", false],
173+
// {param} placeholders
174+
["/", "/{resource}", false],
175+
["/resource1", "/{resource}", true],
176+
["/myid", "/{id}/using/{resId}", false],
177+
["/myid/using/myresid", "/{id}/using/{resId}", true],
178+
// {param} + wildcard
179+
["/proxy/myid", "/proxy/{id}/*", false],
180+
["/proxy/myid/", "/proxy/{id}/*", true],
181+
["/proxy/myid/res", "/proxy/{id}/*", true],
182+
["/proxy/myid/res/res2", "/proxy/{id}/*", true],
183+
["/proxy/myid/res/res2/res3", "/proxy/{id}/*", true],
184+
["/proxy/", "/proxy/{id}/*", false],
185+
// query strings with {param} + wildcard
186+
["/proxy/myid?status=1&type=2", "/proxy/{id}/*", false],
187+
["/proxy/myid/res?status=1&type=2", "/proxy/{id}/*", true],
188+
["/proxy/myid/res/res2?status=1&type=2", "/proxy/{id}/*", true],
189+
["/proxy/myid/res/res2/res3?status=1&type=2", "/proxy/{id}/*", true]
163190
];
164191

165192
public static IEnumerable<object[]> GlobMatchTestData =

Casbin/Functions/BuiltInFunctions.cs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public static class BuiltInFunctions
1313
private static readonly Regex s_keyMatch2Regex = new(@":[^/]+");
1414
private static readonly Regex s_keyMatch3Regex = new(@"\{[^/]+\}");
1515
private static readonly Regex s_keyMatch4Regex = new(@"\{([^/]+)\}");
16+
private static readonly Regex s_keyMatch5Regex = new(@"\{[^/]+\}");
1617
private static readonly Regex s_keyGet2Regex = new(@":[^/]+");
1718
private static readonly Regex s_keyGet3Regex = new(@"\{[^/]+?\}");
1819

@@ -223,20 +224,26 @@ public static bool KeyMatch4(string key1, string key2)
223224
}
224225

225226
/// <summary>
226-
/// KeyMatch determines whether key1 matches the pattern of key2 and ignores the parameters in key2.
227-
/// For example, "/foo/bar?status=1&amp;type=2" matches "/foo/bar"
227+
/// KeyMatch5 determines whether key1 matches the pattern of key2 (similar to RESTful path),
228+
/// key2 can contain a * or {param}. Query strings in key1 are ignored.
229+
/// For example, "/foo/bar?status=1&amp;type=2" matches "/foo/bar", "/foo/bar" matches "/foo/*",
230+
/// "/proxy/myid/res" matches "/proxy/{id}/*".
228231
/// </summary>
229232
/// <param name="key1"> The first argument. </param>
230233
/// <param name="key2"> The second argument. </param>
231234
/// <returns></returns>
232235
public static bool KeyMatch5(string key1, string key2)
233236
{
234-
var key1Span = key1.AsSpan();
235-
var key2Span = key2.AsSpan();
236-
int index = key1Span.IndexOf('?');
237-
return index is -1
238-
? key1Span.Equals(key2Span, StringComparison.Ordinal)
239-
: key1Span.Slice(0, index).Equals(key2Span, StringComparison.Ordinal);
237+
int queryIndex = key1.IndexOf('?');
238+
if (queryIndex != -1)
239+
{
240+
key1 = key1.Substring(0, queryIndex);
241+
}
242+
243+
key2 = key2.Replace("/*", "/.*");
244+
key2 = s_keyMatch5Regex.Replace(key2, "([^/]+)");
245+
246+
return RegexMatch(key1, $"^{key2}$");
240247
}
241248

242249
/// <summary>

0 commit comments

Comments
 (0)