Merge pull request #23068 from backstage/rugvip/pr/640b5d
badges-backend: migrate to support new auth services
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-badges-backend': patch
|
||||
---
|
||||
|
||||
Migrated to support new auth services.
|
||||
@@ -3,11 +3,13 @@
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { AuthService } from '@backstage/backend-plugin-api';
|
||||
import { BackendFeature } from '@backstage/backend-plugin-api';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { Config } from '@backstage/config';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import express from 'express';
|
||||
import { HttpAuthService } from '@backstage/backend-plugin-api';
|
||||
import { IdentityApi } from '@backstage/plugin-auth-node';
|
||||
import { Logger } from 'winston';
|
||||
import { PluginEndpointDiscovery } from '@backstage/backend-common';
|
||||
@@ -131,6 +133,8 @@ export class DefaultBadgeBuilder implements BadgeBuilder {
|
||||
|
||||
// @public (undocumented)
|
||||
export interface RouterOptions {
|
||||
// (undocumented)
|
||||
auth?: AuthService;
|
||||
// (undocumented)
|
||||
badgeBuilder?: BadgeBuilder;
|
||||
// (undocumented)
|
||||
@@ -144,6 +148,8 @@ export interface RouterOptions {
|
||||
// (undocumented)
|
||||
discovery: PluginEndpointDiscovery;
|
||||
// (undocumented)
|
||||
httpAuth?: HttpAuthService;
|
||||
// (undocumented)
|
||||
identity: IdentityApi;
|
||||
// (undocumented)
|
||||
logger: Logger;
|
||||
|
||||
@@ -38,6 +38,8 @@ export const badgesPlugin = createBackendPlugin({
|
||||
tokenManager: coreServices.tokenManager,
|
||||
identity: coreServices.identity,
|
||||
httpRouter: coreServices.httpRouter,
|
||||
httpAuth: coreServices.httpAuth,
|
||||
auth: coreServices.auth,
|
||||
},
|
||||
async init({
|
||||
config,
|
||||
@@ -46,6 +48,8 @@ export const badgesPlugin = createBackendPlugin({
|
||||
tokenManager,
|
||||
identity,
|
||||
httpRouter,
|
||||
httpAuth,
|
||||
auth,
|
||||
}) {
|
||||
httpRouter.use(
|
||||
await createRouter({
|
||||
@@ -55,6 +59,8 @@ export const badgesPlugin = createBackendPlugin({
|
||||
discovery,
|
||||
tokenManager,
|
||||
identity,
|
||||
httpAuth,
|
||||
auth,
|
||||
}),
|
||||
);
|
||||
},
|
||||
|
||||
@@ -32,6 +32,7 @@ import {
|
||||
IdentityApiGetIdentityRequest,
|
||||
} from '@backstage/plugin-auth-node';
|
||||
import { BadgesStore } from '../database/badgesStore';
|
||||
import { mockCredentials, mockServices } from '@backstage/backend-test-utils';
|
||||
|
||||
describe('createRouter', () => {
|
||||
let app: express.Express;
|
||||
@@ -148,6 +149,8 @@ describe('createRouter', () => {
|
||||
tokenManager,
|
||||
logger: getVoidLogger(),
|
||||
identity: { getIdentity },
|
||||
auth: mockServices.auth(),
|
||||
httpAuth: mockServices.httpAuth(),
|
||||
});
|
||||
app = express().use(router);
|
||||
});
|
||||
@@ -167,6 +170,8 @@ describe('createRouter', () => {
|
||||
logger: getVoidLogger(),
|
||||
identity: { getIdentity },
|
||||
badgeStore: badgeStore,
|
||||
auth: mockServices.auth(),
|
||||
httpAuth: mockServices.httpAuth(),
|
||||
});
|
||||
expect(router).toBeDefined();
|
||||
});
|
||||
@@ -232,9 +237,9 @@ describe('createRouter', () => {
|
||||
it('returns obfuscated entity and badges', async () => {
|
||||
catalog.getEntityByRef = jest.fn().mockResolvedValue(entity);
|
||||
|
||||
const obfuscatedEntity = await request(app)
|
||||
.get('/entity/default/component/test/obfuscated')
|
||||
.set('Authorization', 'Bearer fakeToken');
|
||||
const obfuscatedEntity = await request(app).get(
|
||||
'/entity/default/component/test/obfuscated',
|
||||
);
|
||||
|
||||
expect(obfuscatedEntity.status).toEqual(200);
|
||||
expect(obfuscatedEntity.body.uuid).toMatch(
|
||||
@@ -245,7 +250,12 @@ describe('createRouter', () => {
|
||||
|
||||
expect(catalog.getEntityByRef).toHaveBeenCalledWith(
|
||||
{ namespace: 'default', kind: 'component', name: 'test' },
|
||||
{ token: 'fakeToken' },
|
||||
{
|
||||
token: mockCredentials.service.token({
|
||||
onBehalfOf: mockCredentials.user(),
|
||||
targetPluginId: 'catalog',
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
const uuid = obfuscatedEntity.body.uuid;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
import express from 'express';
|
||||
import Router from 'express-promise-router';
|
||||
import {
|
||||
createLegacyAuthAdapters,
|
||||
DatabaseManager,
|
||||
errorHandler,
|
||||
PluginEndpointDiscovery,
|
||||
@@ -30,9 +31,9 @@ import { BadgeContext, BadgeFactories } from '../types';
|
||||
import { isNil } from 'lodash';
|
||||
import { Logger } from 'winston';
|
||||
import { IdentityApi } from '@backstage/plugin-auth-node';
|
||||
import { getBearerTokenFromAuthorizationHeader } from '@backstage/plugin-auth-node';
|
||||
import { BadgesStore, DatabaseBadgesStore } from '../database/badgesStore';
|
||||
import { createDefaultBadgeFactories } from '../badges';
|
||||
import { AuthService, HttpAuthService } from '@backstage/backend-plugin-api';
|
||||
|
||||
/** @public */
|
||||
export interface RouterOptions {
|
||||
@@ -42,6 +43,8 @@ export interface RouterOptions {
|
||||
config: Config;
|
||||
discovery: PluginEndpointDiscovery;
|
||||
tokenManager: TokenManager;
|
||||
auth?: AuthService;
|
||||
httpAuth?: HttpAuthService;
|
||||
logger: Logger;
|
||||
identity: IdentityApi;
|
||||
badgeStore?: BadgesStore;
|
||||
@@ -60,28 +63,31 @@ export async function createRouter(
|
||||
);
|
||||
const router = Router();
|
||||
|
||||
const { config, logger, tokenManager, discovery } = options;
|
||||
const { config, logger, discovery } = options;
|
||||
const baseUrl = await discovery.getExternalBaseUrl('badges');
|
||||
|
||||
const { auth, httpAuth } = createLegacyAuthAdapters(options);
|
||||
|
||||
if (config.getOptionalBoolean('app.badges.obfuscate')) {
|
||||
return obfuscatedRoute(
|
||||
router,
|
||||
catalog,
|
||||
badgeBuilder,
|
||||
tokenManager,
|
||||
logger,
|
||||
options,
|
||||
config,
|
||||
baseUrl,
|
||||
auth,
|
||||
httpAuth,
|
||||
);
|
||||
}
|
||||
return nonObfuscatedRoute(
|
||||
router,
|
||||
catalog,
|
||||
badgeBuilder,
|
||||
tokenManager,
|
||||
config,
|
||||
baseUrl,
|
||||
auth,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -89,18 +95,19 @@ async function obfuscatedRoute(
|
||||
router: express.Router,
|
||||
catalog: CatalogApi,
|
||||
badgeBuilder: BadgeBuilder,
|
||||
tokenManager: TokenManager,
|
||||
logger: Logger,
|
||||
options: RouterOptions,
|
||||
config: Config,
|
||||
baseUrl: string,
|
||||
auth: AuthService,
|
||||
httpAuth: HttpAuthService,
|
||||
) {
|
||||
logger.info('Badges obfuscation is enabled');
|
||||
|
||||
const store = options.badgeStore
|
||||
? options.badgeStore
|
||||
: await DatabaseBadgesStore.create({
|
||||
database: await DatabaseManager.fromConfig(config).forPlugin('badges'),
|
||||
database: DatabaseManager.fromConfig(config).forPlugin('badges'),
|
||||
});
|
||||
|
||||
router.get('/entity/:entityUuid/badge-specs', async (req, res) => {
|
||||
@@ -117,16 +124,15 @@ async function obfuscatedRoute(
|
||||
const name = badgeInfos.name;
|
||||
const namespace = badgeInfos.namespace;
|
||||
const kind = badgeInfos.kind;
|
||||
const token = await tokenManager.getToken();
|
||||
const { token } = await auth.getPluginRequestToken({
|
||||
onBehalfOf: await auth.getOwnServiceCredentials(),
|
||||
targetPluginId: 'catalog',
|
||||
});
|
||||
|
||||
// Query the catalog with the name, namespace, kind to get the entity informations
|
||||
// Query the catalog with the name, namespace, kind to get the entity information
|
||||
const entity = await catalog.getEntityByRef(
|
||||
{
|
||||
namespace,
|
||||
kind,
|
||||
name,
|
||||
},
|
||||
token,
|
||||
{ namespace, kind, name },
|
||||
{ token },
|
||||
);
|
||||
|
||||
if (isNil(entity)) {
|
||||
@@ -168,14 +174,15 @@ async function obfuscatedRoute(
|
||||
const name = badgeInfo.name;
|
||||
const namespace = badgeInfo.namespace;
|
||||
const kind = badgeInfo.kind;
|
||||
const token = await tokenManager.getToken();
|
||||
|
||||
const { token } = await auth.getPluginRequestToken({
|
||||
onBehalfOf: await auth.getOwnServiceCredentials(),
|
||||
targetPluginId: 'catalog',
|
||||
});
|
||||
|
||||
const entity = await catalog.getEntityByRef(
|
||||
{
|
||||
namespace,
|
||||
kind,
|
||||
name,
|
||||
},
|
||||
token,
|
||||
{ namespace, kind, name },
|
||||
{ token },
|
||||
);
|
||||
if (isNil(entity)) {
|
||||
throw new NotFoundError(
|
||||
@@ -217,20 +224,17 @@ async function obfuscatedRoute(
|
||||
router.get(
|
||||
'/entity/:namespace/:kind/:name/obfuscated',
|
||||
async function authenticate(req, _res, next) {
|
||||
const token = getBearerTokenFromAuthorizationHeader(
|
||||
req.headers.authorization,
|
||||
);
|
||||
|
||||
const { kind, namespace, name } = req.params;
|
||||
|
||||
const { token } = await auth.getPluginRequestToken({
|
||||
onBehalfOf: await httpAuth.credentials(req),
|
||||
targetPluginId: 'catalog',
|
||||
});
|
||||
|
||||
// check that the user has the correct permissions
|
||||
// to view the catalog entity by forwarding the token
|
||||
const entity = await catalog.getEntityByRef(
|
||||
{
|
||||
kind,
|
||||
namespace,
|
||||
name,
|
||||
},
|
||||
{ kind, namespace, name },
|
||||
{ token },
|
||||
);
|
||||
|
||||
@@ -266,16 +270,20 @@ async function nonObfuscatedRoute(
|
||||
router: express.Router,
|
||||
catalog: CatalogApi,
|
||||
badgeBuilder: BadgeBuilder,
|
||||
tokenManager: TokenManager,
|
||||
config: Config,
|
||||
baseUrl: string,
|
||||
auth: AuthService,
|
||||
) {
|
||||
router.get('/entity/:namespace/:kind/:name/badge-specs', async (req, res) => {
|
||||
const token = await tokenManager.getToken();
|
||||
const { token } = await auth.getPluginRequestToken({
|
||||
onBehalfOf: await auth.getOwnServiceCredentials(),
|
||||
targetPluginId: 'catalog',
|
||||
});
|
||||
|
||||
const { namespace, kind, name } = req.params;
|
||||
const entity = await catalog.getEntityByRef(
|
||||
{ namespace, kind, name },
|
||||
token,
|
||||
{ token },
|
||||
);
|
||||
if (!entity) {
|
||||
throw new NotFoundError(
|
||||
@@ -306,11 +314,16 @@ async function nonObfuscatedRoute(
|
||||
'/entity/:namespace/:kind/:name/badge/:badgeId',
|
||||
async (req, res) => {
|
||||
const { namespace, kind, name, badgeId } = req.params;
|
||||
const token = await tokenManager.getToken();
|
||||
const { token } = await auth.getPluginRequestToken({
|
||||
onBehalfOf: await auth.getOwnServiceCredentials(),
|
||||
targetPluginId: 'catalog',
|
||||
});
|
||||
|
||||
const entity = await catalog.getEntityByRef(
|
||||
{ namespace, kind, name },
|
||||
token,
|
||||
{ token },
|
||||
);
|
||||
|
||||
if (!entity) {
|
||||
throw new NotFoundError(
|
||||
`No ${kind} entity in ${namespace} named "${name}"`,
|
||||
|
||||
Reference in New Issue
Block a user