@@ -16,6 +16,19 @@
|
||||
|
||||
import { PermissionRule } from '../types';
|
||||
|
||||
/**
|
||||
* Creates a condition function for a given authorization rule and parameter type.
|
||||
*
|
||||
* For example, an isEntityOwner rule for catalog entities might take an array of entityRef strings.
|
||||
* The rule itself defines _how_ to check a given resource, whereas a condition also includes _what_
|
||||
* to verify.
|
||||
*
|
||||
* Plugin authors should generally use the {@link createPermissionIntegration} helper, which creates
|
||||
* conditions for the rules supplied. However, a different plugin can also add rules to this
|
||||
* integration (using the returned `registerPermissionRule` from this function), and create the
|
||||
* condition to be used in an {@link PermissionPolicy} using this method directly.
|
||||
* @public
|
||||
*/
|
||||
export const conditionFor =
|
||||
<TParams extends any[]>(rule: PermissionRule<unknown, unknown, TParams>) =>
|
||||
(...params: TParams) => ({
|
||||
|
||||
@@ -56,21 +56,65 @@ export type ApplyConditionsRequest = {
|
||||
conditions: PermissionCriteria<PermissionCondition>;
|
||||
};
|
||||
|
||||
type Condition<TRule> = TRule extends PermissionRule<any, any, infer TParams>
|
||||
/**
|
||||
* An authorization condition, which is a function to evaluate a given {@link PermissionRule} with
|
||||
* a specific set of parameters.
|
||||
* @see createPermissionIntegration
|
||||
* @public
|
||||
*/
|
||||
export type Condition<TRule> = TRule extends PermissionRule<
|
||||
any,
|
||||
any,
|
||||
infer TParams
|
||||
>
|
||||
? (...params: TParams) => PermissionCondition<TParams>
|
||||
: never;
|
||||
|
||||
type Conditions<TRules extends Record<string, PermissionRule<any, any>>> = {
|
||||
/**
|
||||
* A collection of keyed {@link Condition} functions produced from {@link PermissionRule}.
|
||||
* @see createPermissionIntegration
|
||||
* @public
|
||||
*/
|
||||
export type Conditions<
|
||||
TRules extends Record<string, PermissionRule<any, any>>,
|
||||
> = {
|
||||
[Name in keyof TRules]: Condition<TRules[Name]>;
|
||||
};
|
||||
|
||||
type QueryType<TRules> = TRules extends Record<
|
||||
/**
|
||||
* The plugin-specific type which authorization conditions are translated into, for plugin use in
|
||||
* filtering resources.
|
||||
* @public
|
||||
*/
|
||||
export type QueryType<TRules> = TRules extends Record<
|
||||
string,
|
||||
PermissionRule<any, infer TQuery, any>
|
||||
>
|
||||
? TQuery
|
||||
: never;
|
||||
|
||||
/**
|
||||
* Create a permission and authorization integration for a plugin that supports _conditional
|
||||
* authorization_ for resources.
|
||||
*
|
||||
* To make this concrete, we can use the Backstage software catalog as an example. The catalog has
|
||||
* conditional rules around access to specific _entities_ in the catalog. The _type_ of resource is
|
||||
* captured here as `resourceType`, a string identifier (`catalog-entity` in this example) that can
|
||||
* be provided with permission definitions. This is merely a _type_ to verify that conditions in an
|
||||
* authorization policy are constructed correctly, not a reference to a specific resource.
|
||||
*
|
||||
* The `rules` are a map of {@link PermissionRule} that introduce conditional filtering logic for
|
||||
* resources; for the catalog, these are things like `isEntityOwner` or `hasAnnotation`. Rules
|
||||
* describe how to filter a list of resources, and the `conditions` returned allow these rules to be
|
||||
* applied with specific parameters (such as 'group:default/team-a', or 'backstage.io/edit-url').
|
||||
*
|
||||
* The `getResource` argument should load a resource by reference. For the catalog, this is an
|
||||
* {@link @backstage/catalog-model#EntityRef}. For other plugins, this can be any serialized format.
|
||||
* This is used to construct the `createPermissionIntegrationRouter`, a function to add an
|
||||
* authorization route to your backend plugin. This route will be called by the `permission-backend`
|
||||
* when authorization conditions relating to this plugin need to be evaluated.
|
||||
* @public
|
||||
*/
|
||||
export const createPermissionIntegration = <
|
||||
TResource,
|
||||
TRules extends { [key: string]: PermissionRule<TResource, any> },
|
||||
|
||||
@@ -17,5 +17,6 @@
|
||||
export type {
|
||||
ConditionalPolicyResult,
|
||||
PermissionPolicy,
|
||||
PolicyAuthorizeRequest,
|
||||
PolicyResult,
|
||||
} from './types';
|
||||
|
||||
@@ -25,9 +25,9 @@ import { BackstageIdentity } from '@backstage/plugin-auth-backend';
|
||||
/**
|
||||
* An authorization request to be evaluated by the {@link PermissionPolicy}.
|
||||
*
|
||||
* This differs from {@link AuthorizeRequest} in that `resourceRef` should never be provided. This
|
||||
* forces policies to be written in a way that's compatible with filtering collections of resources
|
||||
* at data load time.
|
||||
* This differs from {@link @backstage/permission-common#AuthorizeRequest} in that `resourceRef`
|
||||
* should never be provided. This forces policies to be written in a way that's compatible with
|
||||
* filtering collections of resources at data load time.
|
||||
* @public
|
||||
*/
|
||||
export type PolicyAuthorizeRequest = Omit<AuthorizeRequest, 'resourceRef'>;
|
||||
@@ -39,8 +39,8 @@ export type PolicyAuthorizeRequest = Omit<AuthorizeRequest, 'resourceRef'>;
|
||||
* conditions hold when evaluated. The conditions will be evaluated by the corresponding plugin
|
||||
* which knows about the referenced permission rules.
|
||||
*
|
||||
* Similar to {@link AuthorizeResult}, but with the plugin and resource identifiers needed to
|
||||
* evaluate the returned conditions.
|
||||
* Similar to {@link @backstage/permission-common#AuthorizeResult}, but with the plugin and resource
|
||||
* identifiers needed to evaluate the returned conditions.
|
||||
* @public
|
||||
*/
|
||||
export type ConditionalPolicyResult = {
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
import type { PermissionCriteria } from '@backstage/plugin-permission-common';
|
||||
|
||||
/**
|
||||
* A conditional rule that can be provided in an {@link AuthorizeResult} response to an
|
||||
* authorization request.
|
||||
* A conditional rule that can be provided in an
|
||||
* {@link @backstage/permission-common#AuthorizeResult} response to an authorization request.
|
||||
*
|
||||
* Rules can either be evaluated against a resource loaded in memory, or used as filters when
|
||||
* loading a collection of resources from a data source. The `apply` and `toQuery` methods implement
|
||||
|
||||
Reference in New Issue
Block a user