cli: Add validation for github credentials

Signed-off-by: Marcus Eide <eide@spotify.com>
This commit is contained in:
Marcus Eide
2023-02-10 14:08:43 +01:00
committed by Philipp Hugenroth
parent 250fb2af40
commit d844a31fc4
4 changed files with 66 additions and 63 deletions
+1
View File
@@ -39,6 +39,7 @@
"@backstage/types": "workspace:^",
"@esbuild-kit/cjs-loader": "^2.4.1",
"@manypkg/get-packages": "^1.1.3",
"@octokit/oauth-app": "^4.2.0",
"@octokit/request": "^6.0.0",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.7",
"@rollup/plugin-commonjs": "^23.0.0",
+1 -4
View File
@@ -30,9 +30,7 @@ export async function command(): Promise<void> {
{
type: 'confirm',
name: 'shouldSetupAuth',
message: chalk.blue(
'Do you want to set up Authentication for this project?',
),
message: 'Do you want to set up Authentication for this project?',
},
{
type: 'confirm',
@@ -51,7 +49,6 @@ export async function command(): Promise<void> {
]);
if (!answers.shouldSetupAuth) {
// TODO(eide): Can we add a Task.warning() method?
console.log(
chalk.yellow(
'If you change your mind, feel free to re-run this command.',
+56 -27
View File
@@ -14,6 +14,7 @@
* limitations under the License.
*/
import { OAuthApp } from '@octokit/oauth-app';
import chalk from 'chalk';
import inquirer from 'inquirer';
import { Task } from '../../lib/tasks';
@@ -22,14 +23,41 @@ export type GithubAuthConfig = {
auth: {
providers: {
github: {
clientId: string;
clientSecret: string;
enterpriseInstanceUrl?: string;
development: {
clientId: string;
clientSecret: string;
enterpriseInstanceUrl?: string;
};
};
};
};
};
const validateCredentials = async (clientId: string, clientSecret: string) => {
try {
const app = new OAuthApp({
clientId,
clientSecret,
});
await app.createToken({
code: '%NOT-VALID-CODE%',
});
} catch (error) {
// @octokit/request returns a error.response object when a request is rejected.
// We can check it to see what kind of error we received.
// If error.response is successful we can double-check that the error itself was due to the bad code.
// If that's the case then we can assume that the client id and secret exists as we otherwise would
// have gotten a 400/404.
if (
error.response.status !== 200 &&
error.response.data.error !== 'bad_verification_code'
) {
throw new Error(`Validating Github Credentials failed.`);
}
}
};
export const github = async (
useEnvForSecrets?: boolean,
): Promise<GithubAuthConfig> => {
@@ -39,6 +67,11 @@ export const github = async (
)}
The Homepage URL should point to Backstage's frontend, while the Authorization callback URL will point to the auth backend.
Settings for local development:
${chalk.cyan(`
Homepage URL: http://localhost:3000
Authorization callback URL: http://localhost:7007/api/auth/github/handler/frame`)}
You can find the full documentation page here: ${chalk.blue(
'https://backstage.io/docs/auth/github/provider',
)}
@@ -52,21 +85,15 @@ export const github = async (
}>([
{
type: 'input',
name: 'clientSecret',
message: 'What is your Client Secret?',
// TODO(eide): Is there another way to validate?
// validate(input) {
// if (/([a-f0-9]{40})/g.test(input)) {
// return true;
// }
// throw Error('Please provide a valid client secret.');
// },
name: 'clientId',
message: 'What is your Client Id?',
validate: (input: string) => (input.length ? true : false),
},
{
type: 'input',
name: 'clientId',
message: 'What is your Client Id?',
name: 'clientSecret',
message: 'What is your Client Secret?',
validate: (input: string) => (input.length ? true : false),
},
{
type: 'confirm',
@@ -78,25 +105,27 @@ export const github = async (
name: 'enterpriseInstanceUrl',
message: 'What is your URL for Github Enterprise?',
when: ({ hasGithubEnterprise }) => hasGithubEnterprise,
validate(input: string) {
return Boolean(new URL(input));
},
validate: (input: string) => Boolean(new URL(input)),
},
]);
await validateCredentials(answers.clientId, answers.clientSecret);
return {
auth: {
providers: {
github: {
clientId: useEnvForSecrets
? '${AUTH_GITHUB_CLIENT_ID}'
: answers.clientId,
clientSecret: useEnvForSecrets
? '${AUTH_GITHUB_CLIENT_SECRET}'
: answers.clientSecret,
...(answers.hasGithubEnterprise && {
enterpriseInstanceUrl: answers.enterpriseInstanceUrl,
}),
development: {
clientId: useEnvForSecrets
? '${AUTH_GITHUB_CLIENT_ID}'
: answers.clientId,
clientSecret: useEnvForSecrets
? '${AUTH_GITHUB_CLIENT_SECRET}'
: answers.clientSecret,
...(answers.hasGithubEnterprise && {
enterpriseInstanceUrl: answers.enterpriseInstanceUrl,
}),
},
},
},
},
+8 -32
View File
@@ -3678,6 +3678,7 @@ __metadata:
"@backstage/types": "workspace:^"
"@esbuild-kit/cjs-loader": ^2.4.1
"@manypkg/get-packages": ^1.1.3
"@octokit/oauth-app": ^4.2.0
"@octokit/request": ^6.0.0
"@pmmmwh/react-refresh-webpack-plugin": ^0.5.7
"@rollup/plugin-commonjs": ^23.0.0
@@ -12534,9 +12535,9 @@ __metadata:
languageName: node
linkType: hard
"@octokit/oauth-app@npm:^4.0.4, @octokit/oauth-app@npm:^4.0.6":
version: 4.0.6
resolution: "@octokit/oauth-app@npm:4.0.6"
"@octokit/oauth-app@npm:^4.0.4, @octokit/oauth-app@npm:^4.0.6, @octokit/oauth-app@npm:^4.2.0":
version: 4.2.0
resolution: "@octokit/oauth-app@npm:4.2.0"
dependencies:
"@octokit/auth-oauth-app": ^5.0.0
"@octokit/auth-oauth-user": ^2.0.0
@@ -12545,13 +12546,9 @@ __metadata:
"@octokit/oauth-authorization-url": ^5.0.0
"@octokit/oauth-methods": ^2.0.0
"@types/aws-lambda": ^8.10.83
aws-lambda: ^1.0.7
fromentries: ^1.3.1
universal-user-agent: ^6.0.0
dependenciesMeta:
aws-lambda:
optional: true
checksum: 0d7ceadda4668748a436f52f6c4ae3160a4a5c81a92592c0a6cfc75b0a065ed480880d8861efcabc6ca41b3ccf753d1c1044782a6c8d5fb481d6e8a0acf6d32e
checksum: 6cf5638d27e589daa577653177f2b135c0c346c8f74cc420d9fd0dc0f559a84040073eee147bd555a55bb5756bd0940e6dc4c3a6b3a508a818e3d5bee3837095
languageName: node
linkType: hard
@@ -17536,20 +17533,6 @@ __metadata:
languageName: node
linkType: hard
"aws-lambda@npm:^1.0.7":
version: 1.0.7
resolution: "aws-lambda@npm:1.0.7"
dependencies:
aws-sdk: ^2.814.0
commander: ^3.0.2
js-yaml: ^3.14.1
watchpack: ^2.0.0-beta.10
bin:
lambda: bin/lambda
checksum: 11316e87b5c4fc36e6bd0495742a3c0ed13befc9527a7b251a58180d141d9afd68b684f37aeb3b53d117d3c2f96747eace31826b683543f1edddc03f392865fd
languageName: node
linkType: hard
"aws-os-connection@npm:^0.2.0":
version: 0.2.0
resolution: "aws-os-connection@npm:0.2.0"
@@ -17596,7 +17579,7 @@ __metadata:
languageName: node
linkType: hard
"aws-sdk@npm:^2.1231.0, aws-sdk@npm:^2.814.0, aws-sdk@npm:^2.840.0, aws-sdk@npm:^2.948.0":
"aws-sdk@npm:^2.1231.0, aws-sdk@npm:^2.840.0, aws-sdk@npm:^2.948.0":
version: 2.1279.0
resolution: "aws-sdk@npm:2.1279.0"
dependencies:
@@ -19475,13 +19458,6 @@ __metadata:
languageName: node
linkType: hard
"commander@npm:^3.0.2":
version: 3.0.2
resolution: "commander@npm:3.0.2"
checksum: 6d14ad030d1904428139487ed31febcb04c1604db2b8d9fae711f60ee6718828dc0e11602249e91c8a97b0e721e9c6d53edbc166bad3cde1596851d59a8f824d
languageName: node
linkType: hard
"commander@npm:^4.0.0":
version: 4.1.1
resolution: "commander@npm:4.1.1"
@@ -27320,7 +27296,7 @@ __metadata:
languageName: node
linkType: hard
"js-yaml@npm:^3.10.0, js-yaml@npm:^3.13.0, js-yaml@npm:^3.13.1, js-yaml@npm:^3.14.1, js-yaml@npm:^3.6.1, js-yaml@npm:^3.8.3":
"js-yaml@npm:^3.10.0, js-yaml@npm:^3.13.0, js-yaml@npm:^3.13.1, js-yaml@npm:^3.6.1, js-yaml@npm:^3.8.3":
version: 3.14.1
resolution: "js-yaml@npm:3.14.1"
dependencies:
@@ -38736,7 +38712,7 @@ __metadata:
languageName: node
linkType: hard
"watchpack@npm:^2.0.0-beta.10, watchpack@npm:^2.4.0":
"watchpack@npm:^2.4.0":
version: 2.4.0
resolution: "watchpack@npm:2.4.0"
dependencies: