UNPKG

@zowe/imperative

Version:
154 lines 8.42 kB
"use strict"; /* * This program and the accompanying materials are made available under the terms of the * Eclipse Public License v2.0 which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-v20.html * * SPDX-License-Identifier: EPL-2.0 * * Copyright Contributors to the Zowe Project. * */ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const config_1 = require("../../../../../config"); const ConfigAutoStore_1 = require("../../../../../config/src/ConfigAutoStore"); const ConfigUtils_1 = require("../../../../../config/src/ConfigUtils"); const error_1 = require("../../../../../error"); const logger_1 = require("../../../../../logger"); const rest_1 = require("../../../../../rest"); const utilities_1 = require("../../../../../utilities"); class SecureHandler { /** * Process the command and input. * * @param {IHandlerParameters} params Parameters supplied by yargs * * @throws {ImperativeError} */ process(params) { return __awaiter(this, void 0, void 0, function* () { this.params = params; const config = utilities_1.ImperativeConfig.instance.config; // Setup the credential vault API for the config if (config.api.secure.loadFailed) { throw ConfigUtils_1.ConfigUtils.secureSaveError(); } if (params.arguments.prune) { const prunedFiles = config.api.secure.rmUnusedProps(); if (prunedFiles.length > 0) { yield config.api.secure.directSave(); params.response.console.log("Deleted secure properties for the following missing files:\n\t" + prunedFiles.join("\n\t") + "\n"); } } // Create the config, load the secure values, and activate the desired layer config.api.layers.activate(params.arguments.userConfig, params.arguments.globalConfig); let secureProps = config.api.secure.secureFields(); if (secureProps.length === 0) { params.response.console.log("No secure properties found in your config"); return; } if (params.arguments.profile) { const filteredSecureProps = secureProps.filter((prop) => config.api.profiles .getProfileNameFromPath(prop) .toLowerCase() === params.arguments.profile.toLowerCase()); if (filteredSecureProps.length === 0 && secureProps.length > 0) { params.response.console.log(`No secure properties from profile '${params.arguments.profile}' found.`); } else { secureProps = filteredSecureProps; } } // Prompt for values designated as secure for (const propName of secureProps) { let propValue; if (propName.endsWith(".tokenValue")) { propValue = yield this.handlePromptForAuthToken(config, propName); if (propValue === undefined) { propValue = yield params.response.console.prompt(`Enter ${propName} ${config_1.ConfigConstants.SKIP_PROMPT}`, { hideText: true }); } } else { propValue = yield params.response.console.prompt(`Enter ${propName} ${config_1.ConfigConstants.SKIP_PROMPT}`, { hideText: true }); // Save the value in the config securely if (propValue) { propValue = ConfigUtils_1.ConfigUtils.coercePropValue(propValue, config_1.ConfigSchema.findPropertyType(propName, config.properties)); } } // Save the value in the config securely if (propValue) { logger_1.Logger.getAppLogger().trace(`Setting property ${propName} to ${propValue}`); config.set(propName, propValue, { secure: true }); } } // Write the config layer yield config.save(); }); } /** * Checks if authentication service is associated with an auth token * property. If an auth service is found, we log in to it obtain the token * instead of prompting for the value. * @param config Team config class from which the property was loaded * @param propPath JSON property path of the auth token * @returns Token value, or undefined if none was obtained */ handlePromptForAuthToken(config, propPath) { return __awaiter(this, void 0, void 0, function* () { const profilePath = propPath.slice(0, propPath.indexOf(".properties")); const profile = config.api.profiles.get(profilePath.replace(/profiles\./g, ""), false); const authHandlerClass = ConfigAutoStore_1.ConfigAutoStore.findAuthHandlerForProfile(profilePath, this.params.arguments); if (authHandlerClass == null) { // no auth handler service was associated with the specified profile const tokenTypMsg = profile.tokenType ? `of type '${profile.tokenType}'` : "with no associated tokenType"; this.params.response.console.log(utilities_1.TextUtils.wordWrap(utilities_1.TextUtils.chalk.yellowBright(`\nA profile requires a token ${tokenTypMsg} to be securely stored. ` + `Supply a token at the prompt. Or press ENTER at the prompt and ` + `later log in to your service for a token.\n`))); // return undefined to allow prompting for tokenValue for this profile return; } // call auth handler service that was associated with the specified profile const api = authHandlerClass.getAuthHandlerApi(); if (api.promptParams.serviceDescription != null) { this.params.response.console.log(utilities_1.TextUtils.wordWrap(utilities_1.TextUtils.chalk.yellowBright(`\nNow logging in to ${api.promptParams.serviceDescription} to get a token for profile ` + `'${config.api.profiles.getProfileNameFromPath(propPath)}' ` + `${config_1.ConfigConstants.SKIP_PROMPT}`))); } const sessCfg = api.createSessCfg(profile); const sessCfgWithCreds = yield rest_1.ConnectionPropsForSessCfg.addPropsOrPrompt(sessCfg, profile, Object.assign({ parms: this.params, doPrompting: true, requestToken: true }, api.promptParams)); logger_1.Logger.getAppLogger().info(`Fetching ${profile.tokenType} for ${propPath}`); if (rest_1.ConnectionPropsForSessCfg.sessHasCreds(sessCfgWithCreds)) { try { const tokenValue = yield api.sessionLogin(new rest_1.Session(sessCfgWithCreds)); this.params.response.console.log("Logged in successfully\n"); return tokenValue; } catch (error) { throw new error_1.ImperativeError({ msg: `Failed to fetch ${profile.tokenType} for ${propPath}: ${error.message}`, causeErrors: error, }); } } else { this.params.response.console.log("No credentials provided.\n"); // return null to avoid prompting for tokenValue for this profile return null; } }); } } exports.default = SecureHandler; //# sourceMappingURL=secure.handler.js.map