cli: Add user entity to local catalog in auth flow
Signed-off-by: Marcus Eide <eide@spotify.com>
This commit is contained in:
committed by
Philipp Hugenroth
parent
2f851a3945
commit
5663de4a37
@@ -29,6 +29,13 @@ type GithubAuthConfig = {
|
||||
};
|
||||
};
|
||||
};
|
||||
catalog?: {
|
||||
locations: Array<{
|
||||
type: string;
|
||||
target: string;
|
||||
rules: Array<{ allow: Array<string> }>;
|
||||
}>;
|
||||
};
|
||||
};
|
||||
|
||||
const readYaml = async (file: string) => {
|
||||
@@ -67,3 +74,27 @@ AUTH_GITHUB_CLIENT_SECRET=${clientSecret}`;
|
||||
|
||||
return await fs.writeFile(file, content, 'utf8');
|
||||
};
|
||||
|
||||
export const addUserEntity = async (file: string, username: string) => {
|
||||
const content = {
|
||||
apiVersion: 'backstage.io/v1alpha1',
|
||||
kind: 'User',
|
||||
metadata: {
|
||||
name: username,
|
||||
annotations: {
|
||||
'github.com/user-login': username,
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
memberOf: [],
|
||||
},
|
||||
};
|
||||
|
||||
return await fs.writeFile(
|
||||
file,
|
||||
yaml.stringify(content, {
|
||||
indent: 2,
|
||||
}),
|
||||
'utf8',
|
||||
);
|
||||
};
|
||||
|
||||
@@ -21,6 +21,8 @@ import * as path from 'path';
|
||||
const { targetRoot, resolveTargetRoot } = findPaths(__dirname);
|
||||
export const APP_CONFIG_FILE = path.join(targetRoot, 'app-config.local.yaml');
|
||||
export const ENV_CONFIG_FILE = path.join(targetRoot, '.env.local');
|
||||
export const USER_ENTITY_FILE = path.join(targetRoot, 'user-info.yaml');
|
||||
|
||||
export const APP_TSX_FILE = path.join(
|
||||
resolveTargetRoot('packages/app'),
|
||||
'src',
|
||||
|
||||
@@ -17,13 +17,15 @@
|
||||
import { OAuthApp } from '@octokit/oauth-app';
|
||||
import chalk from 'chalk';
|
||||
import inquirer from 'inquirer';
|
||||
import fetch from 'node-fetch';
|
||||
import { Task } from '../../../../lib/tasks';
|
||||
import { updateConfigFile, updateEnvFile } from '../config';
|
||||
import { addUserEntity, updateConfigFile, updateEnvFile } from '../config';
|
||||
import {
|
||||
APP_CONFIG_FILE,
|
||||
APP_TSX_FILE,
|
||||
AUTH_BACKEND_PLUGIN_FILE,
|
||||
ENV_CONFIG_FILE,
|
||||
USER_ENTITY_FILE,
|
||||
} from '../files';
|
||||
import { patch } from '../patch';
|
||||
import { addSignInPageDiff, replaceSignInResolverDiff } from './diffs';
|
||||
@@ -53,6 +55,46 @@ const validateCredentials = async (clientId: string, clientSecret: string) => {
|
||||
}
|
||||
};
|
||||
|
||||
const getConfig = (answers: Answers, useEnvForSecrets: boolean) => {
|
||||
const { clientId, clientSecret, hasEnterprise, enterpriseInstanceUrl } =
|
||||
answers;
|
||||
|
||||
return {
|
||||
auth: {
|
||||
providers: {
|
||||
github: {
|
||||
development: {
|
||||
clientId: useEnvForSecrets ? '${AUTH_GITHUB_CLIENT_ID}' : clientId,
|
||||
clientSecret: useEnvForSecrets
|
||||
? '${AUTH_GITHUB_CLIENT_SECRET}'
|
||||
: clientSecret,
|
||||
...(hasEnterprise && {
|
||||
enterpriseInstanceUrl: enterpriseInstanceUrl,
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
catalog: {
|
||||
locations: [
|
||||
{
|
||||
type: 'file',
|
||||
target: '../../user-info.yaml',
|
||||
rules: [{ allow: ['User'] }],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
type Answers = {
|
||||
username: string;
|
||||
clientSecret: string;
|
||||
clientId: string;
|
||||
hasEnterprise: boolean;
|
||||
enterpriseInstanceUrl?: string;
|
||||
};
|
||||
|
||||
export const oauth = async (useEnvForSecrets: boolean) => {
|
||||
Task.log(`
|
||||
To add GitHub authentication, you must create an OAuth App from the GitHub developer settings: ${chalk.blue(
|
||||
@@ -69,12 +111,19 @@ export const oauth = async (useEnvForSecrets: boolean) => {
|
||||
'https://backstage.io/docs/auth/github/provider',
|
||||
)}`);
|
||||
|
||||
const answers = await inquirer.prompt<{
|
||||
clientSecret: string;
|
||||
clientId: string;
|
||||
hasEnterprise: boolean;
|
||||
enterpriseInstanceUrl?: string;
|
||||
}>([
|
||||
const answers = await inquirer.prompt<Answers>([
|
||||
{
|
||||
type: 'input',
|
||||
name: 'username',
|
||||
message: 'What is your Github username?',
|
||||
validate: async (input: string) => {
|
||||
const response = await fetch(`https://api.github.com/users/${input}`);
|
||||
if (!response.ok) {
|
||||
return chalk.red('Unknown user. Please try again.');
|
||||
}
|
||||
return true;
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
name: 'clientId',
|
||||
@@ -101,32 +150,19 @@ export const oauth = async (useEnvForSecrets: boolean) => {
|
||||
},
|
||||
]);
|
||||
|
||||
const { clientId, clientSecret, hasEnterprise, enterpriseInstanceUrl } =
|
||||
answers;
|
||||
const { username, clientId, clientSecret } = answers;
|
||||
|
||||
await validateCredentials(clientId, clientSecret);
|
||||
|
||||
const auth = {
|
||||
providers: {
|
||||
github: {
|
||||
development: {
|
||||
clientId: useEnvForSecrets ? '${AUTH_GITHUB_CLIENT_ID}' : clientId,
|
||||
clientSecret: useEnvForSecrets
|
||||
? '${AUTH_GITHUB_CLIENT_SECRET}'
|
||||
: clientSecret,
|
||||
...(hasEnterprise && {
|
||||
enterpriseInstanceUrl: enterpriseInstanceUrl,
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const config = getConfig(answers, useEnvForSecrets);
|
||||
await updateConfigFile(APP_CONFIG_FILE, config);
|
||||
|
||||
await updateConfigFile(APP_CONFIG_FILE, { auth });
|
||||
if (useEnvForSecrets) {
|
||||
await updateEnvFile(ENV_CONFIG_FILE, clientId, clientSecret);
|
||||
}
|
||||
|
||||
await addUserEntity(USER_ENTITY_FILE, username);
|
||||
|
||||
await patch(APP_TSX_FILE, addSignInPageDiff);
|
||||
await patch(AUTH_BACKEND_PLUGIN_FILE, replaceSignInResolverDiff);
|
||||
};
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import chalk from 'chalk';
|
||||
import inquirer from 'inquirer';
|
||||
import { Task } from '../../../lib/tasks';
|
||||
import { github } from './github';
|
||||
@@ -42,4 +43,5 @@ export async function auth(): Promise<void> {
|
||||
}
|
||||
|
||||
Task.log(`Done setting up ${provider}!`);
|
||||
Task.log(`You can now start you app with ${chalk.inverse('yarn dev')}`);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user