|
1 | 1 | import { NotAllowedError, NotFoundError } from '@backstage/errors';
|
2 | 2 |
|
3 |
| -import { Enforcer, newEnforcer, newModelFromString } from 'casbin'; |
| 3 | +import { Enforcer, newModelFromString } from 'casbin'; |
4 | 4 | import { Knex } from 'knex';
|
5 | 5 |
|
6 | 6 | import {
|
@@ -575,26 +575,51 @@ export class EnforcerDelegate {
|
575 | 575 | }
|
576 | 576 | }
|
577 | 577 |
|
| 578 | + /** |
| 579 | + * enforce aims to enforce a particular permission policy based on the user that it receives. |
| 580 | + * Under the hood, enforce uses the `enforce` method from the enforcer`. |
| 581 | + * |
| 582 | + * Before enforcement, a filter is set up to reduce the number of permission policies that will |
| 583 | + * be loaded in. |
| 584 | + * This will reduce the amount of checks that need to be made to determine if a user is authorize |
| 585 | + * to perform an action |
| 586 | + * |
| 587 | + * A temporary enforcer will also be used while enforcing. |
| 588 | + * This is to ensure that the filter does not interact with the base enforcer. |
| 589 | + * The temporary enforcer has lazy loading of the permission policies enabled to reduce the amount |
| 590 | + * of time it takes to initialize the temporary enforcer. |
| 591 | + * The justification for lazy loading is because permission policies are already present in the |
| 592 | + * role manager / database and it will be filtered and loaded whenever `loadFilteredPolicy` is called. |
| 593 | + * @param entityRef The user to enforce |
| 594 | + * @param resourceType The resource type / name of the permission policy |
| 595 | + * @param action The action of the permission policy |
| 596 | + * @param roles Any roles that the user is directly or indirectly attached to. |
| 597 | + * Used for filtering permission policies. |
| 598 | + * @returns True if the user is allowed based on the particular permission |
| 599 | + */ |
578 | 600 | async enforce(
|
579 | 601 | entityRef: string,
|
580 | 602 | resourceType: string,
|
581 | 603 | action: string,
|
| 604 | + roles: string[], |
582 | 605 | ): Promise<boolean> {
|
583 |
| - const filter = [ |
584 |
| - { |
585 |
| - ptype: 'p', |
586 |
| - v1: resourceType, |
587 |
| - v2: action, |
588 |
| - }, |
589 |
| - { |
590 |
| - ptype: 'g', |
591 |
| - v0: entityRef, |
592 |
| - }, |
593 |
| - ]; |
| 606 | + const filter = []; |
| 607 | + if (roles.length > 0) { |
| 608 | + roles.forEach(role => { |
| 609 | + filter.push({ ptype: 'p', v0: role, v1: resourceType, v2: action }); |
| 610 | + }); |
| 611 | + } else { |
| 612 | + filter.push({ ptype: 'p', v1: resourceType, v2: action }); |
| 613 | + } |
594 | 614 |
|
595 | 615 | const adapt = this.enforcer.getAdapter();
|
596 | 616 | const roleManager = this.enforcer.getRoleManager();
|
597 |
| - const tempEnforcer = await newEnforcer(newModelFromString(MODEL), adapt); |
| 617 | + const tempEnforcer = new Enforcer(); |
| 618 | + await tempEnforcer.initWithModelAndAdapter( |
| 619 | + newModelFromString(MODEL), |
| 620 | + adapt, |
| 621 | + true, |
| 622 | + ); |
598 | 623 | tempEnforcer.setRoleManager(roleManager);
|
599 | 624 |
|
600 | 625 | await tempEnforcer.loadFilteredPolicy(filter);
|
|
0 commit comments