Introduce PermissionMessageBatch utility type. Rename Identified type to IdentifiedPermissionMessage.
Co-authored-by: Mike Lewis <mtlewis@users.noreply.github.com> Signed-off-by: Joe Porpeglia <josephp@spotify.com>
This commit is contained in:
committed by
Joe Porpeglia
parent
fa013a336b
commit
ac0a6cb827
@@ -32,7 +32,7 @@ import {
|
||||
AuthorizeResult,
|
||||
AuthorizeDecision,
|
||||
AuthorizeQuery,
|
||||
Identified,
|
||||
IdentifiedPermissionMessage,
|
||||
AuthorizeRequest,
|
||||
AuthorizeResponse,
|
||||
isResourcePermission,
|
||||
@@ -73,11 +73,12 @@ const permissionSchema = z.union([
|
||||
}),
|
||||
]);
|
||||
|
||||
const querySchema: z.ZodSchema<Identified<AuthorizeQuery>> = z.object({
|
||||
id: z.string(),
|
||||
resourceRef: z.string().optional(),
|
||||
permission: permissionSchema,
|
||||
});
|
||||
const querySchema: z.ZodSchema<IdentifiedPermissionMessage<AuthorizeQuery>> =
|
||||
z.object({
|
||||
id: z.string(),
|
||||
resourceRef: z.string().optional(),
|
||||
permission: permissionSchema,
|
||||
});
|
||||
|
||||
const requestSchema: z.ZodSchema<AuthorizeRequest> = z.object({
|
||||
items: z.array(querySchema),
|
||||
@@ -98,12 +99,12 @@ export interface RouterOptions {
|
||||
}
|
||||
|
||||
const handleRequest = async (
|
||||
requests: Identified<AuthorizeQuery>[],
|
||||
requests: IdentifiedPermissionMessage<AuthorizeQuery>[],
|
||||
user: BackstageIdentityResponse | undefined,
|
||||
policy: PermissionPolicy,
|
||||
permissionIntegrationClient: PermissionIntegrationClient,
|
||||
authHeader?: string,
|
||||
): Promise<Identified<AuthorizeDecision>[]> => {
|
||||
): Promise<IdentifiedPermissionMessage<AuthorizeDecision>[]> => {
|
||||
const applyConditionsLoaderFor = memoize((pluginId: string) => {
|
||||
return new DataLoader<
|
||||
ApplyConditionsRequestEntry,
|
||||
|
||||
@@ -18,7 +18,11 @@ import { RestContext, rest } from 'msw';
|
||||
import { setupServer } from 'msw/node';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { PermissionClient } from './PermissionClient';
|
||||
import { AuthorizeQuery, AuthorizeResult, Identified } from './types/api';
|
||||
import {
|
||||
AuthorizeQuery,
|
||||
AuthorizeResult,
|
||||
IdentifiedPermissionMessage,
|
||||
} from './types/api';
|
||||
import { DiscoveryApi } from './types/discovery';
|
||||
import { createPermission } from './permissions';
|
||||
|
||||
@@ -54,10 +58,12 @@ describe('PermissionClient', () => {
|
||||
};
|
||||
|
||||
const mockAuthorizeHandler = jest.fn((req, res, { json }: RestContext) => {
|
||||
const responses = req.body.items.map((a: Identified<AuthorizeQuery>) => ({
|
||||
id: a.id,
|
||||
result: AuthorizeResult.ALLOW,
|
||||
}));
|
||||
const responses = req.body.items.map(
|
||||
(a: IdentifiedPermissionMessage<AuthorizeQuery>) => ({
|
||||
id: a.id,
|
||||
result: AuthorizeResult.ALLOW,
|
||||
}),
|
||||
);
|
||||
|
||||
return res(json({ items: responses }));
|
||||
});
|
||||
@@ -141,7 +147,7 @@ describe('PermissionClient', () => {
|
||||
mockAuthorizeHandler.mockImplementationOnce(
|
||||
(req, res, { json }: RestContext) => {
|
||||
const responses = req.body.items.map(
|
||||
(a: Identified<AuthorizeQuery>) => ({
|
||||
(a: IdentifiedPermissionMessage<AuthorizeQuery>) => ({
|
||||
id: a.id,
|
||||
outcome: AuthorizeResult.ALLOW,
|
||||
}),
|
||||
@@ -158,10 +164,12 @@ describe('PermissionClient', () => {
|
||||
it('should allow all when permission.enabled is false', async () => {
|
||||
mockAuthorizeHandler.mockImplementationOnce(
|
||||
(req, res, { json }: RestContext) => {
|
||||
const responses = req.body.map((a: Identified<AuthorizeQuery>) => ({
|
||||
id: a.id,
|
||||
result: AuthorizeResult.DENY,
|
||||
}));
|
||||
const responses = req.body.map(
|
||||
(a: IdentifiedPermissionMessage<AuthorizeQuery>) => ({
|
||||
id: a.id,
|
||||
result: AuthorizeResult.DENY,
|
||||
}),
|
||||
);
|
||||
|
||||
return res(json({ items: responses }));
|
||||
},
|
||||
@@ -180,10 +188,12 @@ describe('PermissionClient', () => {
|
||||
it('should allow all when permission.enabled is not configured', async () => {
|
||||
mockAuthorizeHandler.mockImplementationOnce(
|
||||
(req, res, { json }: RestContext) => {
|
||||
const responses = req.body.map((a: Identified<AuthorizeQuery>) => ({
|
||||
id: a.id,
|
||||
outcome: AuthorizeResult.DENY,
|
||||
}));
|
||||
const responses = req.body.map(
|
||||
(a: IdentifiedPermissionMessage<AuthorizeQuery>) => ({
|
||||
id: a.id,
|
||||
outcome: AuthorizeResult.DENY,
|
||||
}),
|
||||
);
|
||||
|
||||
return res(json(responses));
|
||||
},
|
||||
|
||||
@@ -23,7 +23,7 @@ import {
|
||||
AuthorizeResult,
|
||||
AuthorizeQuery,
|
||||
AuthorizeDecision,
|
||||
Identified,
|
||||
IdentifiedPermissionMessage,
|
||||
PermissionCriteria,
|
||||
PermissionCondition,
|
||||
AuthorizeResponse,
|
||||
@@ -145,7 +145,7 @@ export class PermissionClient implements PermissionAuthorizer {
|
||||
const responsesById = responseBody.items.reduce((acc, r) => {
|
||||
acc[r.id] = r;
|
||||
return acc;
|
||||
}, {} as Record<string, Identified<AuthorizeDecision>>);
|
||||
}, {} as Record<string, IdentifiedPermissionMessage<AuthorizeDecision>>);
|
||||
|
||||
return request.items.map(query => responsesById[query.id]);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,15 @@ import { Permission } from './permission';
|
||||
* requests.
|
||||
* @public
|
||||
*/
|
||||
export type Identified<T> = T & { id: string };
|
||||
export type IdentifiedPermissionMessage<T> = T & { id: string };
|
||||
|
||||
/**
|
||||
* A batch of request or response items.
|
||||
* @public
|
||||
*/
|
||||
export type PermissionMessageBatch<T> = {
|
||||
items: IdentifiedPermissionMessage<T>[];
|
||||
};
|
||||
|
||||
/**
|
||||
* The result of an authorization request.
|
||||
@@ -55,9 +63,7 @@ export type AuthorizeQuery = {
|
||||
* A batch of authorization requests from {@link PermissionClient#authorize}.
|
||||
* @public
|
||||
*/
|
||||
export type AuthorizeRequest = {
|
||||
items: Identified<AuthorizeQuery>[];
|
||||
};
|
||||
export type AuthorizeRequest = PermissionMessageBatch<AuthorizeQuery>;
|
||||
|
||||
/**
|
||||
* A condition returned with a CONDITIONAL authorization response.
|
||||
@@ -127,6 +133,4 @@ export type AuthorizeDecision =
|
||||
* A batch of authorization responses from {@link PermissionClient#authorize}.
|
||||
* @public
|
||||
*/
|
||||
export type AuthorizeResponse = {
|
||||
items: Identified<AuthorizeDecision>[];
|
||||
};
|
||||
export type AuthorizeResponse = PermissionMessageBatch<AuthorizeDecision>;
|
||||
|
||||
@@ -20,7 +20,8 @@ export type {
|
||||
AuthorizeRequest,
|
||||
AuthorizeDecision,
|
||||
AuthorizeResponse,
|
||||
Identified,
|
||||
IdentifiedPermissionMessage,
|
||||
PermissionMessageBatch,
|
||||
PermissionCondition,
|
||||
PermissionCriteria,
|
||||
AllOfCriteria,
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
import { ServerPermissionClient } from './ServerPermissionClient';
|
||||
import {
|
||||
Identified,
|
||||
IdentifiedPermissionMessage,
|
||||
AuthorizeQuery,
|
||||
AuthorizeResult,
|
||||
createPermission,
|
||||
@@ -32,10 +32,12 @@ import { RestContext, rest } from 'msw';
|
||||
|
||||
const server = setupServer();
|
||||
const mockAuthorizeHandler = jest.fn((req, res, { json }: RestContext) => {
|
||||
const responses = req.body.items.map((r: Identified<AuthorizeQuery>) => ({
|
||||
id: r.id,
|
||||
result: AuthorizeResult.ALLOW,
|
||||
}));
|
||||
const responses = req.body.items.map(
|
||||
(r: IdentifiedPermissionMessage<AuthorizeQuery>) => ({
|
||||
id: r.id,
|
||||
result: AuthorizeResult.ALLOW,
|
||||
}),
|
||||
);
|
||||
|
||||
return res(json({ items: responses }));
|
||||
});
|
||||
|
||||
@@ -21,7 +21,7 @@ import { InputError } from '@backstage/errors';
|
||||
import { errorHandler } from '@backstage/backend-common';
|
||||
import {
|
||||
AuthorizeResult,
|
||||
Identified,
|
||||
IdentifiedPermissionMessage,
|
||||
PermissionCondition,
|
||||
PermissionCriteria,
|
||||
} from '@backstage/plugin-permission-common';
|
||||
@@ -67,7 +67,7 @@ const applyConditionsRequestSchema = z.object({
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type ApplyConditionsRequestEntry = Identified<{
|
||||
export type ApplyConditionsRequestEntry = IdentifiedPermissionMessage<{
|
||||
resourceRef: string;
|
||||
resourceType: string;
|
||||
conditions: PermissionCriteria<PermissionCondition>;
|
||||
@@ -88,7 +88,8 @@ export type ApplyConditionsRequest = {
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type ApplyConditionsResponseEntry = Identified<DefinitivePolicyDecision>;
|
||||
export type ApplyConditionsResponseEntry =
|
||||
IdentifiedPermissionMessage<DefinitivePolicyDecision>;
|
||||
|
||||
/**
|
||||
* A batch of {@link ApplyConditionsResponseEntry} objects.
|
||||
|
||||
Reference in New Issue
Block a user