Skip to content

Commit

Permalink
Add more tests, fix envQuery defect, handle multiple option definitions
Browse files Browse the repository at this point in the history
Signed-off-by: Andrew W. Harn <[email protected]>
  • Loading branch information
awharn committed Jan 30, 2025
1 parent 68fb52e commit aeb7e91
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 17 deletions.
94 changes: 93 additions & 1 deletion packages/imperative/src/censor/__tests__/Censor.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ beforeAll(() => {

afterAll(() => {
jest.restoreAllMocks();
Censor.setCensoredOptions();
});

describe("Censor tests", () => {
Expand Down Expand Up @@ -258,7 +259,11 @@ describe("Censor tests", () => {
properties: {
test: {
type: "string",
description: "Fake Test Description"
optionDefinition: {
name: "test",
type: "string",
description: "Fake Test Description"
}
}
}
}
Expand All @@ -276,4 +281,91 @@ describe("Censor tests", () => {
expect(Censor.profileSchemas).toEqual([]);
});
});

describe("isSpecialValues", () => {
let impConfigSpy: jest.SpyInstance = null;

beforeEach(() => {
(Censor as any).mSchema = null;
impConfigSpy = jest.spyOn(ImperativeConfig, "instance", "get");
});

afterAll(() => {
(Censor as any).mSchema = null;
});

describe("default list", () => {
for(const opt of Censor.SECURE_PROMPT_OPTIONS) {
it(`should return true for ${opt}`, () => {
expect(Censor.isSpecialValue("profiles.secret.properties." + opt)).toBe(true);
});
}

it("should return false for option 'test' when no profile schema is set", () => {
expect(Censor.isSpecialValue("profiles.test.properties.test")).toBe(false);
});

it("should return true for option 'test' when profile schema is set 1", () => {
const mockedProfiles = [{
type: "test",
schema: {
title: "Fake Profile Type",
description: "Fake Profile Description",
type: "object",
properties: {
test: {
type: "string",
secure: true,
optionDefinition: {
name: "test",
type: "string",
description: "Fake Test Description",
}
}
}
}
}];
impConfigSpy.mockReturnValue({
loadedConfig: {
profiles: mockedProfiles
}
});
expect(Censor.isSpecialValue("profiles.test.properties.test")).toBe(true);
});

it("should return true for option 'test' when profile schema is set 2", () => {
const mockedProfiles = [{
type: "test",
schema: {
title: "Fake Profile Type",
description: "Fake Profile Description",
type: "object",
properties: {
test: {
type: "string",
secure: true,
optionDefinitions: [{
name: "test1",
type: "string",
description: "Fake Test Description"
}, {
name: "test2",
type: "string",
description: "Fake Test Description"
}]
}
}
}
}];
impConfigSpy.mockReturnValue({
loadedConfig: {
profiles: mockedProfiles
}
});
expect(Censor.isSpecialValue("profiles.test.properties.test")).toBe(false);
expect(Censor.isSpecialValue("profiles.test.properties.test1")).toBe(true);
expect(Censor.isSpecialValue("profiles.test.properties.test2")).toBe(true);
});
});
});
});
38 changes: 25 additions & 13 deletions packages/imperative/src/censor/src/Censor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,12 @@ export class Censor {
* @param {string} option - The option to censor
*/
public static addCensoredOption(option: string) {
this.censored_options.add(option);
this.censored_options.add(CliUtils.getOptionFormat(option).camelCase);
this.censored_options.add(CliUtils.getOptionFormat(option).kebabCase);
// This option is required, but we do not want to ever allow null or undefined itself into the censored options
if (option != null) {
this.censored_options.add(option);
this.censored_options.add(CliUtils.getOptionFormat(option).camelCase);
this.censored_options.add(CliUtils.getOptionFormat(option).kebabCase);
}
}

/**
Expand Down Expand Up @@ -154,17 +157,26 @@ export class Censor {
if (censorOpts.profiles) {this.setProfileSchemas(censorOpts.profiles);}

for (const profileType of this.profileSchemas ?? []) {
for (const [propName, propValue] of Object.entries(profileType.schema.properties)) {
// Include the property itself
if (propValue.secure) {
this.addCensoredOption(propName);
}

// Include any known aliases (if available)
if ((propValue as ICommandProfileProperty).optionDefinition?.aliases != null) {
for (const alias of (propValue as ICommandProfileProperty).optionDefinition.aliases) {
this.addCensoredOption(alias);
for (const [_, prop] of Object.entries(profileType.schema.properties)) {
// Add censored options from the schema if the option is secure
if (prop.secure) {
// Handle the case of a single option definition
if (prop.optionDefinition) {
this.addCensoredOption(prop.optionDefinition.name);
for (const alias of prop.optionDefinition.aliases || []) {
// Remember to add the alias
this.addCensoredOption(alias);
}
}

// Handle the case of multiple option definitions
prop.optionDefinitions?.map(opDef => {
this.addCensoredOption(opDef.name);
for (const alias of opDef.aliases || []) {
// Remember to add the alias
this.addCensoredOption(alias);
}
});
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -483,12 +483,10 @@ export class EnvQuery {
nextVar != "ZOWE_APP_LOG_LEVEL" && nextVar != "ZOWE_IMPERATIVE_LOG_LEVEL")
{
getResult.itemValMsg += nextVar + " = " ;
if (secureCredsList.includes(nextVar.toUpperCase()))
{
if (secureCredsList.some(secureOpt => nextVar.toUpperCase().includes(secureOpt))) {
getResult.itemValMsg += "******";
} else {
getResult.itemValMsg += envVars[nextVar];

}
getResult.itemValMsg += os.EOL;
}
Expand Down

0 comments on commit aeb7e91

Please sign in to comment.