Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple issues: Fixed errors with updating optional profile fields #1120

Merged
merged 18 commits into from
Feb 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/zowe-explorer-api/src/profiles/ProfilesCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ export class ProfilesCache {
profile: profileInfo,
name: profileName,
type: profileType,
overwrite: true,
});
return newProfile.profile;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/zowe-explorer-api/src/tree/IZoweTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export interface IZoweTree<T> extends vscode.TreeDataProvider<T> {
* Edit a session to the container
* @param node This parameter identifies the node that needs to be called
*/
editSession(node: IZoweNodeType): Promise<void>;
editSession(node: IZoweNodeType, zoweFileProvider: IZoweTree<IZoweNodeType>): Promise<void>;

/**
* Add a new session to the container
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,7 @@ describe("KeytarCredentialManager Unit Tests", () => {
error = err;
}
expect(error).toBeDefined();
expect(error.additionalDetails).toContain("Service = Zowe-Plugin");
expect(error.additionalDetails).toContain("Awesome-Service\n Account = user5");
expect(error.additionalDetails).toContain("Could not find an entry in the credential vault");
});

it("Test saving passwords to credential store", async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,7 @@ describe("Profiles Unit Tests - Function createNewConnection", () => {
globalMocks.mockShowQuickPick.mockResolvedValueOnce("False");

await blockMocks.profiles.createNewConnection("alternate");
expect(globalMocks.mockShowInformationMessage.mock.calls[0][0]).toBe("Operation Cancelled");
expect(globalMocks.mockShowInformationMessage.mock.calls[0][0]).toBe("Profile alternate was created.");
});

it("Tests that createNewConnection creates an alternate profile with default port value", async () => {
Expand Down Expand Up @@ -1015,7 +1015,7 @@ describe("Profiles Unit Tests - Function updateProfile", () => {
};
newMocks.profiles = await Profiles.createInstance(newMocks.log);
newMocks.profileInstance = createInstanceOfProfile(newMocks.profiles);
newMocks.changedImperativeProfile.profile = { user: "test2", password: "test2" };
newMocks.changedImperativeProfile.profile = { user: "test2", password: "test2", rejectUnauthorize: true };
newMocks.profileInfo = newMocks.changedImperativeProfile;
Object.defineProperty(globalMocks.mockCliProfileManager, "load", {
value: jest.fn(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ describe("ZoweJobNode unit tests - Function editSession", () => {
const blockMocks = await createBlockMocks(globalMocks);
const checkSession = jest.spyOn(blockMocks.testJobsProvider, "editSession");

await blockMocks.testJobsProvider.editSession(blockMocks.jobNode);
await blockMocks.testJobsProvider.editSession(blockMocks.jobNode, globalMocks.testUSSTree);
expect(globalMocks.mockEditSession).toHaveBeenCalled();
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1629,7 +1629,7 @@ describe("Dataset Tree Unit Tests - Function editSession", () => {
null
);

await testTree.editSession(node);
await testTree.editSession(node, testTree);

expect(node.getProfile().profile).toBe("testProfile");
});
Expand Down
8 changes: 3 additions & 5 deletions packages/zowe-explorer/src/KeytarCredentialManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
* *
*/

import { AbstractCredentialManager, ImperativeError, SecureCredential } from "@zowe/imperative";
import { AbstractCredentialManager, ImperativeError, SecureCredential, Logger } from "@zowe/imperative";

import * as nls from "vscode-nls";

// Set up localization
nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })();
const localize: nls.LocalizeFunc = nls.loadMessageBundle();
Expand Down Expand Up @@ -72,10 +73,7 @@ export class KeytarCredentialManager extends AbstractCredentialManager {
*/
protected async deleteCredentials(account: string): Promise<void> {
if (!(await this.deleteCredentialsHelper(account))) {
throw new ImperativeError({
msg: localize("errorHandling.deleteCredentials", "Unable to delete credentials."),
additionalDetails: this.getMissingEntryMessage(account),
});
Logger.getAppLogger().debug(localize("errorHandling.deleteCredentials", "Unable to delete credentials."));
}
}

Expand Down
79 changes: 45 additions & 34 deletions packages/zowe-explorer/src/Profiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
IProfileLoaded,
Logger,
ISession,
IUpdateProfileFromCliArgs,
ICommandArguments,
Session,
SessConstants,
Expand Down Expand Up @@ -605,8 +604,11 @@ export class Profiles extends ProfilesCache {
localize("createNewConnection.undefined.username", "Operation Cancelled")
);
return undefined;
} else if (newUser === "") {
delete schemaValues[value];
} else {
schemaValues[value] = newUser;
}
schemaValues[value] = newUser;
break;
case "password":
newPass = await this.passwordInfo();
Expand All @@ -615,8 +617,11 @@ export class Profiles extends ProfilesCache {
localize("createNewConnection.undefined.username", "Operation Cancelled")
);
return undefined;
} else if (newPass === "") {
delete schemaValues[value];
} else {
schemaValues[value] = newPass;
}
schemaValues[value] = newPass;
break;
case "rejectUnauthorized":
newRU = await this.ruInfo();
Expand All @@ -634,22 +639,18 @@ export class Profiles extends ProfilesCache {
switch (response) {
case "number":
options = await this.optionsValue(value, schema);
const enteredValue = await vscode.window.showInputBox(options);
if (!Number.isNaN(Number(enteredValue))) {
schemaValues[value] = Number(enteredValue);
const enteredValue = Number(await vscode.window.showInputBox(options));
if (!Number.isNaN(enteredValue)) {
if ((value === "encoding" || value === "responseTimeout") && enteredValue === 0) {
delete schemaValues[value];
} else {
schemaValues[value] = Number(enteredValue);
}
} else {
switch (true) {
case enteredValue === undefined:
vscode.window.showInformationMessage(
localize("createNewConnection.number", "Operation Cancelled")
);
return undefined;
case schema[value].optionDefinition.hasOwnProperty("defaultValue"):
schemaValues[value] = schema[value].optionDefinition.defaultValue;
break;
default:
schemaValues[value] = undefined;
break;
if (schema[value].optionDefinition.hasOwnProperty("defaultValue")) {
schemaValues[value] = schema[value].optionDefinition.defaultValue;
} else {
delete schemaValues[value];
}
}
break;
Expand All @@ -674,9 +675,10 @@ export class Profiles extends ProfilesCache {
return undefined;
}
if (defValue === "") {
break;
delete schemaValues[value];
} else {
schemaValues[value] = defValue;
}
schemaValues[value] = defValue;
break;
}
}
Expand Down Expand Up @@ -937,7 +939,7 @@ export class Profiles extends ProfilesCache {

// Remove from list of all profiles
const index = this.allProfiles.findIndex((deleteItem) => {
return deleteItem === deletedProfile;
return deleteItem.name === deletedProfile.name;
});
if (index >= 0) {
this.allProfiles.splice(index, 1);
Expand Down Expand Up @@ -1597,26 +1599,35 @@ export class Profiles extends ProfilesCache {
const OrigProfileInfo = this.loadedProfile.profile;
const NewProfileInfo = ProfileInfo.profile;

// Update the currently-loaded profile with the new info
const profileArray = Object.keys(this.loadedProfile.profile);
for (const value of profileArray) {
if (value === "user" || value === "password") {
if (!rePrompt) {
OrigProfileInfo.user = NewProfileInfo.user;
OrigProfileInfo.password = NewProfileInfo.password;
if ((value === "encoding" || value === "responseTimeout") && NewProfileInfo[value] === 0) {
// If the updated profile had these fields set to 0, delete them...
// this should get rid of a bad value that was stored
// in these properties before this update
delete OrigProfileInfo[value];
} else if (NewProfileInfo[value] !== undefined && NewProfileInfo[value] !== "") {
if (value === "user" || value === "password") {
if (!rePrompt) {
OrigProfileInfo.user = NewProfileInfo.user;
OrigProfileInfo.password = NewProfileInfo.password;
}
} else {
OrigProfileInfo[value] = NewProfileInfo[value];
}
} else {
OrigProfileInfo[value] = NewProfileInfo[value];
} else if (NewProfileInfo[value] === undefined || NewProfileInfo[value] === "") {
// If the updated profile had an empty property, delete it...
// this should get rid of any empty strings
// that were stored in the profile before this update
delete OrigProfileInfo[value];
}
}

// Using `IUpdateProfileFromCliArgs` here instead of `IUpdateProfile` is
// kind of a hack, but necessary to support storing secure credentials
// until this is fixed: https://github.com/zowe/imperative/issues/379
const updateParms: IUpdateProfileFromCliArgs = {
const updateParms: IUpdateProfile = {
name: this.loadedProfile.name,
merge: true,
// profile: OrigProfileInfo as IProfile
args: OrigProfileInfo as any,
merge: false,
profile: OrigProfileInfo as IProfile,
};
try {
this.getCliProfileManager(this.loadedProfile.type).update(updateParms);
Expand Down
17 changes: 9 additions & 8 deletions packages/zowe-explorer/src/abstract/ZoweTreeProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ export class ZoweTreeProvider {
return undefined;
}

public async editSession(node: IZoweTreeNode) {
public async editSession(node: IZoweTreeNode, zoweFileProvider: IZoweTree<IZoweNodeType>) {
const profile = node.getProfile();
const profileName = node.getProfileName();
// Check what happens is inactive
Expand All @@ -165,21 +165,22 @@ export class ZoweTreeProvider {
if (EditSession) {
node.getProfile().profile = EditSession as IProfile;
await setProfile(node, EditSession as IProfile);
await setSession(node, EditSession as ISession);
if (await node.getSession()) {
await setSession(node, EditSession as ISession);
} else {
zoweFileProvider.deleteSession(node.getSessionNode());
this.mHistory.addSession(node.label);
zoweFileProvider.addSession(node.getProfileName());
}
this.refresh();
}
try {
// refresh profilesForValidation to check the profile status again
// Remove the edited profile from profilesForValidation since it should be revalidated
Profiles.getInstance().profilesForValidation.forEach((checkProfile, index) => {
if (index === 0) {
Profiles.getInstance().profilesForValidation = [];
}
if (checkProfile.name === profileName) {
Profiles.getInstance().profilesForValidation.splice(index, 1);
}
});

await this.checkCurrentProfile(node);
} catch (error) {
await errorHandling(error);
}
Expand Down
12 changes: 9 additions & 3 deletions packages/zowe-explorer/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,9 @@ function initDatasetProvider(context: vscode.ExtensionContext, datasetProvider:
vscode.commands.registerCommand("zowe.refreshAll", () => refreshActions.refreshAll(datasetProvider));
vscode.commands.registerCommand("zowe.refreshNode", (node) => dsActions.refreshPS(node));
vscode.commands.registerCommand("zowe.pattern", (node) => datasetProvider.filterPrompt(node));
vscode.commands.registerCommand("zowe.editSession", async (node) => datasetProvider.editSession(node));
vscode.commands.registerCommand("zowe.editSession", async (node) =>
datasetProvider.editSession(node, datasetProvider)
);
vscode.commands.registerCommand("zowe.ZoweNode.openPS", (node) => dsActions.openPS(node, true, datasetProvider));
vscode.commands.registerCommand("zowe.createDataset", (node) => dsActions.createFile(node, datasetProvider));
vscode.commands.registerCommand("zowe.all.profilelink", (node) => linkProfileDialog(node.getProfile()));
Expand Down Expand Up @@ -286,7 +288,9 @@ function initUSSProvider(context: vscode.ExtensionContext, ussFileProvider: IZow
vscode.commands.registerCommand("zowe.uss.fullPath", (node: IZoweUSSTreeNode) =>
ussFileProvider.filterPrompt(node)
);
vscode.commands.registerCommand("zowe.uss.editSession", async (node) => ussFileProvider.editSession(node));
vscode.commands.registerCommand("zowe.uss.editSession", async (node) =>
ussFileProvider.editSession(node, ussFileProvider)
);
vscode.commands.registerCommand("zowe.uss.ZoweUSSNode.open", (node: IZoweUSSTreeNode) =>
node.openUSS(false, true, ussFileProvider)
);
Expand Down Expand Up @@ -371,7 +375,9 @@ function initJobsProvider(context: vscode.ExtensionContext, jobsProvider: IZoweT
jobsProvider.setItem(jobsProvider.getTreeView(), job);
});
vscode.commands.registerCommand("zowe.jobs.search", (node) => jobsProvider.filterPrompt(node));
vscode.commands.registerCommand("zowe.jobs.editSession", async (node) => jobsProvider.editSession(node));
vscode.commands.registerCommand("zowe.jobs.editSession", async (node) =>
jobsProvider.editSession(node, jobsProvider)
);
vscode.commands.registerCommand("zowe.issueTsoCmd", async () => MvsCommandHandler.getInstance().issueMvsCommand());
vscode.commands.registerCommand("zowe.issueMvsCmd", async (node, command) =>
MvsCommandHandler.getInstance().issueMvsCommand(node.session, command, node)
Expand Down
8 changes: 4 additions & 4 deletions packages/zowe-explorer/src/uss/USSTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ export class USSTree extends ZoweTreeProvider implements IZoweTree<IZoweUSSTreeN
node.getSession(),
null,
false,
node.getSessionNode().getProfileName()
profileName
);
temp.fullPath = node.fullPath;
this.saveSearch(temp);
Expand All @@ -318,7 +318,7 @@ export class USSTree extends ZoweTreeProvider implements IZoweTree<IZoweUSSTreeN
node.getSession(),
node.getParent().fullPath,
false,
node.getSessionNode().getProfileName()
profileName
);
temp.contextValue = contextually.asFavorite(temp);
if (contextually.isFavoriteTextOrBinary(temp)) {
Expand Down Expand Up @@ -484,13 +484,13 @@ export class USSTree extends ZoweTreeProvider implements IZoweTree<IZoweUSSTreeN
if (this.log) {
this.log.debug(localize("filterPrompt.log.debug.promptUSSPath", "Prompting the user for a USS path"));
}
let sessionNode = node.getSessionNode();
let remotepath: string;
await this.checkCurrentProfile(node);
if (
Profiles.getInstance().validProfile === ValidProfileEnum.VALID ||
Profiles.getInstance().validProfile === ValidProfileEnum.UNVERIFIED
) {
let sessionNode = node.getSessionNode();
let remotepath: string;
if (contextually.isSessionNotFav(node)) {
if (this.mHistory.getSearchHistory().length > 0) {
const createPick = new FilterDescriptor(USSTree.defaultDialogText);
Expand Down
8 changes: 4 additions & 4 deletions packages/zowe-explorer/src/utils/ProfilesUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import * as vscode from "vscode";
import * as os from "os";
import * as path from "path";
import { ISession, IProfile, ImperativeConfig } from "@zowe/imperative";
import { IZoweTreeNode } from "@zowe/zowe-explorer-api";
import { IZoweNodeType, IZoweTree, IZoweTreeNode } from "@zowe/zowe-explorer-api";
import { Profiles } from "../Profiles";
import * as nls from "vscode-nls";

Expand Down Expand Up @@ -111,14 +111,14 @@ export function isTheia(): boolean {
* @param {sessNode} IZoweTreeNode
*************************************************************************************************************/
// This function does not perform any UI refresh; it just gets updated profile information.
export function refreshTree(sessNode: IZoweTreeNode) {
export async function refreshTree(sessNode: IZoweTreeNode) {
const allProf = Profiles.getInstance().getProfiles();
for (const profNode of allProf) {
if (sessNode.getProfileName() === profNode.name) {
setProfile(sessNode, profNode.profile);
const SessionProfile = profNode.profile as ISession;
if (sessNode.getSession().ISession !== SessionProfile) {
setSession(sessNode, SessionProfile);
if (sessNode.getSession() && sessNode.getSession().ISession !== SessionProfile) {
await setSession(sessNode, SessionProfile);
}
}
}
Expand Down