permission-node: improve typings

Signed-off-by: Vincenzo Scamporlino <vincenzos@spotify.com>
This commit is contained in:
Vincenzo Scamporlino
2023-04-12 11:39:08 +02:00
parent 81ea755347
commit b947f4230d
2 changed files with 84 additions and 129 deletions
@@ -92,7 +92,7 @@ const defaultMockedGetResources2: CreatePermissionIntegrationRouterResourceOptio
resourceRefs.map(resourceRef => ({ id: resourceRef })),
);
const mockedResourceOptions = {
const mockedOptionResources: OptionResources = {
resources: [
{
resourceType: 'test-resource',
@@ -125,17 +125,6 @@ const createApp = (
return express().use(router);
};
const createAppWithResources = (
resourceOptions:
| CreatePermissionIntegrationRouterResourceOptions<string, any>
| OptionResources<string, any>,
) => {
const router = createPermissionIntegrationRouter(
resourceOptions as Parameters<typeof createPermissionIntegrationRouter>[0],
);
return express().use(router);
};
describe('createPermissionIntegrationRouter', () => {
afterEach(() => {
jest.clearAllMocks();
@@ -240,7 +229,11 @@ describe('createPermissionIntegrationRouter', () => {
(defaultMockedGetResources1 as jest.Mock).mockClear();
response = await request(createAppWithResources(mockedResourceOptions))
const app = express().use(
createPermissionIntegrationRouter(mockedOptionResources),
);
response = await request(app)
.post('/.well-known/backstage/permissions/apply-conditions')
.send({
items: [
@@ -459,7 +452,11 @@ describe('createPermissionIntegrationRouter', () => {
let response: Response;
beforeEach(async () => {
response = await request(createAppWithResources(mockedResourceOptions))
const app = express().use(
createPermissionIntegrationRouter(mockedOptionResources),
);
response = await request(app)
.post('/.well-known/backstage/permissions/apply-conditions')
.send({
items: [
@@ -763,11 +760,13 @@ describe('createPermissionIntegrationRouter', () => {
it('returns 501 with no getResources implementation', async () => {
const response = await request(
createAppWithResources({
resourceType: 'test-resource',
permissions: [testPermission],
rules: [testRule1, testRule2],
}),
express().use(
createPermissionIntegrationRouter({
resourceType: 'test-resource',
permissions: [testPermission],
rules: [testRule1, testRule2],
}),
),
)
.post('/.well-known/backstage/permissions/apply-conditions')
.send({
@@ -841,7 +840,7 @@ describe('createPermissionIntegrationRouter', () => {
});
it('returns a list of permissions and rules used by a given backend that was created with an array of resource options', async () => {
const response = await request(
createAppWithResources(mockedResourceOptions),
express().use(createPermissionIntegrationRouter(mockedOptionResources)),
).get('/.well-known/backstage/permissions/metadata');
expect(response.status).toEqual(200);
@@ -207,16 +207,46 @@ export type CreatePermissionIntegrationRouterResourceOptions<
) => Promise<Array<TResource | undefined>>;
};
/**
* Options for creating a permission integration router
*
* @public
*/
export type OptionResources<TResourceType extends string, TResource> = {
resources:
| { permissions: Array<Permission> }
| CreatePermissionIntegrationRouterResourceOptions<TResourceType, TResource>
| Array<CreatePermissionIntegrationRouterResourceOptions<string, any>>;
export type OptionResources<
TResourceType1 extends string = string,
TResource1 = any,
TResourceType2 extends string = string,
TResource2 = any,
TResourceType3 extends string = string,
TResource3 = any,
> = {
resources: Readonly<
| [
CreatePermissionIntegrationRouterResourceOptions<
TResourceType1,
TResource1
>,
]
| [
CreatePermissionIntegrationRouterResourceOptions<
TResourceType1,
TResource1
>,
CreatePermissionIntegrationRouterResourceOptions<
TResourceType2,
TResource2
>,
]
| [
CreatePermissionIntegrationRouterResourceOptions<
TResourceType1,
TResource1
>,
CreatePermissionIntegrationRouterResourceOptions<
TResourceType2,
TResource2
>,
CreatePermissionIntegrationRouterResourceOptions<
TResourceType3,
TResource3
>,
]
>;
};
/**
@@ -229,8 +259,8 @@ export type OptionResources<TResourceType extends string, TResource> = {
* In case the `permissions` option is provided, the router also
* provides a route that exposes permissions and routes of a plugin.
*
* In case an array of CreatePermissionIntegrationRouterResourceOptions is
* provided, the routes can handle permissions for multiple resource types.
* In case resources is provided, the routes can handle permissions
* for multiple resource types.
*
* @remarks
*
@@ -260,64 +290,6 @@ export type OptionResources<TResourceType extends string, TResource> = {
*
* @public
*/
export function createPermissionIntegrationRouter<
TResourceType extends string,
TResource,
>(
options:
| CreatePermissionIntegrationRouterResourceOptions<TResourceType, TResource>
| {
resources: CreatePermissionIntegrationRouterResourceOptions<
TResourceType,
TResource
>;
},
): express.Router;
/**
*
* Create an express Router which provides a route that exposes
* permissions and routes of a plugin.
* @public
*/
export function createPermissionIntegrationRouter(
options:
| { permissions: Array<Permission> }
| { resources: { permissions: Array<Permission> } },
): express.Router;
/**
*
* Create an express Router which provides an authorization route to allow
* integration between the permission backend and other Backstage backend
* plugins. Handles permissions for 2 resource types.
* @public
*/
export function createPermissionIntegrationRouter<
TResourceType1 extends string,
TResource1,
TResourceType2 extends string,
TResource2,
>(options: {
resources: [
CreatePermissionIntegrationRouterResourceOptions<
TResourceType1,
TResource1
>,
CreatePermissionIntegrationRouterResourceOptions<
TResourceType2,
TResource2
>,
];
}): express.Router;
/**
*
* Create an express Router which provides an authorization route to allow
* integration between the permission backend and other Backstage backend
* plugins. Handles permissions for 3 resource types.
* @public
*/
export function createPermissionIntegrationRouter<
TResourceType1 extends string,
TResource1,
@@ -325,39 +297,23 @@ export function createPermissionIntegrationRouter<
TResource2,
TResourceType3 extends string,
TResource3,
>(options: {
resources: [
CreatePermissionIntegrationRouterResourceOptions<
TResourceType1,
TResource1
>,
CreatePermissionIntegrationRouterResourceOptions<
TResourceType2,
TResource2
>,
CreatePermissionIntegrationRouterResourceOptions<
TResourceType3,
TResource3
>,
];
}): express.Router;
/**
* @public
*/
export function createPermissionIntegrationRouter<
TResourceType extends string,
TResource,
>(
options:
| { permissions: Array<Permission> }
| CreatePermissionIntegrationRouterResourceOptions<TResourceType, TResource>
| OptionResources<TResourceType, TResource>,
| CreatePermissionIntegrationRouterResourceOptions<
TResourceType1,
TResource1
>
| OptionResources<
TResourceType1,
TResource1,
TResourceType2,
TResource2,
TResourceType3,
TResource3
>,
): express.Router {
const optionsWithResources = options as OptionResources<
TResourceType,
TResource
>;
const optionsWithResources = options as OptionResources;
const allOptions = [
optionsWithResources.resources ? optionsWithResources.resources : options,
].flat();
@@ -365,8 +321,8 @@ export function createPermissionIntegrationRouter<
option =>
(
option as CreatePermissionIntegrationRouterResourceOptions<
TResourceType,
TResource
TResourceType1,
TResource1
>
).rules || [],
);
@@ -381,16 +337,16 @@ export function createPermissionIntegrationRouter<
option as
| { permissions: Array<Permission> }
| CreatePermissionIntegrationRouterResourceOptions<
TResourceType,
TResource
TResourceType1,
TResource1
>,
)
) {
acc.push(
(
option as CreatePermissionIntegrationRouterResourceOptions<
TResourceType,
TResource
TResourceType1,
TResource1
>
).resourceType,
);
@@ -429,8 +385,8 @@ export function createPermissionIntegrationRouter<
const getResourcesByResourceType: Record<
string,
CreatePermissionIntegrationRouterResourceOptions<
TResourceType,
TResource
TResourceType1,
TResource1
>['getResources']
> = {};
@@ -438,8 +394,8 @@ export function createPermissionIntegrationRouter<
option = option as
| { permissions: Array<Permission> }
| CreatePermissionIntegrationRouterResourceOptions<
TResourceType,
TResource
TResourceType1,
TResource1
>;
if (isCreatePermissionIntegrationRouterResourceOptions(option)) {
ruleMapByResourceType[option.resourceType] = createGetRule(