@zowe/imperative
Version:
framework for building configurable CLIs
307 lines • 13.1 kB
JavaScript
/*
* 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.
*
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.AbstractSession = void 0;
const logger_1 = require("../../../logger");
const error_1 = require("../../../error");
const expect_1 = require("../../../expect");
const SessConstants = require("./SessConstants");
/**
* The API session object, serves as the base for sessions and contains the fields that are required by
* most API calls (hostname, port, credentials, etc).
* @export
* @abstract
* @class AbstractSession
*/
class AbstractSession {
/**
* Obtain user name from a base 64 credential
* @static
* @param {string} auth - base 64 encoded credentials
* @returns {string} - user name
* @memberof AbstractSession
*/
static getUsernameFromAuth(auth) {
auth = auth.replace(AbstractSession.BASIC, "");
const decoding = Buffer.from(auth, "base64").toString();
return decoding.substring(0, decoding.lastIndexOf(":"));
}
/**
* Obtain password from a base 64 credential
* @static
* @param {string} auth - base 64 encoded credentials
* @returns {string} - password
* @memberof AbstractSession
*/
static getPasswordFromAuth(auth) {
auth = auth.replace(AbstractSession.BASIC, "");
const decoding = Buffer.from(auth, "base64").toString();
return decoding.substring(decoding.lastIndexOf(":") + 1);
}
/**
* Create base 64 encoded representation of user and password
* @static
* @param user - plain text user
* @param password - plain text password
* @returns {string} - base 64 encoded auth
* @memberof AbstractSession
*/
static getBase64Auth(user, password) {
return Buffer.from(user + ":" + password).toString("base64");
}
/**
* Creates an instance of AbstractSession.
* @param {ISession} session: Session parameter object
* @memberof AbstractSession
*/
constructor(mISession) {
this.mISession = mISession;
this.mLog = logger_1.Logger.getImperativeLogger();
mISession = this.buildSession(mISession);
}
/**
* Method to parse the requested token type
* @param {*} cookie - cookie object from http(s) response
* @memberof AbstractSession
*/
storeCookie(cookie) {
const headerKeys = Object.keys(cookie);
headerKeys.forEach((key) => {
const auth = cookie[key];
const authArr = auth.split(";");
// see each field in the cookie, e/g. Path=/; Secure; HttpOnly; LtpaToken2=...
authArr.forEach((element) => {
// if element begins with tokenType, extract full tokenType and tokenValue.
if (element.indexOf(this.ISession.tokenType) === 0) {
// parse off token value, splitting element at first "=".
const split = element.indexOf("=");
if (split >= 0) {
this.ISession.tokenType = element.substring(0, split);
this.ISession.tokenValue = element.substring(split + 1);
}
}
});
});
}
/**
* Builds an ISession so all required pieces are filled in
* @private
* @param {ISession} session - the fully populated session
* @memberof AbstractSession
*/
buildSession(session) {
var _a, _b;
const populatedSession = session;
// set protocol if not set
if (populatedSession.protocol === undefined || populatedSession.protocol === null) {
populatedSession.protocol = AbstractSession.DEFAULT_PROTOCOL;
}
// set rejectUnauthorized
if (populatedSession.rejectUnauthorized === undefined || populatedSession.rejectUnauthorized === null) {
populatedSession.rejectUnauthorized = AbstractSession.DEFAULT_REJECT_UNAUTHORIZED_SETTING;
}
// set strictSSL
if (((_a = populatedSession.proxy) === null || _a === void 0 ? void 0 : _a.proxy_strict_ssl) === false) {
populatedSession.strictSSL = false;
}
else {
if (((_b = populatedSession.proxy) === null || _b === void 0 ? void 0 : _b.proxy_strict_ssl) || populatedSession.strictSSL === undefined || populatedSession.strictSSL === null) {
populatedSession.strictSSL = AbstractSession.DEFAULT_STRICT_SSL;
}
}
// set port if not set
if (populatedSession.port === undefined || populatedSession.port === null) {
if (populatedSession.protocol === SessConstants.HTTP_PROTOCOL) {
populatedSession.port = AbstractSession.DEFAULT_HTTP_PORT;
}
else if (populatedSession.protocol === SessConstants.HTTPS_PROTOCOL) {
populatedSession.port = AbstractSession.DEFAULT_HTTPS_PORT;
}
}
// set protocol if not set
if (populatedSession.secureProtocol === undefined || populatedSession.secureProtocol === null) {
populatedSession.secureProtocol = AbstractSession.DEFAULT_SECURE_PROTOCOL;
}
// set basePath if not set
if (populatedSession.basePath === undefined || populatedSession.basePath === null) {
populatedSession.basePath = AbstractSession.DEFAULT_BASE_PATH;
}
// set type if not set
if (populatedSession.type === undefined || populatedSession.type === null) {
populatedSession.type = AbstractSession.DEFAULT_TYPE;
}
// populatedSession.type = populatedSession.type.toLocaleLowerCase();
expect_1.ImperativeExpect.keysToBeDefinedAndNonBlank(populatedSession, ["hostname"]);
expect_1.ImperativeExpect.toBeOneOf(populatedSession.type, [SessConstants.AUTH_TYPE_NONE, SessConstants.AUTH_TYPE_BASIC, SessConstants.AUTH_TYPE_TOKEN,
SessConstants.AUTH_TYPE_BEARER, SessConstants.AUTH_TYPE_CERT_PEM]); // , SessConstants.AUTH_TYPE_CERT_PFX]);
expect_1.ImperativeExpect.toBeOneOf(populatedSession.protocol, [SessConstants.HTTPS_PROTOCOL, SessConstants.HTTP_PROTOCOL]);
// if basic auth, must have user and password OR base 64 encoded credentials
if (session.type === SessConstants.AUTH_TYPE_BASIC) {
if (session.user !== undefined && session.user !== null &&
session.password !== undefined && session.password !== null) {
// ok
}
else if (session.base64EncodedAuth !== undefined && session.base64EncodedAuth !== null) {
// ok
}
else {
throw new error_1.ImperativeError({
msg: "Must have user & password OR base64 encoded credentials",
additionalDetails: "For CLI usage, see '<your-cli> auth login <service> --help'"
});
}
expect_1.ImperativeExpect.keysToBeUndefined(populatedSession, ["tokenType", "tokenValue", "cert", "certKey"]);
}
// if bearer auth, must have token
if (session.type === SessConstants.AUTH_TYPE_BEARER) {
expect_1.ImperativeExpect.keysToBeDefinedAndNonBlank(populatedSession, ["tokenValue"]);
expect_1.ImperativeExpect.keysToBeUndefined(populatedSession, ["tokenType", "user", "password", "cert", "certKey"]);
}
if (session.type === SessConstants.AUTH_TYPE_TOKEN) {
expect_1.ImperativeExpect.keysToBeDefinedAndNonBlank(session, ["tokenType"], "You must provide a token type to use cookie authentication");
if (populatedSession.tokenValue === undefined || populatedSession.tokenValue === null) {
if (session.user !== undefined && session.user !== null &&
session.password !== undefined && session.password !== null) {
// ok
}
else if (session.base64EncodedAuth !== undefined && session.base64EncodedAuth !== null) {
// ok
}
else {
throw new error_1.ImperativeError({
// msg: "Must have user & password OR tokenType & tokenValue OR cert & certKey OR cert & passphrase",
msg: "Must have user & password OR tokenType & tokenValue OR cert & certKey.",
additionalDetails: "For CLI usage, see '<your-cli> auth login <service> --help'"
});
}
}
}
if (session.type === SessConstants.AUTH_TYPE_CERT_PEM) {
expect_1.ImperativeExpect.keysToBeDefinedAndNonBlank(populatedSession, ["cert", "certKey"]);
expect_1.ImperativeExpect.keysToBeUndefined(populatedSession, ["tokenValue", "user", "password"]);
expect_1.ImperativeExpect.toNotBeEqual(populatedSession.protocol, SessConstants.HTTP_PROTOCOL, "Certificate based authentication cannot be used over HTTP. Please set protocol to HTTPS to use certificate authentication.");
}
// if (session.type === SessConstants.AUTH_TYPE_CERT_PFX) {
// ImperativeExpect.keysToBeDefinedAndNonBlank(populatedSession, ["cert", "passphrase"]);
// ImperativeExpect.toNotBeEqual(populatedSession.protocol, SessConstants.HTTP_PROTOCOL,
// "Certificate based authentication cannot be used over HTTP. Please set protocol to HTTPS to use certificate authentication.");
// }
// if basic auth
if (populatedSession.type === SessConstants.AUTH_TYPE_BASIC || populatedSession.type === SessConstants.AUTH_TYPE_TOKEN) {
// get base 64 encoded auth if not provided
if (populatedSession.base64EncodedAuth === undefined || populatedSession.base64EncodedAuth === null) {
if (populatedSession.user !== undefined && populatedSession.user !== null &&
populatedSession.password !== undefined && populatedSession.password !== null) {
populatedSession.base64EncodedAuth = AbstractSession.getBase64Auth(populatedSession.user, populatedSession.password);
}
}
else {
if (populatedSession.user === undefined || populatedSession.user === null) {
populatedSession.user = AbstractSession.getUsernameFromAuth(populatedSession.base64EncodedAuth);
}
if (populatedSession.password === undefined || populatedSession.password === null) {
populatedSession.password = AbstractSession.getPasswordFromAuth(populatedSession.base64EncodedAuth);
}
}
}
return populatedSession;
}
/**
* Obtain session info and defaults
* @readonly
* @type {ISession}
* @memberof AbstractSession
*/
get ISession() {
return this.mISession;
}
}
exports.AbstractSession = AbstractSession;
/**
* Basic auth prefix
* @static
* @type {string}
* @memberof AbstractSession
*/
AbstractSession.BASIC_PREFIX = "Basic ";
/**
* Bearer auth prefix
* @static
* @type {string}
* @memberof AbstractSession
*/
AbstractSession.BEARER_PREFIX = "Bearer ";
/**
* Default protocol
* @static
* @memberof AbstractSession
*/
AbstractSession.DEFAULT_PROTOCOL = SessConstants.HTTPS_PROTOCOL;
/**
* Default session type
* @static
* @memberof AbstractSession
*/
AbstractSession.DEFAULT_TYPE = SessConstants.AUTH_TYPE_NONE;
/**
* Default http port 80
* @static
* @memberof AbstractSession
*/
AbstractSession.DEFAULT_HTTP_PORT = 80;
/**
* Default https port 443
* @static
* @memberof AbstractSession
*/
AbstractSession.DEFAULT_HTTPS_PORT = 443;
/**
* Default https port
* @static
* @memberof AbstractSession
*/
AbstractSession.DEFAULT_PORT = AbstractSession.DEFAULT_HTTPS_PORT;
/**
* Default base path.
* Our empty string means that we do **not** use an API mediation layer
* base path at the beginning of every resource URL.
* @static
* @memberof AbstractSession
*/
AbstractSession.DEFAULT_BASE_PATH = "";
/**
* Default reject unauthorized
* @static
* @memberof AbstractSession
*/
AbstractSession.DEFAULT_REJECT_UNAUTHORIZED_SETTING = true;
/**
* Default strict ssl setting
* @static
* @memberof AbstractSession
*/
AbstractSession.DEFAULT_STRICT_SSL = true;
/**
* Default SSL method
* @static
* @memberof AbstractSession
*/
AbstractSession.DEFAULT_SECURE_PROTOCOL = "SSLv23_method";
// TODO: Investigate - this does not seem to do anything, and Node defaults to TLS_method w/ TLS 1.3 support
/**
* Regex to extract basic from base64 encoded auth
* @static
* @type {RegExp}
* @memberof AbstractSession
*/
AbstractSession.BASIC = /^Basic/ig;
//# sourceMappingURL=AbstractSession.js.map
;