mirror of
https://github.com/balena-io/balena-cli.git
synced 2025-01-18 02:39:49 +00:00
Add support for authentication checking to oclif
Change-type: patch Signed-off-by: Scott Lowe <scott@balena.io>
This commit is contained in:
parent
6ec8bcddaa
commit
8658104647
3
lib/actions-oclif/env/add.ts
vendored
3
lib/actions-oclif/env/add.ts
vendored
@ -105,7 +105,6 @@ export default class EnvAddCmd extends Command {
|
||||
EnvAddCmd,
|
||||
);
|
||||
const cmd = this;
|
||||
const { checkLoggedIn } = await import('../../utils/patterns');
|
||||
|
||||
if (!options.application && !options.device) {
|
||||
throw new ExpectedError(
|
||||
@ -113,7 +112,7 @@ export default class EnvAddCmd extends Command {
|
||||
);
|
||||
}
|
||||
|
||||
await checkLoggedIn();
|
||||
await Command.checkLoggedIn();
|
||||
|
||||
if (params.value == null) {
|
||||
params.value = process.env[params.name];
|
||||
|
3
lib/actions-oclif/env/rename.ts
vendored
3
lib/actions-oclif/env/rename.ts
vendored
@ -85,9 +85,8 @@ export default class EnvRenameCmd extends Command {
|
||||
const { args: params, flags: opt } = this.parse<FlagsDef, ArgsDef>(
|
||||
EnvRenameCmd,
|
||||
);
|
||||
const { checkLoggedIn } = await import('../../utils/patterns');
|
||||
|
||||
await checkLoggedIn();
|
||||
await Command.checkLoggedIn();
|
||||
|
||||
await getBalenaSdk().pine.patch({
|
||||
resource: ec.getVarResourceName(opt.config, opt.device, opt.service),
|
||||
|
4
lib/actions-oclif/env/rm.ts
vendored
4
lib/actions-oclif/env/rm.ts
vendored
@ -88,9 +88,9 @@ export default class EnvRmCmd extends Command {
|
||||
EnvRmCmd,
|
||||
);
|
||||
const balena = getBalenaSdk();
|
||||
const { checkLoggedIn, confirm } = await import('../../utils/patterns');
|
||||
const { confirm } = await import('../../utils/patterns');
|
||||
|
||||
await checkLoggedIn();
|
||||
await Command.checkLoggedIn();
|
||||
|
||||
await confirm(
|
||||
opt.yes || false,
|
||||
|
@ -133,10 +133,9 @@ export default class EnvsCmd extends Command {
|
||||
|
||||
public async run() {
|
||||
const { flags: options } = this.parse<FlagsDef, {}>(EnvsCmd);
|
||||
const { checkLoggedIn } = await import('../utils/patterns');
|
||||
const variables: EnvironmentVariableInfo[] = [];
|
||||
|
||||
await checkLoggedIn();
|
||||
await Command.checkLoggedIn();
|
||||
|
||||
if (!options.application && !options.device) {
|
||||
throw new ExpectedError('You must specify an application or device');
|
||||
|
@ -308,8 +308,8 @@ async function validateOptions(options: FlagsDef) {
|
||||
-------------------------------------------------------------------------------------------
|
||||
`);
|
||||
}
|
||||
const { checkLoggedIn } = await import('../../utils/patterns');
|
||||
await checkLoggedIn();
|
||||
|
||||
await Command.checkLoggedIn();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import Command from '@oclif/command';
|
||||
import { ExpectedError } from './errors';
|
||||
import { InsufficientPrivilegesError } from './errors';
|
||||
|
||||
export default abstract class BalenaCommand extends Command {
|
||||
/**
|
||||
@ -33,19 +33,59 @@ export default abstract class BalenaCommand extends Command {
|
||||
*/
|
||||
public static root = false;
|
||||
|
||||
protected async checkElevatedPrivileges() {
|
||||
const root = (this.constructor as typeof BalenaCommand).root;
|
||||
if (root) {
|
||||
const isElevated = await (await import('is-elevated'))();
|
||||
if (!isElevated) {
|
||||
throw new ExpectedError(
|
||||
'You need admin privileges to run this command',
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Require authentication to run.
|
||||
* When set to true, command will exit with an error
|
||||
* if user is not already logged in.
|
||||
*/
|
||||
public static authenticated = false;
|
||||
|
||||
/**
|
||||
* Throw InsufficientPrivilegesError if not root on Mac/Linux
|
||||
* or non-Administrator on Windows.
|
||||
*
|
||||
* Called automatically if `root=true`.
|
||||
* Can be called explicitly by command implementation, if e.g.:
|
||||
* - check should only be done conditionally
|
||||
* - other code needs to execute before check
|
||||
*/
|
||||
protected static async checkElevatedPrivileges() {
|
||||
const isElevated = await (await import('is-elevated'))();
|
||||
if (!isElevated) {
|
||||
throw new InsufficientPrivilegesError(
|
||||
'You need root/admin privileges to run this command',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw NotLoggedInError if not logged in.
|
||||
*
|
||||
* Called automatically if `authenticated=true`.
|
||||
* Can be called explicitly by command implementation, if e.g.:
|
||||
* - check should only be done conditionally
|
||||
* - other code needs to execute before check
|
||||
*
|
||||
* Note, currently public to allow use outside of derived commands
|
||||
* (as some command implementations require this. Can be made protected
|
||||
* if this changes).
|
||||
*/
|
||||
public static async checkLoggedIn() {
|
||||
await (await import('./utils/patterns')).checkLoggedIn();
|
||||
}
|
||||
|
||||
protected async init() {
|
||||
await this.checkElevatedPrivileges();
|
||||
const requireElevatedPrivileges = (this.constructor as typeof BalenaCommand)
|
||||
.root;
|
||||
const requireAuthentication = (this.constructor as typeof BalenaCommand)
|
||||
.authenticated;
|
||||
|
||||
if (requireElevatedPrivileges) {
|
||||
await BalenaCommand.checkElevatedPrivileges();
|
||||
}
|
||||
|
||||
if (requireAuthentication) {
|
||||
await BalenaCommand.checkLoggedIn();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,8 @@ export class ExpectedError extends TypedError {}
|
||||
|
||||
export class NotLoggedInError extends ExpectedError {}
|
||||
|
||||
export class InsufficientPrivilegesError extends ExpectedError {}
|
||||
|
||||
function hasCode(error: any): error is Error & { code: string } {
|
||||
return error.code != null;
|
||||
}
|
||||
|
@ -74,6 +74,10 @@ export function authenticate(options: {}): Bluebird<void> {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if logged in, and throw `NotLoggedInError` if not.
|
||||
* Note: `NotLoggedInError` is an `ExpectedError`.
|
||||
*/
|
||||
export async function checkLoggedIn(): Promise<void> {
|
||||
const balena = getBalenaSdk();
|
||||
if (!(await balena.auth.isLoggedIn())) {
|
||||
@ -84,6 +88,10 @@ export async function checkLoggedIn(): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if logged in, and call `exitWithExpectedError()` if not.
|
||||
* DEPRECATED: Use checkLoggedIn() instead.
|
||||
*/
|
||||
export async function exitIfNotLoggedIn(): Promise<void> {
|
||||
try {
|
||||
await checkLoggedIn();
|
||||
|
Loading…
Reference in New Issue
Block a user