From ea8a2fcbb910634240dc662338075ce9e1d26517 Mon Sep 17 00:00:00 2001 From: Pranav Joglekar Date: Mon, 20 May 2024 13:17:00 +0530 Subject: [PATCH] feat: add support for vault secrets in scripts --- README.md | 1 + lib/sandbox/execution.js | 2 +- lib/sandbox/pmapi.js | 6 ++++ test/unit/pm-variables.test.js | 28 ++++++++++++--- test/unit/sandbox-libraries/pm.test.js | 49 ++++++++++++++++++++++++++ types/index.d.ts | 1 + types/sandbox/prerequest.d.ts | 1 + types/sandbox/test.d.ts | 1 + 8 files changed, 84 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index de04ebe8..5c7ed541 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ The following section outlines the API available inside sandbox scripts - pm.environment - pm.collectionVariables - pm.test +- pm.vaultSecrets #### pre-request script specials diff --git a/lib/sandbox/execution.js b/lib/sandbox/execution.js index ab521ac9..f5b0d8e8 100644 --- a/lib/sandbox/execution.js +++ b/lib/sandbox/execution.js @@ -18,7 +18,7 @@ const _ = require('lodash'), test: true }, - CONTEXT_VARIABLE_SCOPES = ['_variables', 'environment', 'collectionVariables', 'globals'], + CONTEXT_VARIABLE_SCOPES = ['_variables', 'environment', 'collectionVariables', 'globals', 'vaultSecrets'], trackingOptions = { autoCompact: true }; diff --git a/lib/sandbox/pmapi.js b/lib/sandbox/pmapi.js index db514c82..826d244b 100644 --- a/lib/sandbox/pmapi.js +++ b/lib/sandbox/pmapi.js @@ -62,6 +62,7 @@ function Postman (execution, onRequest, onSkipRequest, onAssertion, cookieStore, execution._variables.addLayer(execution.environment.values); execution._variables.addLayer(execution.collectionVariables.values); execution._variables.addLayer(execution.globals.values); + execution._variables.addLayer(execution.vaultSecrets.values); execution.cookies && (execution.cookies.jar = function () { return new PostmanCookieJar(cookieStore); @@ -123,6 +124,11 @@ function Postman (execution, onRequest, onSkipRequest, onAssertion, cookieStore, requestId: execution.legacy._itemId }), + /** + * @type {VariableScope} + */ + vaultSecrets: execution.vaultSecrets, + /** * @type {VariableScope} */ diff --git a/test/unit/pm-variables.test.js b/test/unit/pm-variables.test.js index c77d55e1..ca959e93 100644 --- a/test/unit/pm-variables.test.js +++ b/test/unit/pm-variables.test.js @@ -30,13 +30,15 @@ describe('pm.variables', function () { describe('.set', function () { before(function (done) { - var globalVarList = new sdk.VariableList(null, { key: 'key-1', value: 'value-1' }), + var vaultSecretList = new sdk.VariableList(null, { key: 'vault:key-0', value: 'value-0' }), + globalVarList = new sdk.VariableList(null, { key: 'key-1', value: 'value-1' }), collectionVarList = new sdk.VariableList(null, { key: 'key-2', value: 'value-2' }), envVarList = new sdk.VariableList(null, { key: 'key-3', value: 'value-3' }), contextData = { 'key-4': 'value-4' }, localVarList = new sdk.VariableList(null, { key: 'key-5', value: 'value-5' }); ctx.execute(` + pm.variables.set("vault:key-0", "modified"); pm.variables.set("key-1", "modified"); pm.variables.set("key-2", "modified"); pm.variables.set("key-3", "modified"); @@ -46,6 +48,7 @@ describe('pm.variables', function () { `, { timeout: 200, context: { + vaultSecrets: new sdk.VariableScope(vaultSecretList), globals: new sdk.VariableScope(globalVarList), collectionVariables: new sdk.VariableScope(collectionVarList), environment: new sdk.VariableScope(envVarList), @@ -64,6 +67,7 @@ describe('pm.variables', function () { it('should return the modified variables in the result', function () { expect(executionResults).to.deep.nested.include({ '_variables.values': [ { type: 'any', value: 'modified', key: 'key-5' }, + { type: 'any', value: 'modified', key: 'vault:key-0' }, { type: 'any', value: 'modified', key: 'key-1' }, { type: 'any', value: 'modified', key: 'key-2' }, { type: 'any', value: 'modified', key: 'key-3' }, @@ -74,6 +78,9 @@ describe('pm.variables', function () { it('should not modify the globals, envrironment, collection and data variables', function () { expect(executionResults).to.deep.nested.include({ + 'vaultSecrets.values': [ + { type: 'any', key: 'vault:key-0', value: 'value-0' } + ], 'globals.values': [ { type: 'any', value: 'value-1', key: 'key-1' } ], @@ -128,7 +135,12 @@ describe('pm.variables', function () { describe('.get', function () { it('should honour the precendence', function (done) { - var globalVarList = new sdk.VariableList(null, [ + var vaultSecretList = new sdk.VariableList(null, [ + { key: 'vault:key-0', value: 'value-0' }, + { key: 'vault:key-1', value: 'value-0' } + ]), + globalVarList = new sdk.VariableList(null, [ + { key: 'vault:key-1', value: 'value-1' }, { key: 'key-1', value: 'value-1' }, { key: 'key-2', value: 'value-1' }, { key: 'key-3', value: 'value-1' }, @@ -165,11 +177,14 @@ describe('pm.variables', function () { 'key-2': 'value-2', 'key-3': 'value-3', 'key-4': 'value-4', - 'key-5': 'value-5' + 'key-5': 'value-5', + 'vault:key-0': 'value-0', + 'vault:key-1': 'value-1' }); `, { timeout: 200, context: { + vaultSecrets: new sdk.VariableScope(vaultSecretList), globals: new sdk.VariableScope(globalVarList), collectionVariables: new sdk.VariableScope(collectionVarList), environment: new sdk.VariableScope(envVarList), @@ -186,7 +201,8 @@ describe('pm.variables', function () { }); it('should return appropriate variables', function (done) { - var globalVarList = new sdk.VariableList(null, { key: 'key-1', value: 'value-1' }), + var vaultSecretList = new sdk.VariableList(null, { key: 'vault:key-0', value: 'value-0' }), + globalVarList = new sdk.VariableList(null, { key: 'key-1', value: 'value-1' }), collectionVarList = new sdk.VariableList(null, { key: 'key-2', value: 'value-2' }), envVarList = new sdk.VariableList(null, { key: 'key-3', value: 'value-3' }), contextData = { 'key-4': 'value-4' }, @@ -194,6 +210,7 @@ describe('pm.variables', function () { ctx.execute(` var assert = require('assert'); + assert.strictEqual(pm.variables.get('vault:key-0'), 'value-0'); assert.strictEqual(pm.variables.get('key-1'), 'value-1'); assert.strictEqual(pm.variables.get('key-2'), 'value-2'); assert.strictEqual(pm.variables.get('key-3'), 'value-3'); @@ -203,6 +220,7 @@ describe('pm.variables', function () { `, { timeout: 200, context: { + vaultSecrets: new sdk.VariableScope(vaultSecretList), globals: new sdk.VariableScope(globalVarList), collectionVariables: new sdk.VariableScope(collectionVarList), environment: new sdk.VariableScope(envVarList), @@ -221,6 +239,7 @@ describe('pm.variables', function () { it('should reinitialize the variables when same sandbox instance is used again', function (done) { ctx.execute(` var assert = require('assert'); + assert.strictEqual(pm.variables.get('vault:key-0'), undefined); assert.strictEqual(pm.variables.get('key-1'), undefined); assert.strictEqual(pm.variables.get('key-2'), undefined); assert.strictEqual(pm.variables.get('key-3'), undefined); @@ -234,6 +253,7 @@ describe('pm.variables', function () { if (err) { return done(err); } expect(execution).to.deep.nested.include({ + 'vaultSecrets.values': [], 'globals.values': [], '_variables.values': [], 'collectionVariables.values': [], diff --git a/test/unit/sandbox-libraries/pm.test.js b/test/unit/sandbox-libraries/pm.test.js index b55c5b0a..0d32e6dd 100644 --- a/test/unit/sandbox-libraries/pm.test.js +++ b/test/unit/sandbox-libraries/pm.test.js @@ -30,6 +30,13 @@ describe('sandbox library - pm api', function () { value: 2.9, type: 'number' }], + vaultSecrets: [{ + key: 'vault:var1', + value: 'one-vault' + }, { + key: 'vault:var2', + value: 'two-vault' + }], data: { var1: 'one-data' } @@ -265,6 +272,48 @@ describe('sandbox library - pm api', function () { }); }); + describe('vaultSecrets', function () { + it('should be defined as VariableScope', function (done) { + context.execute(` + var assert = require('assert'), + VariableScope = require('postman-collection').VariableScope; + assert.strictEqual(VariableScope.isVariableScope(pm.vaultSecrets), true); + `, done); + }); + + it('should be a readonly property', function (done) { + context.execute(` + var assert = require('assert'), + _vaultSecrets; + + _vaultSecrets = pm.vaultSecrets; + pm.vaultSecrets = []; + + assert.strictEqual(pm.vaultSecrets, _vaultSecrets, 'property stays unchanged'); + `, done); + }); + + it('should forward vaultSecrets forwarded during execution', function (done) { + context.execute(` + var assert = require('assert'); + assert.strictEqual(pm.vaultSecrets.get('vault:var1'), 'one-vault'); + assert.strictEqual(pm.vaultSecrets.get('vault:var2'), 'two-vault'); + `, { context: sampleContextData }, done); + }); + + it('pm.vaultSecrets.toObject must return a pojo', function (done) { + context.execute(` + var assert = require('assert'); + + assert.strictEqual(_.isPlainObject(pm.vaultSecrets.toObject()), true); + assert.deepEqual(pm.vaultSecrets.toObject(), { + 'vault:var1': 'one-vault', + 'vault:var2': 'two-vault' + }); + `, { context: sampleContextData }, done); + }); + }); + describe('request', function () { it('should be defined as sdk Request object', function (done) { context.execute(` diff --git a/types/index.d.ts b/types/index.d.ts index 11ab88fb..f0b853d6 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -108,6 +108,7 @@ declare class Postman { globals: VariableScope; environment: VariableScope; collectionVariables: VariableScope; + vaultSecrets: VariableScope; variables: VariableScope; /** * The iterationData object contains data from the data file provided during a collection run. diff --git a/types/sandbox/prerequest.d.ts b/types/sandbox/prerequest.d.ts index af7bf282..2fd90cb7 100644 --- a/types/sandbox/prerequest.d.ts +++ b/types/sandbox/prerequest.d.ts @@ -36,6 +36,7 @@ declare class Postman { globals: import("postman-collection").VariableScope; environment: import("postman-collection").VariableScope; collectionVariables: import("postman-collection").VariableScope; + vaultSecrets: import("postman-collection").VariableScope; variables: import("postman-collection").VariableScope; /** * The iterationData object contains data from the data file provided during a collection run. diff --git a/types/sandbox/test.d.ts b/types/sandbox/test.d.ts index 42924417..53f7f5af 100644 --- a/types/sandbox/test.d.ts +++ b/types/sandbox/test.d.ts @@ -36,6 +36,7 @@ declare class Postman { globals: import("postman-collection").VariableScope; environment: import("postman-collection").VariableScope; collectionVariables: import("postman-collection").VariableScope; + vaultSecrets: import("postman-collection").VariableScope; variables: import("postman-collection").VariableScope; /** * The iterationData object contains data from the data file provided during a collection run.