From 70f29c54238823855f10f1a5863fa0d9f90a9f93 Mon Sep 17 00:00:00 2001 From: Hasan Oezdemir <21654050+nodify-at@users.noreply.github.com> Date: Tue, 1 Mar 2022 23:45:01 +0100 Subject: [PATCH] (feature): remove unused configuration and improved permission management, describe the permission integration in detail. Signed-off-by: Hasan Oezdemir <21654050+nodify-at@users.noreply.github.com> --- .changeset/orange-cobras-shave.md | 10 +++- .changeset/ten-fireants-march.md | 5 +- plugins/jenkins-backend/api-report.md | 50 +------------------ plugins/jenkins-backend/package.json | 3 -- plugins/jenkins-backend/src/index.ts | 1 - .../src/permissions/conditionExports.ts | 27 ---------- .../jenkins-backend/src/permissions/index.ts | 20 -------- .../src/permissions/rules/index.ts | 30 ----------- .../jenkins-backend/src/service/jenkinsApi.ts | 7 +-- plugins/jenkins-backend/src/service/router.ts | 21 ++++---- 10 files changed, 27 insertions(+), 147 deletions(-) delete mode 100644 plugins/jenkins-backend/src/permissions/conditionExports.ts delete mode 100644 plugins/jenkins-backend/src/permissions/index.ts delete mode 100644 plugins/jenkins-backend/src/permissions/rules/index.ts diff --git a/.changeset/orange-cobras-shave.md b/.changeset/orange-cobras-shave.md index 2b840dab48..9f54f6d48b 100644 --- a/.changeset/orange-cobras-shave.md +++ b/.changeset/orange-cobras-shave.md @@ -2,5 +2,11 @@ '@backstage/plugin-jenkins-backend': minor --- -Add permissions support for Jenkins backend and provide an integration router. You must pass a permission router -if you want to enable permissions in Jenkins plugin. +Jenkins plugin supports permissions now. We have added a new permission, so you can manage the permission for the users. +A new permission `jenkinsExecutePermission` is provided in `jenkins-common` package. This permission rule will be applied to check rebuild actions +if user is allowed to execute this action. + +> We use 'catalog-entity' as a resource type, so you need to integrate a policy to handle catalog-entity resources + +> You need to use this permission in your permission policy to check the user role/rights and return +> `AuthorizeResult.ALLOW` to allow rebuild action to logged user. (e.g: you can check if user or related group owns the entity) diff --git a/.changeset/ten-fireants-march.md b/.changeset/ten-fireants-march.md index 9376292196..8283eef5d6 100644 --- a/.changeset/ten-fireants-march.md +++ b/.changeset/ten-fireants-march.md @@ -2,4 +2,7 @@ '@backstage/plugin-jenkins': minor --- -Integrated the permission plugin, if enabled, the actions can be executed only by owned user (or assigned to related group) +Jenkins plugin supports permissions now. We have added a new permission, so you can manage the permission for the users. See relates notes for `jenkins-plugin` for more details. + +Rebuild action will be disabled if the user does not have necessary rights to execute rebuild action. A permission policy (defined in backend) must handle and check the identity rights +and return `AuthorizeResult.ALLOW` if user is allowed to execute rebuild action. diff --git a/plugins/jenkins-backend/api-report.md b/plugins/jenkins-backend/api-report.md index 41bebb1061..7af3968897 100644 --- a/plugins/jenkins-backend/api-report.md +++ b/plugins/jenkins-backend/api-report.md @@ -4,26 +4,11 @@ ```ts import { CatalogApi } from '@backstage/catalog-client'; -import { ConditionalPolicyDecision } from '@backstage/plugin-permission-node'; -import { Conditions } from '@backstage/plugin-permission-node'; import { Config } from '@backstage/config'; -import { EntitiesSearchFilter } from '@backstage/plugin-catalog-backend'; -import { Entity } from '@backstage/catalog-model'; import { EntityName } from '@backstage/catalog-model'; import express from 'express'; -import { Logger as Logger_2 } from 'winston'; -import { PermissionAuthorizer } from '@backstage/plugin-permission-common'; -import { PermissionCondition } from '@backstage/plugin-permission-common'; -import { PermissionCriteria } from '@backstage/plugin-permission-common'; -import { PermissionRule } from '@backstage/plugin-permission-node'; -import { PluginEndpointDiscovery } from '@backstage/backend-common'; - -// Warning: (ae-missing-release-tag) "createJenkinsPermissionPolicy" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const createJenkinsPermissionPolicy: ( - conditions: PermissionCriteria>, -) => ConditionalPolicyDecision; +import type { Logger as Logger_2 } from 'winston'; +import type { PermissionAuthorizer } from '@backstage/plugin-permission-common'; // Warning: (ae-missing-release-tag) "createRouter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -50,17 +35,6 @@ export class DefaultJenkinsInfoProvider implements JenkinsInfoProvider { static readonly OLD_JENKINS_ANNOTATION = 'jenkins.io/github-folder'; } -// Warning: (ae-missing-release-tag) "jenkinsConditions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const jenkinsConditions: Conditions<{ - isEntityOwner: PermissionRule< - Entity, - EntitiesSearchFilter, - [claims: string[]] - >; -}>; - // Warning: (ae-missing-release-tag) "JenkinsConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public @@ -113,30 +87,10 @@ export interface JenkinsInstanceConfig { username: string; } -// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag -// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@" -// -// @public -export const jenkinsPermissionRules: { - isEntityOwner: PermissionRule< - Entity, - EntitiesSearchFilter, - [claims: string[]] - >; -}; - // Warning: (ae-missing-release-tag) "RouterOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export interface RouterOptions { - // (undocumented) - config?: Config; - // (undocumented) - discovery?: PluginEndpointDiscovery; - // (undocumented) - fetchApi?: { - fetch: typeof fetch; - }; // (undocumented) jenkinsInfoProvider: JenkinsInfoProvider; // (undocumented) diff --git a/plugins/jenkins-backend/package.json b/plugins/jenkins-backend/package.json index f0659f42d8..64278618af 100644 --- a/plugins/jenkins-backend/package.json +++ b/plugins/jenkins-backend/package.json @@ -31,11 +31,8 @@ "@backstage/config": "^0.1.15", "@backstage/errors": "^0.2.2", "@backstage/plugin-auth-node": "^0.1.3", - "@backstage/plugin-catalog-backend": "^0.22.0", - "@backstage/plugin-catalog-common": "^0.1.4", "@backstage/plugin-jenkins-common": "^0.1.0", "@backstage/plugin-permission-common": "^0.5.1", - "@backstage/plugin-permission-node": "^0.5.2", "@types/express": "^4.17.6", "express": "^4.17.1", "express-promise-router": "^4.1.0", diff --git a/plugins/jenkins-backend/src/index.ts b/plugins/jenkins-backend/src/index.ts index c584842e07..c55335c52d 100644 --- a/plugins/jenkins-backend/src/index.ts +++ b/plugins/jenkins-backend/src/index.ts @@ -21,4 +21,3 @@ */ export * from './service'; -export * from './permissions'; diff --git a/plugins/jenkins-backend/src/permissions/conditionExports.ts b/plugins/jenkins-backend/src/permissions/conditionExports.ts deleted file mode 100644 index 197f2cb0ec..0000000000 --- a/plugins/jenkins-backend/src/permissions/conditionExports.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2022 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 { jenkinsPermissionRules } from './rules'; -import { createConditionExports } from '@backstage/plugin-permission-node'; -import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common'; - -const { conditions, createPolicyDecision } = createConditionExports({ - pluginId: 'jenkins', - resourceType: RESOURCE_TYPE_CATALOG_ENTITY, - rules: jenkinsPermissionRules, -}); - -export const jenkinsConditions = conditions; -export const createJenkinsPermissionPolicy = createPolicyDecision; diff --git a/plugins/jenkins-backend/src/permissions/index.ts b/plugins/jenkins-backend/src/permissions/index.ts deleted file mode 100644 index 522f40aeee..0000000000 --- a/plugins/jenkins-backend/src/permissions/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2022 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. - */ -export { - createJenkinsPermissionPolicy, - jenkinsConditions, -} from './conditionExports'; -export * from './rules'; diff --git a/plugins/jenkins-backend/src/permissions/rules/index.ts b/plugins/jenkins-backend/src/permissions/rules/index.ts deleted file mode 100644 index 0cd07b26a8..0000000000 --- a/plugins/jenkins-backend/src/permissions/rules/index.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2022 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 { permissionRules } from '@backstage/plugin-catalog-backend'; -/** - * - * Jenkins' permission rules can be used to defined different kind of rules to check if the user authorizes an action - * (or listing the jobs ever) - * - * Provided rules: - * {isEntityOwner} can be used to determine if a user or the group of the user - * owns an entity. - * - * @public - */ -export const jenkinsPermissionRules = { - isEntityOwner: permissionRules.isEntityOwner, -}; diff --git a/plugins/jenkins-backend/src/service/jenkinsApi.ts b/plugins/jenkins-backend/src/service/jenkinsApi.ts index c0b1c63112..da16bbc553 100644 --- a/plugins/jenkins-backend/src/service/jenkinsApi.ts +++ b/plugins/jenkins-backend/src/service/jenkinsApi.ts @@ -14,9 +14,9 @@ * limitations under the License. */ -import { JenkinsInfo } from './jenkinsInfoProvider'; +import type { JenkinsInfo } from './jenkinsInfoProvider'; import jenkins from 'jenkins'; -import { +import type { BackstageBuild, BackstageProject, JenkinsBuild, @@ -139,13 +139,14 @@ export class JenkinsApiImpl { async buildProject( jenkinsInfo: JenkinsInfo, jobFullName: string, + resourceRef?: string, options?: { token?: string }, ) { const client = await JenkinsApiImpl.getClient(jenkinsInfo); if (this.permissionApi) { const response = await this.permissionApi.authorize( - [{ permission: jenkinsExecutePermission }], + [{ permission: jenkinsExecutePermission, resourceRef }], { token: options?.token }, ); // permission api returns always at least one item, we need to check only one result since we do not expect any additional results diff --git a/plugins/jenkins-backend/src/service/router.ts b/plugins/jenkins-backend/src/service/router.ts index 89d755efed..dcef2c2e0a 100644 --- a/plugins/jenkins-backend/src/service/router.ts +++ b/plugins/jenkins-backend/src/service/router.ts @@ -14,25 +14,19 @@ * limitations under the License. */ -import { - errorHandler, - PluginEndpointDiscovery, -} from '@backstage/backend-common'; +import { errorHandler } from '@backstage/backend-common'; import express from 'express'; import Router from 'express-promise-router'; -import { Logger } from 'winston'; -import { JenkinsInfoProvider } from './jenkinsInfoProvider'; +import type { Logger } from 'winston'; +import type { JenkinsInfoProvider } from './jenkinsInfoProvider'; import { JenkinsApiImpl } from './jenkinsApi'; -import { Config } from '@backstage/config'; -import { PermissionAuthorizer } from '@backstage/plugin-permission-common'; +import type { PermissionAuthorizer } from '@backstage/plugin-permission-common'; import { getBearerTokenFromAuthorizationHeader } from '@backstage/plugin-auth-node'; +import { stringifyEntityRef } from '@backstage/catalog-model'; export interface RouterOptions { logger: Logger; jenkinsInfoProvider: JenkinsInfoProvider; - config?: Config; - discovery?: PluginEndpointDiscovery; - fetchApi?: { fetch: typeof fetch }; permissions?: PermissionAuthorizer; } @@ -125,7 +119,10 @@ export async function createRouter( request.header('authorization'), ); - await jenkinsApi.buildProject(jenkinsInfo, jobFullName, { token }); + const resourceRef = stringifyEntityRef({ kind, namespace, name }); + await jenkinsApi.buildProject(jenkinsInfo, jobFullName, resourceRef, { + token, + }); response.json({}); }, );