Skip to content

Commit

Permalink
Merge branch 'main' into fix/extenders-api-credential-manager
Browse files Browse the repository at this point in the history
Signed-off-by: Billie Simmons <[email protected]>
  • Loading branch information
JillieBeanSim committed Jun 20, 2023
2 parents 9652fa9 + 473774c commit 43678a2
Show file tree
Hide file tree
Showing 8 changed files with 191 additions and 19 deletions.
7 changes: 5 additions & 2 deletions packages/zowe-explorer-api/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@ All notable changes to the "zowe-explorer-api" extension will be documented in t

### New features and enhancements

- Added optional `profile` parameter to `IPromptCredentialsOptions` so developers can choose to skip rebuilding the profile with ProfilesCache.
- Fixed error when an extender's extension attempts to access the keyring in a remote VSCode session [#324](https://github.com/zowe/vscode-extension-for-cics/issues/324).

### Bug fixes

- Fixed issue where profiles with authentication tokens were breaking functionality for direct-to-service profiles after user interaction. [#2111](https://github.com/zowe/vscode-extension-for-zowe/issues/2111)

## `2.9.0`

### New features and enhancements
Expand All @@ -17,8 +22,6 @@ All notable changes to the "zowe-explorer-api" extension will be documented in t
- Added optional `cancelJob` function to `ZoweExplorerApi.IJes` interface.
- Added z/OSMF API implementation for `cancelJob` function.
- Added optional `id` variable to `IZoweTreeNode` interface, which can be used to designate a unique ID for a tree node. [#2215](https://github.com/zowe/vscode-extension-for-zowe/issues/2215)

- Fixed error when an extender's extension attempts to access the keyring in a remote VSCode session [#324](https://github.com/zowe/vscode-extension-for-cics/issues/324).
- Fixed error shown by API when accessing the `name` and `type` property of a profile when updating the profile arrays [#2334](https://github.com/zowe/vscode-extension-for-zowe/issues/2334).

## `2.8.1`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import { Gui } from "../../../src/globals/Gui";
import { MessageSeverity, IZoweLogger } from "../../../src/logger/IZoweLogger";
import { IProfileLoaded } from "@zowe/imperative";
import { IPromptCredentialsOptions, ZoweVsCodeExtension } from "../../../src/vscode";
import { ZoweExplorerApi } from "../../../src";
import { ProfilesCache, ZoweExplorerApi } from "../../../src";
import { imperative } from "@zowe/cli";

describe("ZoweVsCodeExtension", () => {
const fakeVsce = {
Expand Down Expand Up @@ -328,5 +329,50 @@ describe("ZoweVsCodeExtension", () => {
expect(showInputBoxSpy).toHaveBeenCalledTimes(2);
expect(mockUpdateProperty).toHaveBeenCalledTimes(0);
});

it("should do nothing if profile and sessionName args are not provided", async () => {
const mockUpdateProperty = jest.fn();
jest.spyOn(ZoweVsCodeExtension as any, "profilesCache", "get").mockReturnValue({
getLoadedProfConfig: jest.fn().mockReturnValue({
profile: {},
}),
getProfileInfo: jest.fn().mockReturnValue({
isSecured: jest.fn().mockReturnValue(true),
updateProperty: mockUpdateProperty,
}),
refresh: jest.fn(),
});
const showInputBoxSpy = jest.spyOn(Gui, "showInputBox").mockResolvedValueOnce("fakeUser").mockResolvedValueOnce(undefined);
const profileLoaded = await ZoweVsCodeExtension.updateCredentials({}, undefined as unknown as ZoweExplorerApi.IApiRegisterClient);
expect(profileLoaded).toBeUndefined();
expect(showInputBoxSpy).not.toHaveBeenCalled();
expect(mockUpdateProperty).not.toHaveBeenCalled();
});

it("should not call ProfilesCache.getLoadedProfConfig if profile object is provided", async () => {
const mockUpdateProperty = jest.fn();
jest.spyOn(ZoweVsCodeExtension as any, "profilesCache", "get").mockReturnValue({
getLoadedProfConfig: jest.fn().mockReturnValue({
profile: {
name: "someExampleProfile",
profile: {
user: "testUser",
password: "testPassword",
} as imperative.IProfile,
} as imperative.IProfileLoaded,
}),
getProfileInfo: jest.fn().mockReturnValue({
isSecured: jest.fn().mockReturnValue(true),
updateProperty: mockUpdateProperty,
}),
refresh: jest.fn(),
});
const getLoadedProfConfigSpy = jest.spyOn(ProfilesCache.prototype, "getLoadedProfConfig");
const showInputBoxSpy = jest.spyOn(Gui, "showInputBox").mockResolvedValueOnce("fakeUser").mockResolvedValueOnce(undefined);
const profileLoaded = await ZoweVsCodeExtension.updateCredentials({}, undefined as unknown as ZoweExplorerApi.IApiRegisterClient);
expect(profileLoaded).toBeUndefined();
expect(getLoadedProfConfigSpy).not.toHaveBeenCalled();
expect(showInputBoxSpy).not.toHaveBeenCalled();
});
});
});
15 changes: 12 additions & 3 deletions packages/zowe-explorer-api/src/vscode/ZoweVsCodeExtension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export class ZoweVsCodeExtension {
* @deprecated
*/
public static async promptCredentials(options: IPromptCredentialsOptions): Promise<imperative.IProfileLoaded> {
const loadProfile = await this.profilesCache.getLoadedProfConfig(options.sessionName.trim());
const loadProfile = options.sessionName ? await this.profilesCache.getLoadedProfConfig(options.sessionName.trim()) : options.profile;
if (loadProfile == null) {
return undefined;
}
Expand Down Expand Up @@ -117,8 +117,17 @@ export class ZoweVsCodeExtension {
const cache = this.profilesCache;
const profInfo = await cache.getProfileInfo();
const setSecure = options.secure ?? profInfo.isSecured();
const loadProfile = await cache.getLoadedProfConfig(options.sessionName, options.sessionType);
const loadSession = loadProfile.profile as imperative.ISession;

if (options.profile == null && options.sessionName == null) {
return undefined;
}

const loadProfile = options.sessionName ? await cache.getLoadedProfConfig(options.sessionName) : options.profile;
const loadSession = loadProfile?.profile as imperative.ISession;

if (loadProfile == null || loadSession == null) {
return undefined;
}
const creds = await ZoweVsCodeExtension.promptUserPass({ session: loadSession, ...options });

if (creds && creds.length > 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ export interface IPromptCredentialsCommonOptions {
}

export interface IPromptCredentialsOptions extends IPromptCredentialsCommonOptions {
sessionName: string;
profile?: imperative.IProfileLoaded;
sessionName?: string;
sessionType?: string;
secure?: boolean;
}
Expand Down
1 change: 1 addition & 0 deletions packages/zowe-explorer/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ All notable changes to the "vscode-extension-for-zowe" extension will be documen
- Fixed an issue where the mismatch etag error returned was not triggering the diff editor, resulting in possible loss of data due to the issue. [#2277](https://github.com/zowe/vscode-extension-for-zowe/issues/2277)
- Fixed issue where refreshing views collapsed the respective trees. [#2215](https://github.com/zowe/vscode-extension-for-zowe/issues/2215)
- Fixed an issue where user would not get prompted when authentication error is thrown. [#2334](https://github.com/zowe/vscode-extension-for-zowe/issues/2334)
- Fixed issue where profiles with authentication tokens were breaking functionality for direct-to-service profiles after user interaction. [#2111](https://github.com/zowe/vscode-extension-for-zowe/issues/2111)

## `2.8.2`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ import { Profiles } from "../../../src/Profiles";
import { imperative } from "@zowe/cli";
import * as globals from "../../../src/globals";
import { createUSSTree } from "../../../src/uss/USSTree";
import { createIJobObject } from "../../../__mocks__/mockCreators/jobs";
import { createIJobObject, createJobSessionNode } from "../../../__mocks__/mockCreators/jobs";
import { Job } from "../../../src/job/ZoweJobNode";
import { createJobsTree } from "../../../src/job/ZosJobsProvider";
import { SettingsConfig } from "../../../src/utils/SettingsConfig";
import { ZoweTreeProvider } from "../../../src/abstract/ZoweTreeProvider";
import { ZoweLogger } from "../../../src/utils/LoggerUtils";
import { createDatasetSessionNode } from "../../../__mocks__/mockCreators/datasets";

async function createGlobalMocks() {
const globalMocks = {
Expand All @@ -54,6 +55,8 @@ async function createGlobalMocks() {
mockGetProfileSetting: jest.fn(),
mockProfilesForValidation: jest.fn(),
mockProfilesValidationSetting: jest.fn(),
mockSsoLogin: jest.fn(),
mockSsoLogout: jest.fn(),
ProgressLocation: jest.fn().mockImplementation(() => {
return {
Notification: 15,
Expand Down Expand Up @@ -115,6 +118,8 @@ async function createGlobalMocks() {
name: globalMocks.testProfile.name,
setting: true,
}),
ssoLogin: globalMocks.mockSsoLogin,
ssoLogout: globalMocks.mockSsoLogout,
getProfileInfo: () => globalMocks.mockProfileInfo,
fetchAllProfiles: jest.fn(() => {
return [{ name: "sestest" }, { name: "profile1" }, { name: "profile2" }];
Expand Down Expand Up @@ -405,3 +410,103 @@ describe("Tree Provider Unit Tests - function renameNode", () => {
spy.mockClear();
});
});

describe("Tree Provider Unit Tests - function ssoLogin", () => {
const createBlockMocks = () => {
const executeCommandSpy = jest.spyOn(vscode.commands, "executeCommand");
return {
executeCommandSpy,
};
};

const blockMocks = createBlockMocks();

afterEach(() => {
blockMocks.executeCommandSpy.mockClear();
});

it("should only call zowe.ds.refreshAll for a Data Set session node", async () => {
const globalMocks = await createGlobalMocks();
const dsNode = createDatasetSessionNode(globalMocks.testSession, globalMocks.testProfile);

await globalMocks.testTreeProvider.ssoLogin(dsNode);
expect(globalMocks.mockSsoLogin).toHaveBeenCalled();
expect(blockMocks.executeCommandSpy).toHaveBeenCalledWith("zowe.ds.refreshAll");
expect(blockMocks.executeCommandSpy).not.toHaveBeenCalledWith("zowe.uss.refreshAll");
expect(blockMocks.executeCommandSpy).not.toHaveBeenCalledWith("zowe.jobs.refreshAllJobs");
});

it("should only call zowe.uss.refreshAll for a USS session node", async () => {
const globalMocks = await createGlobalMocks();
const ussNode = createUSSSessionNode(globalMocks.testSession, globalMocks.testProfile);

await globalMocks.testTreeProvider.ssoLogin(ussNode);
expect(globalMocks.mockSsoLogin).toHaveBeenCalled();
expect(blockMocks.executeCommandSpy).toHaveBeenCalledWith("zowe.uss.refreshAll");
expect(blockMocks.executeCommandSpy).not.toHaveBeenCalledWith("zowe.ds.refreshAll");
expect(blockMocks.executeCommandSpy).not.toHaveBeenCalledWith("zowe.jobs.refreshAllJobs");
});

it("should only call zowe.jobs.refreshAllJobs for a Job session node", async () => {
const globalMocks = await createGlobalMocks();
const jobNode = createJobSessionNode(globalMocks.testSession, globalMocks.testProfile);

await globalMocks.testTreeProvider.ssoLogin(jobNode);
expect(globalMocks.mockSsoLogin).toHaveBeenCalled();
expect(blockMocks.executeCommandSpy).toHaveBeenCalledWith("zowe.jobs.refreshAllJobs");
expect(blockMocks.executeCommandSpy).not.toHaveBeenCalledWith("zowe.uss.refreshAll");
expect(blockMocks.executeCommandSpy).not.toHaveBeenCalledWith("zowe.ds.refreshAll");
});
});

describe("Tree Provider Unit Tests - function ssoLogout", () => {
const createBlockMocks = () => {
const executeCommandSpy = jest.spyOn(vscode.commands, "executeCommand");
return {
executeCommandSpy,
};
};

const blockMocks = createBlockMocks();

afterEach(() => {
blockMocks.executeCommandSpy.mockClear();
});

afterAll(() => {
blockMocks.executeCommandSpy.mockRestore();
});

it("should only call zowe.ds.refreshAll for a Data Set session node", async () => {
const globalMocks = await createGlobalMocks();
const dsNode = createDatasetSessionNode(globalMocks.testSession, globalMocks.testProfile);

await globalMocks.testTreeProvider.ssoLogout(dsNode);
expect(globalMocks.mockSsoLogout).toHaveBeenCalled();
expect(blockMocks.executeCommandSpy).toHaveBeenCalledWith("zowe.ds.refreshAll");
expect(blockMocks.executeCommandSpy).not.toHaveBeenCalledWith("zowe.uss.refreshAll");
expect(blockMocks.executeCommandSpy).not.toHaveBeenCalledWith("zowe.jobs.refreshAllJobs");
});

it("should only call zowe.uss.refreshAll for a USS session node", async () => {
const globalMocks = await createGlobalMocks();
const ussNode = createUSSSessionNode(globalMocks.testSession, globalMocks.testProfile);

await globalMocks.testTreeProvider.ssoLogout(ussNode);
expect(globalMocks.mockSsoLogout).toHaveBeenCalled();
expect(blockMocks.executeCommandSpy).toHaveBeenCalledWith("zowe.uss.refreshAll");
expect(blockMocks.executeCommandSpy).not.toHaveBeenCalledWith("zowe.ds.refreshAll");
expect(blockMocks.executeCommandSpy).not.toHaveBeenCalledWith("zowe.jobs.refreshAllJobs");
});

it("should only call zowe.jobs.refreshAllJobs for a Job session node", async () => {
const globalMocks = await createGlobalMocks();
const jobNode = createJobSessionNode(globalMocks.testSession, globalMocks.testProfile);

await globalMocks.testTreeProvider.ssoLogout(jobNode);
expect(globalMocks.mockSsoLogout).toHaveBeenCalled();
expect(blockMocks.executeCommandSpy).toHaveBeenCalledWith("zowe.jobs.refreshAllJobs");
expect(blockMocks.executeCommandSpy).not.toHaveBeenCalledWith("zowe.uss.refreshAll");
expect(blockMocks.executeCommandSpy).not.toHaveBeenCalledWith("zowe.ds.refreshAll");
});
});
9 changes: 4 additions & 5 deletions packages/zowe-explorer/src/Profiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -869,8 +869,8 @@ export class Profiles extends ProfilesCache {

const promptInfo = await ZoweVsCodeExtension.updateCredentials(
{
sessionName: typeof profile !== "string" ? profile.name : profile,
sessionType: typeof profile !== "string" ? profile.type : undefined,
profile: typeof profile === "string" ? undefined : profile,
sessionName: typeof profile === "string" ? profile : undefined,
rePrompt,
secure: (await this.getProfileInfo()).isSecured(),
userInputBoxOptions,
Expand All @@ -883,8 +883,7 @@ export class Profiles extends ProfilesCache {
return; // See https://github.com/zowe/vscode-extension-for-zowe/issues/1827
}

const updSession = promptInfo.profile as zowe.imperative.ISession;
const returnValue = [updSession.user, updSession.password, updSession.base64EncodedAuth];
const returnValue: string[] = [promptInfo.profile.user, promptInfo.profile.password, promptInfo.profile.base64EncodedAuth];
this.updateProfilesArrays(promptInfo);
return returnValue;
}
Expand Down Expand Up @@ -1213,7 +1212,7 @@ export class Profiles extends ProfilesCache {
};
await this.updateBaseProfileFileLogin(baseProfile, updBaseProfile);
const baseIndex = this.allProfiles.findIndex((profile) => profile.name === baseProfile.name);
this.allProfiles[baseIndex] = { ...baseProfile, profile: { ...baseProfile, ...updBaseProfile } };
this.allProfiles[baseIndex] = { ...baseProfile, profile: { ...baseProfile.profile, ...updBaseProfile } };
node.setProfileToChoice({
...node.getProfile(),
profile: { ...node.getProfile().profile, ...updBaseProfile },
Expand Down
20 changes: 14 additions & 6 deletions packages/zowe-explorer/src/abstract/ZoweTreeProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,17 +247,25 @@ export class ZoweTreeProvider {
public async ssoLogin(node: IZoweTreeNode): Promise<void> {
ZoweLogger.trace("ZoweTreeProvider.ssoLogin called.");
await Profiles.getInstance().ssoLogin(node);
await vscode.commands.executeCommand("zowe.ds.refreshAll");
await vscode.commands.executeCommand("zowe.uss.refreshAll");
await vscode.commands.executeCommand("zowe.jobs.refreshAllJobs");
if (contextually.isDsSession(node)) {
await vscode.commands.executeCommand("zowe.ds.refreshAll");
} else if (contextually.isUssSession(node)) {
await vscode.commands.executeCommand("zowe.uss.refreshAll");
} else {
await vscode.commands.executeCommand("zowe.jobs.refreshAllJobs");
}
}

public async ssoLogout(node: IZoweTreeNode): Promise<void> {
ZoweLogger.trace("ZoweTreeProvider.ssoLogout called.");
await Profiles.getInstance().ssoLogout(node);
await vscode.commands.executeCommand("zowe.ds.refreshAll");
await vscode.commands.executeCommand("zowe.uss.refreshAll");
await vscode.commands.executeCommand("zowe.jobs.refreshAllJobs");
if (contextually.isDsSession(node)) {
await vscode.commands.executeCommand("zowe.ds.refreshAll");
} else if (contextually.isUssSession(node)) {
await vscode.commands.executeCommand("zowe.uss.refreshAll");
} else {
await vscode.commands.executeCommand("zowe.jobs.refreshAllJobs");
}
}

public async createZoweSchema(zoweFileProvider: IZoweTree<IZoweNodeType>): Promise<void> {
Expand Down

0 comments on commit 43678a2

Please sign in to comment.