Merge pull request #7943 from backstage/natasha/b2b-auth

Support backend to backend authentication
This commit is contained in:
MT Lewis
2021-11-26 15:31:52 +00:00
committed by GitHub
29 changed files with 661 additions and 29 deletions
@@ -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) =>