remove factory signature from gh creds provider
This change required the SingleInstanceGithubCredentialsProvider to be changed to allow it to look up the credentials from the whole list of integrations. As such all places where it was used I have updated. Signed-off-by: Brian Fletcher <brian@roadie.io>
This commit is contained in:
@@ -14,6 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ScmIntegrations } from '../ScmIntegrations';
|
||||
|
||||
const octokit = {
|
||||
paginate: async (fn: any) => (await fn()).data,
|
||||
apps: {
|
||||
@@ -34,22 +36,33 @@ jest.doMock('@octokit/rest', () => {
|
||||
import { SingleInstanceGithubCredentialsProvider } from './SingleInstanceGithubCredentialsProvider';
|
||||
import { RestEndpointMethodTypes } from '@octokit/rest';
|
||||
import { DateTime } from 'luxon';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
|
||||
const github = SingleInstanceGithubCredentialsProvider.create({
|
||||
host: 'github.com',
|
||||
apps: [
|
||||
{
|
||||
appId: 1,
|
||||
privateKey: 'privateKey',
|
||||
webhookSecret: '123',
|
||||
clientId: 'CLIENT_ID',
|
||||
clientSecret: 'CLIENT_SECRET',
|
||||
let integrations = ScmIntegrations.fromConfig(
|
||||
new ConfigReader({
|
||||
integrations: {
|
||||
github: [
|
||||
{
|
||||
host: 'github.com',
|
||||
apps: [
|
||||
{
|
||||
appId: 1,
|
||||
privateKey: 'privateKey',
|
||||
webhookSecret: '123',
|
||||
clientId: 'CLIENT_ID',
|
||||
clientSecret: 'CLIENT_SECRET',
|
||||
},
|
||||
],
|
||||
token: 'hardcoded_token',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
token: 'hardcoded_token',
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
describe('DefaultGithubCredentialsProvider tests', () => {
|
||||
const github = SingleInstanceGithubCredentialsProvider.create(integrations);
|
||||
|
||||
describe('SingleInstanceGithubCredentialsProvider tests', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
@@ -204,11 +217,22 @@ describe('DefaultGithubCredentialsProvider tests', () => {
|
||||
});
|
||||
|
||||
it('should return the default token if no app is configured', async () => {
|
||||
const githubProvider = SingleInstanceGithubCredentialsProvider.create({
|
||||
host: 'github.com',
|
||||
apps: [],
|
||||
token: 'fallback_token',
|
||||
});
|
||||
integrations = ScmIntegrations.fromConfig(
|
||||
new ConfigReader({
|
||||
integrations: {
|
||||
github: [
|
||||
{
|
||||
host: 'github.com',
|
||||
apps: [],
|
||||
token: 'fallback_token',
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
const githubProvider =
|
||||
SingleInstanceGithubCredentialsProvider.create(integrations);
|
||||
|
||||
await expect(
|
||||
githubProvider.getCredentials({
|
||||
@@ -218,19 +242,29 @@ describe('DefaultGithubCredentialsProvider tests', () => {
|
||||
});
|
||||
|
||||
it('should return the configured token if there are no installations', async () => {
|
||||
const githubProvider = SingleInstanceGithubCredentialsProvider.create({
|
||||
host: 'github.com',
|
||||
apps: [
|
||||
{
|
||||
appId: 1,
|
||||
privateKey: 'privateKey',
|
||||
webhookSecret: '123',
|
||||
clientId: 'CLIENT_ID',
|
||||
clientSecret: 'CLIENT_SECRET',
|
||||
integrations = ScmIntegrations.fromConfig(
|
||||
new ConfigReader({
|
||||
integrations: {
|
||||
github: [
|
||||
{
|
||||
host: 'github.com',
|
||||
apps: [
|
||||
{
|
||||
appId: 1,
|
||||
privateKey: 'privateKey',
|
||||
webhookSecret: '123',
|
||||
clientId: 'CLIENT_ID',
|
||||
clientSecret: 'CLIENT_SECRET',
|
||||
},
|
||||
],
|
||||
token: 'hardcoded_token',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
token: 'hardcoded_token',
|
||||
});
|
||||
}),
|
||||
);
|
||||
const githubProvider =
|
||||
SingleInstanceGithubCredentialsProvider.create(integrations);
|
||||
octokit.apps.listInstallations.mockResolvedValue({
|
||||
data: [],
|
||||
} as unknown as RestEndpointMethodTypes['apps']['listInstallations']['response']);
|
||||
@@ -243,9 +277,19 @@ describe('DefaultGithubCredentialsProvider tests', () => {
|
||||
});
|
||||
|
||||
it('should return undefined if no token or apps are configured', async () => {
|
||||
const githubProvider = SingleInstanceGithubCredentialsProvider.create({
|
||||
host: 'github.com',
|
||||
});
|
||||
integrations = ScmIntegrations.fromConfig(
|
||||
new ConfigReader({
|
||||
integrations: {
|
||||
github: [
|
||||
{
|
||||
host: 'github.com',
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
);
|
||||
const githubProvider =
|
||||
SingleInstanceGithubCredentialsProvider.create(integrations);
|
||||
|
||||
await expect(
|
||||
githubProvider.getCredentials({
|
||||
|
||||
@@ -22,9 +22,9 @@ import { DateTime } from 'luxon';
|
||||
import {
|
||||
GithubCredentials,
|
||||
GithubCredentialsProvider,
|
||||
GithubCredentialsProviderFactory,
|
||||
GithubCredentialType,
|
||||
} from './types';
|
||||
import { ScmIntegrations } from '../ScmIntegrations';
|
||||
|
||||
type InstallationData = {
|
||||
installationId: number;
|
||||
@@ -232,17 +232,11 @@ export class GithubAppCredentialsMux {
|
||||
export class SingleInstanceGithubCredentialsProvider
|
||||
implements GithubCredentialsProvider
|
||||
{
|
||||
static create: GithubCredentialsProviderFactory = config => {
|
||||
return new SingleInstanceGithubCredentialsProvider(
|
||||
new GithubAppCredentialsMux(config),
|
||||
config.token,
|
||||
);
|
||||
};
|
||||
static create(integrations: ScmIntegrations) {
|
||||
return new SingleInstanceGithubCredentialsProvider(integrations);
|
||||
}
|
||||
|
||||
private constructor(
|
||||
private readonly githubAppCredentialsMux: GithubAppCredentialsMux,
|
||||
private readonly token?: string,
|
||||
) {}
|
||||
private constructor(private readonly integrations: ScmIntegrations) {}
|
||||
|
||||
/**
|
||||
* Returns {@link GithubCredentials} for a given URL.
|
||||
@@ -266,15 +260,24 @@ export class SingleInstanceGithubCredentialsProvider
|
||||
*/
|
||||
async getCredentials(opts: { url: string }): Promise<GithubCredentials> {
|
||||
const parsed = parseGitUrl(opts.url);
|
||||
const gitHubConfig = this.integrations.github.byUrl(opts.url)?.config;
|
||||
if (!gitHubConfig) {
|
||||
throw new Error(
|
||||
`There is no GitHub integration that matches ${opts.url}. Please add a configuration for an integration.`,
|
||||
);
|
||||
}
|
||||
|
||||
const githubAppCredentialsMux = new GithubAppCredentialsMux(gitHubConfig);
|
||||
const defaultToken = gitHubConfig.token;
|
||||
|
||||
const owner = parsed.owner || parsed.name;
|
||||
const repo = parsed.owner ? parsed.name : undefined;
|
||||
|
||||
let type: GithubCredentialType = 'app';
|
||||
let token = await this.githubAppCredentialsMux.getAppToken(owner, repo);
|
||||
let token = await githubAppCredentialsMux.getAppToken(owner, repo);
|
||||
if (!token) {
|
||||
type = 'token';
|
||||
token = this.token;
|
||||
token = defaultToken;
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -27,7 +27,6 @@ export {
|
||||
export type {
|
||||
GithubCredentials,
|
||||
GithubCredentialsProvider,
|
||||
GithubCredentialsProviderFactory,
|
||||
GithubCredentialType,
|
||||
} from './types';
|
||||
export { GitHubIntegration, replaceGitHubUrlType } from './GitHubIntegration';
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { GitHubIntegrationConfig } from './config';
|
||||
|
||||
/**
|
||||
* The type of credentials produced by the credential provider.
|
||||
*
|
||||
@@ -43,13 +41,3 @@ export type GithubCredentials = {
|
||||
export interface GithubCredentialsProvider {
|
||||
getCredentials(opts: { url: string }): Promise<GithubCredentials>;
|
||||
}
|
||||
|
||||
/**
|
||||
* This allows implementations to be provided to create credentials providers.
|
||||
*
|
||||
* @public
|
||||
*
|
||||
*/
|
||||
export type GithubCredentialsProviderFactory = (
|
||||
config: GitHubIntegrationConfig,
|
||||
) => GithubCredentialsProvider;
|
||||
|
||||
Reference in New Issue
Block a user