diff --git a/.changeset/tough-seahorses-learn.md b/.changeset/tough-seahorses-learn.md new file mode 100644 index 0000000000..f0b6bcb70a --- /dev/null +++ b/.changeset/tough-seahorses-learn.md @@ -0,0 +1,26 @@ +--- +'@backstage/plugin-bazaar-backend': minor +--- + +**BREAKING** The bazaar-backend createRouter now requires that the `identityApi` is passed to the router. + +These changes are **required** to `packages/backend/src/plugins/bazaar.ts` + +The user entity ref is now added to the members table and is taken from the requesting user using the `identityApi`. + +```diff +import { PluginEnvironment } from '../types'; +import { createRouter } from '@backstage/plugin-bazaar-backend'; +import { Router } from 'express'; + +export default async function createPlugin( + env: PluginEnvironment, +): Promise { + return await createRouter({ + logger: env.logger, + config: env.config, + database: env.database, ++ identity: env.identity, + }); +} +``` diff --git a/plugins/bazaar-backend/README.md b/plugins/bazaar-backend/README.md index b7a08a2fb8..266841b26b 100644 --- a/plugins/bazaar-backend/README.md +++ b/plugins/bazaar-backend/README.md @@ -15,7 +15,7 @@ yarn add --cwd packages/backend @backstage/plugin-bazaar-backend You'll need to add the plugin to the router in your `backend` package. You can do this by creating a file called `packages/backend/src/plugins/bazaar.ts` -```tsx +```typescript import { PluginEnvironment } from '../types'; import { createRouter } from '@backstage/plugin-bazaar-backend'; import { Router } from 'express'; @@ -27,6 +27,7 @@ export default async function createPlugin( logger: env.logger, config: env.config, database: env.database, + identity: env.identity, }); } ``` diff --git a/plugins/bazaar-backend/migrations/20220817150443_add_member_entity_ref.js b/plugins/bazaar-backend/migrations/20220817150443_add_member_entity_ref.js new file mode 100644 index 0000000000..79b80ef20c --- /dev/null +++ b/plugins/bazaar-backend/migrations/20220817150443_add_member_entity_ref.js @@ -0,0 +1,27 @@ +/* + * 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. + */ + +exports.up = async function up(knex) { + await knex.schema.alterTable('members', table => { + table.string('user_ref').nullable(); + }); +}; + +exports.down = async function down(knex) { + return knex.schema.table('members', table => { + table.dropColumn('user_ref'); + }); +}; diff --git a/plugins/bazaar-backend/package.json b/plugins/bazaar-backend/package.json index 4aaaa73a2b..c08287fcb8 100644 --- a/plugins/bazaar-backend/package.json +++ b/plugins/bazaar-backend/package.json @@ -25,6 +25,7 @@ "@backstage/backend-common": "workspace:^", "@backstage/backend-test-utils": "workspace:^", "@backstage/config": "workspace:^", + "@backstage/plugin-auth-node": "workspace:^", "@types/express": "^4.17.6", "express": "^4.17.1", "express-promise-router": "^4.1.0", diff --git a/plugins/bazaar-backend/src/service/DatabaseHandler.test.ts b/plugins/bazaar-backend/src/service/DatabaseHandler.test.ts index e1a722016b..371d20ff13 100644 --- a/plugins/bazaar-backend/src/service/DatabaseHandler.test.ts +++ b/plugins/bazaar-backend/src/service/DatabaseHandler.test.ts @@ -75,6 +75,13 @@ describe('DatabaseHandler', () => { responsible: bazaarProject.responsible, }); + // Add a member to the project + await knex('members').insert({ + item_id: 1, + user_ref: 'user:default/thehulk', + user_id: 'Bruce Banner', + }); + const res = await dbHandler.getMetadataByRef('ref1'); expect(res).toHaveLength(1); @@ -85,6 +92,9 @@ describe('DatabaseHandler', () => { expect(res[0].end_date).toEqual(null); expect(res[0].size).toEqual('small'); expect(res[0].responsible).toEqual('r'); + expect( + res[0].members_count === '1' || res[0].members_count === 1, + ).toBeTruthy(); }, 60_000, ); diff --git a/plugins/bazaar-backend/src/service/DatabaseHandler.ts b/plugins/bazaar-backend/src/service/DatabaseHandler.ts index d8d975b7ed..352866b4b5 100644 --- a/plugins/bazaar-backend/src/service/DatabaseHandler.ts +++ b/plugins/bazaar-backend/src/service/DatabaseHandler.ts @@ -67,11 +67,17 @@ export class DatabaseHandler { return await this.client.select('*').from('members').where({ item_id: id }); } - async addMember(id: number, userId: string, picture?: string) { + async addMember( + id: number, + userId: string, + userRef?: string, + picture?: string, + ) { await this.client .insert({ item_id: id, user_id: userId, + user_ref: userRef, picture: picture, }) .into('members'); diff --git a/plugins/bazaar-backend/src/service/router.ts b/plugins/bazaar-backend/src/service/router.ts index a5248c2949..359945f298 100644 --- a/plugins/bazaar-backend/src/service/router.ts +++ b/plugins/bazaar-backend/src/service/router.ts @@ -19,6 +19,7 @@ import express from 'express'; import Router from 'express-promise-router'; import { Logger } from 'winston'; import { Config } from '@backstage/config'; +import { IdentityApi } from '@backstage/plugin-auth-node'; import { DatabaseHandler } from './DatabaseHandler'; /** @public */ @@ -26,13 +27,14 @@ export interface RouterOptions { logger: Logger; database: PluginDatabaseManager; config: Config; + identity: IdentityApi; } /** @public */ export async function createRouter( options: RouterOptions, ): Promise { - const { logger, database } = options; + const { logger, database, identity } = options; const dbHandler = await DatabaseHandler.create({ database }); @@ -53,7 +55,14 @@ export async function createRouter( router.put('/projects/:id/member/:userId', async (request, response) => { const { id, userId } = request.params; - await dbHandler.addMember(parseInt(id, 10), userId, request.body?.picture); + const user = await identity.getIdentity({ request: request }); + + await dbHandler.addMember( + parseInt(id, 10), + userId, + user?.identity.userEntityRef, + request.body?.picture, + ); response.json({ status: 'ok' }); }); diff --git a/plugins/bazaar-backend/src/service/standaloneServer.ts b/plugins/bazaar-backend/src/service/standaloneServer.ts index e8a49fbf5d..a865a9875d 100644 --- a/plugins/bazaar-backend/src/service/standaloneServer.ts +++ b/plugins/bazaar-backend/src/service/standaloneServer.ts @@ -19,6 +19,7 @@ import { loadBackendConfig, useHotMemoize, } from '@backstage/backend-common'; +import { DefaultIdentityClient } from '@backstage/plugin-auth-node'; import { Server } from 'http'; import { Logger } from 'winston'; import { createRouter } from './router'; @@ -54,6 +55,7 @@ export async function startStandaloneServer( logger, database: { getClient: async () => db }, config: config, + identity: {} as DefaultIdentityClient, }); let service = createServiceBuilder(module)