* permission-node: fix signature of permission rule in test suites Signed-off-by: Mike Lewis <mtlewis@users.noreply.github.com> * permission-common: add isPermission helper for comparing permissions Signed-off-by: Mike Lewis <mtlewis@users.noreply.github.com> * permission-node: adjust createConditionExports for more type safety Signed-off-by: Mike Lewis <mtlewis@users.noreply.github.com> * permissions: add resourceType property to PermissionCondition and PermissionRule Signed-off-by: Mike Lewis <mtlewis@users.noreply.github.com> * catalog: handle changes to PermissionCondition and PermissionRule types Signed-off-by: Mike Lewis <mtlewis@users.noreply.github.com> * catalog-backend: avoid re-exporting alpha import cf. https://github.com/backstage/backstage/pull/10128 Signed-off-by: Mike Lewis <mtlewis@users.noreply.github.com> * Update changeset Signed-off-by: Joe Porpeglia <josephp@spotify.com> * Resolve api-report conflict Signed-off-by: Joon Park <joonp@spotify.com> Co-authored-by: Joe Porpeglia <josephp@spotify.com> Co-authored-by: Joon Park <joonp@spotify.com>
2.6 KiB
@backstage/plugin-permission-node
| @backstage/plugin-permission-node |
|---|
| minor |
BREAKING: Stronger typing in PermissionPolicy 🎉.
Previously, it was entirely the responsibility of the PermissionPolicy author to only return CONDITIONAL decisions for permissions that are associated with a resource, and to return the correct kind of PermissionCondition instances inside the decision. Now, the policy authoring helpers provided in this package now ensure that the decision and permission match.
For policy authors: rename and adjust api of createConditionExports. Previously, the function returned a factory for creating conditional decisions named createPolicyDecision, which had a couple of drawbacks:
- The function always creates a conditional policy decision, but this was not reflected in the name.
- Conditional decisions should only ever be returned from
PermissionPolicy#handlefor resource permissions, but there was nothing in the API that encoded this constraint.
This change addresses the drawbacks above by making the following changes for policy authors:
- The
createPolicyDecisionmethod has been renamed tocreateConditionalDecision. - Along with conditions, the method now accepts a permission, which must be a
ResourcePermission. This is expected to be the handled permission inPermissionPolicy#handle, whose type must first be narrowed using methods likeisPermissionandisResourcePermission:
class TestPermissionPolicy implements PermissionPolicy {
async handle(
request: PolicyQuery<Permission>,
_user?: BackstageIdentityResponse,
): Promise<PolicyDecision> {
if (
// Narrow type of `request.permission` to `ResourcePermission<'catalog-entity'>
isResourcePermission(request.permission, RESOURCE_TYPE_CATALOG_ENTITY)
) {
return createCatalogConditionalDecision(
request.permission,
catalogConditions.isEntityOwner(
_user?.identity.ownershipEntityRefs ?? [],
),
);
}
return {
result: AuthorizeResult.ALLOW,
};
BREAKING: when creating PermissionRules, provide a resourceType.
export const isEntityOwner = createCatalogPermissionRule({
name: 'IS_ENTITY_OWNER',
description: 'Allow entities owned by the current user',
+ resourceType: RESOURCE_TYPE_CATALOG_ENTITY,
apply: (resource: Entity, claims: string[]) => {
if (!resource.relations) {
return false;
}
return resource.relations
.filter(relation => relation.type === RELATION_OWNED_BY)
.some(relation => claims.includes(relation.targetRef));
},
toQuery: (claims: string[]) => ({
key: 'relations.ownedBy',
values: claims,
}),
});