diff --git a/.changeset/famous-beds-break.md b/.changeset/famous-beds-break.md new file mode 100644 index 0000000000..a3d2e929a8 --- /dev/null +++ b/.changeset/famous-beds-break.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-permission-node': patch +--- + +Introduced alpha export of the `policyExtensionPoint` for use in the new backend system. diff --git a/.changeset/famous-beds-repair.md b/.changeset/famous-beds-repair.md index 54adce96b5..f08506b130 100644 --- a/.changeset/famous-beds-repair.md +++ b/.changeset/famous-beds-repair.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-permission-backend': minor +'@backstage/plugin-permission-backend': patch --- -Introduced alpha export of the `permissionPlugin` using the new backend system +Introduced alpha export of the `permissionPlugin` for use in the new backend system, along with a `permissionModuleAllowAllPolicy` that can be used to allow all requests. diff --git a/packages/backend-next/src/index.ts b/packages/backend-next/src/index.ts index 12437c8ab5..fc936b1b0f 100644 --- a/packages/backend-next/src/index.ts +++ b/packages/backend-next/src/index.ts @@ -16,17 +16,19 @@ import { createBackend } from '@backstage/backend-defaults'; import { appPlugin } from '@backstage/plugin-app-backend/alpha'; -import { todoPlugin } from '@backstage/plugin-todo-backend'; -import { techdocsPlugin } from '@backstage/plugin-techdocs-backend/alpha'; import { catalogPlugin } from '@backstage/plugin-catalog-backend/alpha'; -import { catalogModuleTemplateKind } from '@backstage/plugin-scaffolder-backend/alpha'; -import { searchPlugin } from '@backstage/plugin-search-backend/alpha'; -import { searchModuleCatalogCollator } from '@backstage/plugin-search-backend-module-catalog/alpha'; -import { searchModuleTechDocsCollator } from '@backstage/plugin-search-backend-module-techdocs/alpha'; -import { searchModuleExploreCollator } from '@backstage/plugin-search-backend-module-explore/alpha'; import { kubernetesPlugin } from '@backstage/plugin-kubernetes-backend/alpha'; -import { permissionPlugin } from '@backstage/plugin-permission-backend/alpha'; -import { ExamplePermissionPolicy } from './ExamplePermissionPolicy'; +import { + permissionModuleAllowAllPolicy, + permissionPlugin, +} from '@backstage/plugin-permission-backend/alpha'; +import { catalogModuleTemplateKind } from '@backstage/plugin-scaffolder-backend/alpha'; +import { searchModuleCatalogCollator } from '@backstage/plugin-search-backend-module-catalog/alpha'; +import { searchModuleExploreCollator } from '@backstage/plugin-search-backend-module-explore/alpha'; +import { searchModuleTechDocsCollator } from '@backstage/plugin-search-backend-module-techdocs/alpha'; +import { searchPlugin } from '@backstage/plugin-search-backend/alpha'; +import { techdocsPlugin } from '@backstage/plugin-techdocs-backend/alpha'; +import { todoPlugin } from '@backstage/plugin-todo-backend'; const backend = createBackend(); @@ -52,6 +54,7 @@ backend.add(searchModuleExploreCollator()); backend.add(kubernetesPlugin()); // Permissions -backend.add(permissionPlugin({ policy: new ExamplePermissionPolicy() })); +backend.add(permissionPlugin()); +backend.add(permissionModuleAllowAllPolicy()); backend.start(); diff --git a/plugins/permission-backend/alpha-api-report.md b/plugins/permission-backend/alpha-api-report.md index a86d8903ad..926691930b 100644 --- a/plugins/permission-backend/alpha-api-report.md +++ b/plugins/permission-backend/alpha-api-report.md @@ -4,17 +4,12 @@ ```ts import { BackendFeature } from '@backstage/backend-plugin-api'; -import { PermissionPolicy } from '@backstage/plugin-permission-node'; // @alpha -export const permissionPlugin: ( - options: PermissionPluginOptions, -) => BackendFeature; +export const permissionModuleAllowAllPolicy: () => BackendFeature; // @alpha -export type PermissionPluginOptions = { - policy: PermissionPolicy; -}; +export const permissionPlugin: () => BackendFeature; // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/permission-backend/src/alpha.ts b/plugins/permission-backend/src/alpha.ts index a03fa0cee6..f6a2bb4f09 100644 --- a/plugins/permission-backend/src/alpha.ts +++ b/plugins/permission-backend/src/alpha.ts @@ -14,4 +14,4 @@ * limitations under the License. */ -export { permissionPlugin, type PermissionPluginOptions } from './plugin'; +export { permissionPlugin, permissionModuleAllowAllPolicy } from './plugin'; diff --git a/plugins/permission-backend/src/plugin.ts b/plugins/permission-backend/src/plugin.ts index 9a6e5a13af..5c0a9a87a0 100644 --- a/plugins/permission-backend/src/plugin.ts +++ b/plugins/permission-backend/src/plugin.ts @@ -17,50 +17,102 @@ import { loggerToWinstonLogger } from '@backstage/backend-common'; import { coreServices, + createBackendModule, createBackendPlugin, } from '@backstage/backend-plugin-api'; -import { PermissionPolicy } from '@backstage/plugin-permission-node'; +import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; +import { + AuthorizeResult, + PolicyDecision, +} from '@backstage/plugin-permission-common'; +import { + PermissionPolicy, + PolicyQuery, +} from '@backstage/plugin-permission-node'; +import { + policyExtensionPoint, + PolicyExtensionPoint, +} from '@backstage/plugin-permission-node/alpha'; import { createRouter } from './service'; +class PolicyExtensionPointImpl implements PolicyExtensionPoint { + public policy: PermissionPolicy | undefined; + + setPolicy(policy: PermissionPolicy): void { + if (this.policy) { + throw new Error('Policy already set'); + } + this.policy = policy; + } +} + /** - * Permission plugin options + * A permission policy module that allows all requests. * * @alpha */ -export type PermissionPluginOptions = { - policy: PermissionPolicy; -}; +export const permissionModuleAllowAllPolicy = createBackendModule({ + moduleId: 'allowAllPolicy', + pluginId: 'permission', + register(reg) { + class AllowAllPermissionPolicy implements PermissionPolicy { + async handle( + _request: PolicyQuery, + _user?: BackstageIdentityResponse, + ): Promise { + return { + result: AuthorizeResult.ALLOW, + }; + } + } + + reg.registerInit({ + deps: { policy: policyExtensionPoint }, + async init({ policy }) { + policy.setPolicy(new AllowAllPermissionPolicy()); + }, + }); + }, +}); /** * Permission plugin * * @alpha */ -export const permissionPlugin = createBackendPlugin( - (options: PermissionPluginOptions) => ({ - pluginId: 'permission', - register(env) { - env.registerInit({ - deps: { - http: coreServices.httpRouter, - config: coreServices.config, - logger: coreServices.logger, - discovery: coreServices.discovery, - identity: coreServices.identity, - }, - async init({ http, config, logger, discovery, identity }) { - const winstonLogger = loggerToWinstonLogger(logger); - http.use( - await createRouter({ - config, - discovery, - identity, - logger: winstonLogger, - policy: options.policy, - }), +export const permissionPlugin = createBackendPlugin(() => ({ + pluginId: 'permission', + register(env) { + const policies = new PolicyExtensionPointImpl(); + + env.registerExtensionPoint(policyExtensionPoint, policies); + + env.registerInit({ + deps: { + http: coreServices.httpRouter, + config: coreServices.config, + logger: coreServices.logger, + discovery: coreServices.discovery, + identity: coreServices.identity, + }, + async init({ http, config, logger, discovery, identity }) { + const winstonLogger = loggerToWinstonLogger(logger); + if (!policies.policy) { + throw new Error( + 'No policy module installed! Please install a policy module. If you want to allow all requests, use permissionModuleAllowAllPolicy', ); - }, - }); - }, - }), -); + } + + http.use( + await createRouter({ + config, + discovery, + identity, + logger: winstonLogger, + policy: policies.policy, + }), + ); + }, + }); + }, +})); diff --git a/plugins/permission-node/alpha-api-report.md b/plugins/permission-node/alpha-api-report.md new file mode 100644 index 0000000000..1be8e77035 --- /dev/null +++ b/plugins/permission-node/alpha-api-report.md @@ -0,0 +1,18 @@ +## API Report File for "@backstage/plugin-permission-node" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { ExtensionPoint } from '@backstage/backend-plugin-api'; +import { PermissionPolicy } from '@backstage/plugin-permission-node'; + +// @alpha +export type PolicyExtensionPoint = { + setPolicy(policy: PermissionPolicy): void; +}; + +// @alpha +export const policyExtensionPoint: ExtensionPoint; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/permission-node/package.json b/plugins/permission-node/package.json index d8adbc08e7..308bd05ee2 100644 --- a/plugins/permission-node/package.json +++ b/plugins/permission-node/package.json @@ -10,6 +10,21 @@ "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } + }, "backstage": { "role": "node-library" }, @@ -34,6 +49,7 @@ }, "dependencies": { "@backstage/backend-common": "workspace:^", + "@backstage/backend-plugin-api": "workspace:^", "@backstage/config": "workspace:^", "@backstage/errors": "workspace:^", "@backstage/plugin-auth-node": "workspace:^", diff --git a/packages/backend-next/src/ExamplePermissionPolicy.ts b/plugins/permission-node/src/alpha.ts similarity index 54% rename from packages/backend-next/src/ExamplePermissionPolicy.ts rename to plugins/permission-node/src/alpha.ts index cf7c024e01..1031dc4fe9 100644 --- a/packages/backend-next/src/ExamplePermissionPolicy.ts +++ b/plugins/permission-node/src/alpha.ts @@ -13,23 +13,5 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; -import { - AuthorizeResult, - PolicyDecision, -} from '@backstage/plugin-permission-common'; -import { - PermissionPolicy, - PolicyQuery, -} from '@backstage/plugin-permission-node'; -export class ExamplePermissionPolicy implements PermissionPolicy { - async handle( - _request: PolicyQuery, - _user?: BackstageIdentityResponse, - ): Promise { - return { - result: AuthorizeResult.ALLOW, - }; - } -} +export { type PolicyExtensionPoint, policyExtensionPoint } from './plugin'; diff --git a/plugins/permission-node/src/plugin.ts b/plugins/permission-node/src/plugin.ts new file mode 100644 index 0000000000..646223a3ee --- /dev/null +++ b/plugins/permission-node/src/plugin.ts @@ -0,0 +1,36 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createExtensionPoint } from '@backstage/backend-plugin-api'; +import { PermissionPolicy } from '@backstage/plugin-permission-node'; + +/** + * Allows supplying policies to the permissions backend + * + * @alpha + */ +export type PolicyExtensionPoint = { + setPolicy(policy: PermissionPolicy): void; +}; + +/** + * Allows supplying policies to the permissions backend + * + * @alpha + */ +export const policyExtensionPoint = createExtensionPoint({ + id: 'permission.policy', +}); diff --git a/yarn.lock b/yarn.lock index 80c89a35d6..02e38e1b33 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7650,6 +7650,7 @@ __metadata: resolution: "@backstage/plugin-permission-node@workspace:plugins/permission-node" dependencies: "@backstage/backend-common": "workspace:^" + "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^"