|
13 | 13 | // limitations under the License. |
14 | 14 |
|
15 | 15 | import * as _ from 'lodash'; |
16 | | -import { newEnforcer, Enforcer, newModel } from '../src'; |
| 16 | +import { DefaultRoleManager, Enforcer, newEnforcer, newModel } from '../src'; |
| 17 | +import { keyMatch2Func, keyMatch3Func } from '../src/util'; |
17 | 18 |
|
18 | 19 | async function testEnforce(e: Enforcer, sub: string, obj: any, act: string, res: boolean): Promise<void> { |
19 | 20 | await expect(e.enforce(sub, obj, act)).resolves.toBe(res); |
@@ -300,3 +301,37 @@ test('TestMatcher', async () => { |
300 | 301 |
|
301 | 302 | expect(m.model.get('m')?.get('m')?.value).toEqual(`keyMatch(r_obj, ".*get$") || regexMatch(r_act, ".user.")`); |
302 | 303 | }); |
| 304 | + |
| 305 | +test('TestRBACModelWithPattern', async () => { |
| 306 | + const e = await newEnforcer('examples/rbac_with_pattern_model.conf', 'examples/rbac_with_pattern_policy.csv'); |
| 307 | + |
| 308 | + // Here's a little confusing: the matching function here is not the custom function used in matcher. |
| 309 | + // It is the matching function used by "g" (and "g2", "g3" if any..) |
| 310 | + // You can see in policy that: "g2, /book/:id, book_group", so in "g2()" function in the matcher, instead |
| 311 | + // of checking whether "/book/:id" equals the obj: "/book/1", it checks whether the pattern matches. |
| 312 | + // You can see it as normal RBAC: "/book/:id" == "/book/1" becomes KeyMatch2("/book/:id", "/book/1") |
| 313 | + const rm = e.getRoleManager() as DefaultRoleManager; |
| 314 | + await rm.addMatchingFunc('KeyMatch2', keyMatch2Func); |
| 315 | + await e.buildRoleLinks(); |
| 316 | + await testEnforce(e, 'alice', '/book/1', 'GET', true); |
| 317 | + await testEnforce(e, 'alice', '/book/2', 'GET', true); |
| 318 | + await testEnforce(e, 'alice', '/pen/1', 'GET', true); |
| 319 | + await testEnforce(e, 'alice', '/pen/2', 'GET', false); |
| 320 | + await testEnforce(e, 'bob', '/book/1', 'GET', false); |
| 321 | + await testEnforce(e, 'bob', '/book/2', 'GET', false); |
| 322 | + await testEnforce(e, 'bob', '/pen/1', 'GET', true); |
| 323 | + await testEnforce(e, 'bob', '/pen/2', 'GET', true); |
| 324 | + |
| 325 | + // AddMatchingFunc() is actually setting a function because only one function is allowed, |
| 326 | + // so when we set "KeyMatch3", we are actually replacing "KeyMatch2" with "KeyMatch3". |
| 327 | + await rm.addMatchingFunc('KeyMatch3', keyMatch3Func); |
| 328 | + await e.buildRoleLinks(); |
| 329 | + await testEnforce(e, 'alice', '/book2/1', 'GET', true); |
| 330 | + await testEnforce(e, 'alice', '/book2/2', 'GET', true); |
| 331 | + await testEnforce(e, 'alice', '/pen2/1', 'GET', true); |
| 332 | + await testEnforce(e, 'alice', '/pen2/2', 'GET', false); |
| 333 | + await testEnforce(e, 'bob', '/book2/1', 'GET', false); |
| 334 | + await testEnforce(e, 'bob', '/book2/2', 'GET', false); |
| 335 | + await testEnforce(e, 'bob', '/pen2/1', 'GET', true); |
| 336 | + await testEnforce(e, 'bob', '/pen2/2', 'GET', true); |
| 337 | +}); |
0 commit comments