-
Notifications
You must be signed in to change notification settings - Fork 87
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
feat: add secureFieldsWithDetails 😋 #2241
Changes from all commits
e6f738e
7461902
1b28916
d0e406c
9e77bf9
cf06aa0
7139287
23dec8a
ed4498a
4eafe92
35b9d47
dc945c7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,7 +33,6 @@ import { IExtendersJsonOpts } from "../src/doc/IExtenderOpts"; | |
import { ConfigSchema } from "../src/ConfigSchema"; | ||
import { Logger } from "../../logger/src/Logger"; | ||
|
||
|
||
const testAppNm = "ProfInfoApp"; | ||
const testEnvPrefix = testAppNm.toUpperCase(); | ||
const profileTypes = ["zosmf", "tso", "base", "dummy"]; | ||
|
@@ -331,7 +330,7 @@ describe("TeamConfig ProfileInfo tests", () => { | |
it("should return true if credentials are not secure", async () => { | ||
// ensure that we are not in the team project directory | ||
const profInfo = createNewProfInfo(origDir); | ||
(profInfo as any).mCredentials = {isSecured: false}; | ||
(profInfo as any).mCredentials = { isSecured: false }; | ||
const response = await profInfo.profileManagerWillLoad(); | ||
expect(response).toEqual(true); | ||
}); | ||
|
@@ -366,6 +365,56 @@ describe("TeamConfig ProfileInfo tests", () => { | |
}); | ||
}); | ||
|
||
describe("secureFieldsWithDetails", () => { | ||
it("should return an empty array if there are no secure fields in the given layer or if the layer does not exist", async () => { | ||
const profInfo = createNewProfInfo(teamProjDir); | ||
await profInfo.readProfilesFromDisk(); | ||
|
||
// Temporarily assume that there are no secure properties for this test only | ||
profInfo.getTeamConfig().mLayers[1].properties.profiles["LPAR007"].secure = []; | ||
|
||
// Project User does not exist | ||
expect(profInfo.secureFieldsWithDetails({ user: true, global: false })).toEqual([]); | ||
|
||
// Project Team dos exist, but has no secure properties | ||
expect(profInfo.secureFieldsWithDetails({ user: false, global: false })).toEqual([]); | ||
}); | ||
|
||
it("should return secure fields for the active layer even if they have no secure values stored in the vault", async () => { | ||
const profInfo = createNewProfInfo(teamProjDir); | ||
await profInfo.readProfilesFromDisk(); | ||
|
||
const securePropPath = "profiles.LPAR007.properties."; | ||
const teamProjDirJson = path.join(teamProjDir, testAppNm + ".config.json"); | ||
profInfo.getTeamConfig().mSecure = { | ||
[teamProjDirJson]: { | ||
[securePropPath + "string"]: "area51", | ||
[securePropPath + "boolean"]: true, | ||
[securePropPath + "number"]: 1234, | ||
}, | ||
}; | ||
|
||
const getPropAttr = (name: string | any, value: any, type?: string | null): IProfArgAttrs => ({ | ||
argLoc: { osLoc: [teamProjDirJson], locType: 1, jsonLoc: securePropPath + name }, | ||
argName: name, | ||
argValue: value, | ||
dataType: type !== undefined ? type : name, | ||
}); | ||
|
||
expect(profInfo.secureFieldsWithDetails()).toEqual([ | ||
getPropAttr("string", "area51"), | ||
getPropAttr("boolean", true), | ||
getPropAttr("number", 1234), | ||
getPropAttr("missing-after-this", undefined, null), | ||
getPropAttr("host", undefined, "string"), | ||
getPropAttr("port", undefined, "number"), | ||
getPropAttr("rejectUnauthorized", undefined, "boolean"), | ||
]); | ||
|
||
profInfo.getTeamConfig().mSecure = {}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, is this necessary for the locally scoped |
||
}); | ||
}); | ||
|
||
describe("getAllProfiles", () => { | ||
it("should return all profiles if no type is specified", async () => { | ||
const expectedDefaultProfiles = 4; | ||
|
@@ -375,7 +424,7 @@ describe("TeamConfig ProfileInfo tests", () => { | |
const expectedDefaultProfileNameDummy = "LPAR4"; | ||
let actualDefaultProfiles = 0; | ||
let expectedProfileNames = ["LPAR1", "LPAR2", "LPAR3", "LPAR1.tsoProfName", "LPAR1.tsoProfName.tsoSubProfName", | ||
"base_glob", "LPAR4", "LPAR5"]; | ||
"base_glob", "LPAR4", "LPAR5", "LPAR007"]; | ||
|
||
const profInfo = createNewProfInfo(teamProjDir); | ||
await profInfo.readProfilesFromDisk(); | ||
|
@@ -415,7 +464,7 @@ describe("TeamConfig ProfileInfo tests", () => { | |
const desiredProfType = "zosmf"; | ||
const expectedName = "LPAR1"; | ||
const expectedDefaultProfiles = 1; | ||
let expectedProfileNames = ["LPAR1", "LPAR2", "LPAR3", "LPAR2_home", "LPAR5"]; | ||
let expectedProfileNames = ["LPAR1", "LPAR2", "LPAR3", "LPAR2_home", "LPAR5", "LPAR007"]; | ||
let actualDefaultProfiles = 0; | ||
|
||
const profInfo = createNewProfInfo(teamProjDir); | ||
|
@@ -449,7 +498,7 @@ describe("TeamConfig ProfileInfo tests", () => { | |
const desiredProfType = "zosmf"; | ||
const expectedName = "LPAR1"; | ||
const expectedDefaultProfiles = 1; | ||
let expectedProfileNames = ["LPAR1", "LPAR2", "LPAR3", "LPAR5"]; | ||
let expectedProfileNames = ["LPAR1", "LPAR2", "LPAR3", "LPAR5", "LPAR007"]; | ||
let actualDefaultProfiles = 0; | ||
|
||
const profInfo = createNewProfInfo(teamProjDir); | ||
|
@@ -1116,7 +1165,7 @@ describe("TeamConfig ProfileInfo tests", () => { | |
expect(storeSpy).toHaveBeenCalledWith({ | ||
config: profInfo.getTeamConfig(), profileName: "LPAR4", profileType: "dummy", | ||
defaultBaseProfileName: "base_glob", | ||
propsToStore: [ "DOES_NOT_EXIST" ], sessCfg: { "DOES_NOT_EXIST": true }, setSecure : undefined, | ||
propsToStore: ["DOES_NOT_EXIST"], sessCfg: { "DOES_NOT_EXIST": true }, setSecure: undefined, | ||
}); | ||
}); | ||
|
||
|
@@ -1196,7 +1245,7 @@ describe("TeamConfig ProfileInfo tests", () => { | |
expect(storeSpy).toHaveBeenCalledWith({ | ||
config: profInfo.getTeamConfig(), profileName: "typeless", profileType: null, | ||
defaultBaseProfileName: "base_glob", | ||
propsToStore: [ "areBirdsReal" ], sessCfg: { "areBirdsReal": true }, setSecure : undefined, | ||
propsToStore: ["areBirdsReal"], sessCfg: { "areBirdsReal": true }, setSecure: undefined, | ||
}); | ||
}); | ||
|
||
|
@@ -1242,7 +1291,7 @@ describe("TeamConfig ProfileInfo tests", () => { | |
expect(storeSpy).toHaveBeenCalledWith({ | ||
config: profInfo.getTeamConfig(), profileName: "typeless_new", profileType: null, | ||
defaultBaseProfileName: "base_glob", | ||
propsToStore: [ "areBirdsReal" ], sessCfg: { "areBirdsReal": true }, setSecure : undefined, | ||
propsToStore: ["areBirdsReal"], sessCfg: { "areBirdsReal": true }, setSecure: undefined, | ||
}); | ||
}); | ||
}); | ||
|
@@ -1683,8 +1732,10 @@ describe("TeamConfig ProfileInfo tests", () => { | |
} | ||
} | ||
}, | ||
res: { success: false, info: "Both the old and new schemas are unversioned for some-type, but the schemas are different. " | ||
.concat("The new schema was not written to disk, but will still be accessible in-memory.") } | ||
res: { | ||
success: false, info: "Both the old and new schemas are unversioned for some-type, but the schemas are different. " | ||
.concat("The new schema was not written to disk, but will still be accessible in-memory.") | ||
} | ||
} | ||
); | ||
}); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -242,6 +242,17 @@ export class ConfigSecure extends ConfigApi { | |
return secureProps; | ||
} | ||
|
||
/** | ||
* Retrieve secure properties for a given layer path | ||
* | ||
* @param layerPath Path of the layer to get secure properties for | ||
* @returns the secure properties for the given layer, or null if not found | ||
*/ | ||
public secureFieldsForLayer(layerPath: string): IConfigSecureProperties { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is adding this method necessary? I'm probably being dumb but it seems like the |
||
const secureLayer = Object.keys(this.mConfig.mSecure).find(osLocation => osLocation === layerPath); | ||
return secureLayer ? this.mConfig.mSecure[secureLayer] : null; | ||
} | ||
|
||
/** | ||
* Retrieve info that can be used to store a profile property securely. | ||
* | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this is being a little picky, but is this line necessary for the locally scoped
config
variable?