Merge pull request #7943 from backstage/natasha/b2b-auth
Support backend to backend authentication
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
import {
|
||||
PluginEndpointDiscovery,
|
||||
getVoidLogger,
|
||||
TokenManager,
|
||||
} from '@backstage/backend-common';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { DefaultTechDocsCollator } from './DefaultTechDocsCollator';
|
||||
@@ -87,6 +88,7 @@ const expectedEntities: Entity[] = [
|
||||
|
||||
describe('DefaultTechDocsCollator with legacyPathCasing configuration', () => {
|
||||
let mockDiscoveryApi: jest.Mocked<PluginEndpointDiscovery>;
|
||||
let mockTokenManager: jest.Mocked<TokenManager>;
|
||||
let collator: DefaultTechDocsCollator;
|
||||
|
||||
const worker = setupServer();
|
||||
@@ -96,6 +98,10 @@ describe('DefaultTechDocsCollator with legacyPathCasing configuration', () => {
|
||||
getBaseUrl: jest.fn().mockResolvedValue('http://test-backend'),
|
||||
getExternalBaseUrl: jest.fn(),
|
||||
};
|
||||
mockTokenManager = {
|
||||
getToken: jest.fn().mockResolvedValue({ token: '' }),
|
||||
authenticate: jest.fn(),
|
||||
};
|
||||
const mockConfig = new ConfigReader({
|
||||
techdocs: {
|
||||
legacyUseCaseSensitiveTripletPaths: true,
|
||||
@@ -103,6 +109,7 @@ describe('DefaultTechDocsCollator with legacyPathCasing configuration', () => {
|
||||
});
|
||||
collator = DefaultTechDocsCollator.fromConfig(mockConfig, {
|
||||
discovery: mockDiscoveryApi,
|
||||
tokenManager: mockTokenManager,
|
||||
logger,
|
||||
legacyPathCasing: true,
|
||||
});
|
||||
@@ -147,6 +154,7 @@ describe('DefaultTechDocsCollator with legacyPathCasing configuration', () => {
|
||||
|
||||
describe('DefaultTechDocsCollator', () => {
|
||||
let mockDiscoveryApi: jest.Mocked<PluginEndpointDiscovery>;
|
||||
let mockTokenManager: jest.Mocked<TokenManager>;
|
||||
let collator: DefaultTechDocsCollator;
|
||||
|
||||
const worker = setupServer();
|
||||
@@ -156,8 +164,13 @@ describe('DefaultTechDocsCollator', () => {
|
||||
getBaseUrl: jest.fn().mockResolvedValue('http://test-backend'),
|
||||
getExternalBaseUrl: jest.fn(),
|
||||
};
|
||||
mockTokenManager = {
|
||||
getToken: jest.fn().mockResolvedValue({ token: '' }),
|
||||
authenticate: jest.fn(),
|
||||
};
|
||||
collator = DefaultTechDocsCollator.fromConfig(new ConfigReader({}), {
|
||||
discovery: mockDiscoveryApi,
|
||||
tokenManager: mockTokenManager,
|
||||
logger,
|
||||
});
|
||||
|
||||
@@ -195,6 +208,7 @@ describe('DefaultTechDocsCollator', () => {
|
||||
// Provide an alternate location template.
|
||||
collator = new DefaultTechDocsCollator({
|
||||
discovery: mockDiscoveryApi,
|
||||
tokenManager: mockTokenManager,
|
||||
locationTemplate: '/software/:name',
|
||||
logger,
|
||||
});
|
||||
|
||||
@@ -14,7 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { PluginEndpointDiscovery } from '@backstage/backend-common';
|
||||
import {
|
||||
PluginEndpointDiscovery,
|
||||
TokenManager,
|
||||
} from '@backstage/backend-common';
|
||||
import { Entity, RELATION_OWNED_BY } from '@backstage/catalog-model';
|
||||
import { DocumentCollator } from '@backstage/search-common';
|
||||
import fetch from 'node-fetch';
|
||||
@@ -34,6 +37,7 @@ interface MkSearchIndexDoc {
|
||||
export type TechDocsCollatorOptions = {
|
||||
discovery: PluginEndpointDiscovery;
|
||||
logger: Logger;
|
||||
tokenManager: TokenManager;
|
||||
locationTemplate?: string;
|
||||
catalogClient?: CatalogApi;
|
||||
parallelismLimit?: number;
|
||||
@@ -51,6 +55,7 @@ export class DefaultTechDocsCollator implements DocumentCollator {
|
||||
protected locationTemplate: string;
|
||||
private readonly logger: Logger;
|
||||
private readonly catalogClient: CatalogApi;
|
||||
private readonly tokenManager: TokenManager;
|
||||
private readonly parallelismLimit: number;
|
||||
private readonly legacyPathCasing: boolean;
|
||||
public readonly type: string = 'techdocs';
|
||||
@@ -63,6 +68,7 @@ export class DefaultTechDocsCollator implements DocumentCollator {
|
||||
locationTemplate,
|
||||
logger,
|
||||
catalogClient,
|
||||
tokenManager,
|
||||
parallelismLimit = 10,
|
||||
legacyPathCasing = false,
|
||||
}: TechDocsCollatorOptions) {
|
||||
@@ -74,6 +80,7 @@ export class DefaultTechDocsCollator implements DocumentCollator {
|
||||
catalogClient || new CatalogClient({ discoveryApi: discovery });
|
||||
this.parallelismLimit = parallelismLimit;
|
||||
this.legacyPathCasing = legacyPathCasing;
|
||||
this.tokenManager = tokenManager;
|
||||
}
|
||||
|
||||
static fromConfig(config: Config, options: TechDocsCollatorOptions) {
|
||||
@@ -87,19 +94,23 @@ export class DefaultTechDocsCollator implements DocumentCollator {
|
||||
async execute() {
|
||||
const limit = pLimit(this.parallelismLimit);
|
||||
const techDocsBaseUrl = await this.discovery.getBaseUrl('techdocs');
|
||||
const entities = await this.catalogClient.getEntities({
|
||||
fields: [
|
||||
'kind',
|
||||
'namespace',
|
||||
'metadata.annotations',
|
||||
'metadata.name',
|
||||
'metadata.title',
|
||||
'metadata.namespace',
|
||||
'spec.type',
|
||||
'spec.lifecycle',
|
||||
'relations',
|
||||
],
|
||||
});
|
||||
const { token } = await this.tokenManager.getToken();
|
||||
const entities = await this.catalogClient.getEntities(
|
||||
{
|
||||
fields: [
|
||||
'kind',
|
||||
'namespace',
|
||||
'metadata.annotations',
|
||||
'metadata.name',
|
||||
'metadata.title',
|
||||
'metadata.namespace',
|
||||
'spec.type',
|
||||
'spec.lifecycle',
|
||||
'relations',
|
||||
],
|
||||
},
|
||||
{ token },
|
||||
);
|
||||
const docPromises = entities.items
|
||||
.filter(it => it.metadata?.annotations?.['backstage.io/techdocs-ref'])
|
||||
.map((entity: Entity) =>
|
||||
|
||||
Reference in New Issue
Block a user