This commit is contained in:
Erik Larsson
2021-01-22 23:44:26 +01:00
parent 05a6c4c394
commit b3e9b08fd7
11 changed files with 142 additions and 42 deletions
@@ -48,7 +48,10 @@ export class CatalogIdentityClient {
filter[`metadata.annotations.${key}`] = value;
}
const { items } = await this.catalogClient.getEntities(token, { filter });
const { items } = await this.catalogClient.getEntities(
{ filter },
{ token },
);
if (items.length !== 1) {
if (items.length > 1) {
@@ -14,6 +14,7 @@
* limitations under the License.
*/
import { getVoidLogger } from '@backstage/backend-common';
import { CatalogClient } from '@backstage/catalog-client';
import express from 'express';
import { JWT } from 'jose';
@@ -43,6 +44,9 @@ jest.mock('cross-fetch', () => ({
},
}));
jest.mock('@backstage/catalog-client');
const MockedCatalogClient = CatalogClient as jest.Mock<CatalogClient>;
const identityResolutionCallbackMock = async (): Promise<AuthResponse<any>> => {
return {
backstageIdentity: {
@@ -67,15 +71,7 @@ beforeEach(() => {
});
describe('AwsALBAuthProvider', () => {
const catalogApi = {
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
addLocation: jest.fn(),
getEntities: jest.fn(),
getLocationByEntity: jest.fn(),
getLocationById: jest.fn(),
removeEntityByUid: jest.fn(),
getEntityByName: jest.fn(),
};
const catalogClient = new MockedCatalogClient();
const mockResponseSend = jest.fn();
const mockRequest = ({
@@ -95,7 +91,7 @@ describe('AwsALBAuthProvider', () => {
describe('should transform to type OAuthResponse', () => {
it('when JWT is valid and identity is resolved successfully', async () => {
const provider = new AwsAlbAuthProvider(getVoidLogger(), catalogApi, {
const provider = new AwsAlbAuthProvider(getVoidLogger(), catalogClient, {
region: 'us-west-2',
identityResolutionCallback: identityResolutionCallbackMock,
issuer: 'foo',
@@ -121,7 +117,7 @@ describe('AwsALBAuthProvider', () => {
});
describe('should fail when', () => {
it('JWT is missing', async () => {
const provider = new AwsAlbAuthProvider(getVoidLogger(), catalogApi, {
const provider = new AwsAlbAuthProvider(getVoidLogger(), catalogClient, {
region: 'us-west-2',
identityResolutionCallback: identityResolutionCallbackMock,
issuer: 'foo',
@@ -133,7 +129,7 @@ describe('AwsALBAuthProvider', () => {
});
it('JWT is invalid', async () => {
const provider = new AwsAlbAuthProvider(getVoidLogger(), catalogApi, {
const provider = new AwsAlbAuthProvider(getVoidLogger(), catalogClient, {
region: 'us-west-2',
identityResolutionCallback: identityResolutionCallbackMock,
issuer: 'foo',
@@ -149,7 +145,7 @@ describe('AwsALBAuthProvider', () => {
});
it('issuer is invalid', async () => {
const provider = new AwsAlbAuthProvider(getVoidLogger(), catalogApi, {
const provider = new AwsAlbAuthProvider(getVoidLogger(), catalogClient, {
region: 'us-west-2',
identityResolutionCallback: identityResolutionCallbackMock,
issuer: 'foobar',
@@ -163,7 +159,7 @@ describe('AwsALBAuthProvider', () => {
});
it('identity resolution callback rejects', async () => {
const provider = new AwsAlbAuthProvider(getVoidLogger(), catalogApi, {
const provider = new AwsAlbAuthProvider(getVoidLogger(), catalogClient, {
region: 'us-west-2',
identityResolutionCallback: identityResolutionCallbackRejectedMock,
issuer: 'foo',
@@ -25,7 +25,7 @@ import { KeyObject } from 'crypto';
import { Logger } from 'winston';
import NodeCache from 'node-cache';
import { JWT } from 'jose';
import { CatalogApi } from '@backstage/catalog-client';
import { CatalogClient } from '@backstage/catalog-client';
const ALB_JWT_HEADER = 'x-amzn-oidc-data';
/**
@@ -44,13 +44,13 @@ export const getJWTHeaders = (input: string) => {
export class AwsAlbAuthProvider implements AuthProviderRouteHandlers {
private logger: Logger;
private readonly catalogClient: CatalogApi;
private readonly catalogClient: CatalogClient;
private options: AwsAlbAuthProviderOptions;
private readonly keyCache: NodeCache;
constructor(
logger: Logger,
catalogClient: CatalogApi,
catalogClient: CatalogClient,
options: AwsAlbAuthProviderOptions,
) {
this.logger = logger;
@@ -108,14 +108,14 @@ export class AwsAlbAuthProvider implements AuthProviderRouteHandlers {
export const createAwsAlbProvider = ({
logger,
catalogApi,
catalogClient,
config,
identityResolver,
}: AuthProviderFactoryOptions) => {
const region = config.getString('region');
const issuer = config.getOptionalString('iss');
if (identityResolver !== undefined) {
return new AwsAlbAuthProvider(logger, catalogApi, {
return new AwsAlbAuthProvider(logger, catalogClient, {
region,
issuer,
identityResolutionCallback: identityResolver,
+1 -1
View File
@@ -122,7 +122,7 @@ export type ExperimentalIdentityResolver = (
* An object containing information specific to the auth provider.
*/
payload: object,
catalogApi: CatalogApi,
catalogClient: CatalogClient,
) => Promise<AuthResponse<any>>;
export type AuthProviderFactoryOptions = {
@@ -45,10 +45,25 @@ jest.mock('@octokit/rest', () => ({
}));
describe('CatalogImportClient', () => {
const identityApi = {
getUserId: () => {
return 'user';
},
getProfile: () => {
return {};
},
getIdToken: () => {
return Promise.resolve('token');
},
signOut: () => {
return Promise.resolve();
},
};
describe('checkForExistingCatalogInfo', () => {
const cic = new CatalogImportClient({
discoveryApi: { getBaseUrl: () => Promise.resolve('base') },
githubAuthApi: { getAccessToken: (_, __) => Promise.resolve('token') },
identityApi,
configApi: {} as any,
});
it('should return the closest-to-root catalog-info from multiple responses', async () => {
@@ -35,6 +35,21 @@ describe('<RegisterComponentForm />', () => {
error$: jest.fn(),
};
const identityApi = {
getUserId: () => {
return 'user';
},
getProfile: () => {
return {};
},
getIdToken: () => {
return Promise.resolve('token');
},
signOut: () => {
return Promise.resolve();
},
};
beforeEach(() => {
apis = ApiRegistry.from([
[catalogApiRef, new CatalogClient({ discoveryApi: {} as DiscoveryApi })],
@@ -45,6 +60,7 @@ describe('<RegisterComponentForm />', () => {
githubAuthApi: {
getAccessToken: (_, __) => Promise.resolve('token'),
},
identityApi,
configApi: {} as any,
}),
],
@@ -70,6 +70,21 @@ describe('<ImportComponentPage />', () => {
const server = setupServer();
msw.setupDefaultHandlers(server);
const identityApi = {
getUserId: () => {
return 'user';
},
getProfile: () => {
return {};
},
getIdToken: () => {
return Promise.resolve('token');
},
signOut: () => {
return Promise.resolve();
},
};
beforeEach(() => {
server.use(
rest.post('https://backend.localhost/locations', (_, res, ctx) => {
@@ -112,6 +127,7 @@ describe('<ImportComponentPage />', () => {
githubAuthApi: {
getAccessToken: (_, __) => Promise.resolve('token'),
},
identityApi,
configApi: {} as any,
}),
],
+6 -6
View File
@@ -36,33 +36,33 @@ export class CatalogClientWrapper implements CatalogApi {
async getLocationById(id: String): Promise<Location | undefined> {
const token = await this.identityApi.getIdToken();
return await this.client.getLocationById(token, id);
return await this.client.getLocationById(id, { token });
}
async getEntities(
request?: CatalogEntitiesRequest,
): Promise<CatalogListResponse<Entity>> {
const token = await this.identityApi.getIdToken();
return await this.client.getEntities(token, request);
return await this.client.getEntities(request, { token });
}
async getEntityByName(compoundName: EntityName): Promise<Entity | undefined> {
const token = await this.identityApi.getIdToken();
return await this.client.getEntityByName(token, compoundName);
return await this.client.getEntityByName(compoundName, { token });
}
async addLocation(request: AddLocationRequest): Promise<AddLocationResponse> {
const token = await this.identityApi.getIdToken();
return await this.client.addLocation(token, request);
return await this.client.addLocation(request, { token });
}
async getLocationByEntity(entity: Entity): Promise<Location | undefined> {
const token = await this.identityApi.getIdToken();
return await this.client.getLocationByEntity(token, entity);
return await this.client.getLocationByEntity(entity, { token });
}
async removeEntityByUid(uid: string): Promise<void> {
const token = await this.identityApi.getIdToken();
return await this.client.removeEntityByUid(token, uid);
return await this.client.removeEntityByUid(uid, { token });
}
}
@@ -37,12 +37,15 @@ export class CatalogEntityClient {
token: string | undefined,
templateName: string,
): Promise<TemplateEntityV1alpha1> {
const { items: templates } = (await this.catalogClient.getEntities(token, {
filter: {
kind: 'template',
'metadata.name': templateName,
const { items: templates } = (await this.catalogClient.getEntities(
{
filter: {
kind: 'template',
'metadata.name': templateName,
},
},
})) as { items: TemplateEntityV1alpha1[] };
{ token },
)) as { items: TemplateEntityV1alpha1[] };
if (templates.length !== 1) {
if (templates.length > 1) {