From 76bd25f825a8cdd1b7d7489795924d3c153ad358 Mon Sep 17 00:00:00 2001 From: Andrew Guenther Date: Fri, 21 Jan 2022 23:57:31 -0800 Subject: [PATCH] Add the alwaysInheritAuthentication option This option forces all requests to inherit auth from the top of the collection. This is really useful when all requests should be using the same authentication. If authentication is called out on each request in the Postman app, they will not inherit the options set on the collection, like the token, and must all be set manually. By allowing all requests to simply inherit from the collection, the token can be set once at the top of the collection and all requests will use it automatically. Fixes #271 --- OPTIONS.md | 1 + lib/options.js | 10 ++++ lib/schemaUtils.js | 9 +++- .../security-test-inheritance.yaml | 48 +++++++++++++++++++ test/system/structure.test.js | 12 ++++- test/unit/base.test.js | 28 +++++++++++ 6 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 test/data/valid_openapi/security-test-inheritance.yaml diff --git a/OPTIONS.md b/OPTIONS.md index 22d2c3630..e08940b24 100644 --- a/OPTIONS.md +++ b/OPTIONS.md @@ -20,3 +20,4 @@ ignoreUnresolvedVariables|boolean|-|false|Whether to ignore mismatches resulting strictRequestMatching|boolean|-|false|Whether requests should be strictly matched with schema operations. Setting to true will not include any matches where the URL path segments don't match exactly.|VALIDATION disableOptionalParameters|boolean|-|false|Whether to set optional parameters as disabled|CONVERSION keepImplicitHeaders|boolean|-|false|Whether to keep implicit headers from the OpenAPI specification, which are removed by default.|CONVERSION +alwaysInheritAuthentication|boolean|-|false|Whether authentication details should be included on every request, or always inherited from the collection.|CONVERSION diff --git a/lib/options.js b/lib/options.js index d7b585669..ecad1487d 100644 --- a/lib/options.js +++ b/lib/options.js @@ -230,6 +230,16 @@ module.exports = { description: 'Whether to keep implicit headers from the OpenAPI specification, which are removed by default.', external: true, usage: ['CONVERSION'] + }, + { + name: 'Always inherit authentication', + id: 'alwaysInheritAuthentication', + type: 'boolean', + default: false, + description: 'Whether authentication details should be included on every request, or always inherited from ' + + 'the collection.', + external: true, + usage: ['CONVERSION'] } ]; diff --git a/lib/schemaUtils.js b/lib/schemaUtils.js index e8bfa061b..73cc2bd74 100644 --- a/lib/schemaUtils.js +++ b/lib/schemaUtils.js @@ -2321,7 +2321,12 @@ module.exports = { } // handling authentication here (for http type only) - authHelper = this.getAuthHelper(openapi, operation.security); + if (options.alwaysInheritAuthentication) { + authHelper = this.getAuthHelper(openapi, openapi.security); + } + else { + authHelper = this.getAuthHelper(openapi, operation.security); + } // creating the request object item = new sdk.Item({ @@ -2344,7 +2349,7 @@ module.exports = { thisAuthObject[authMap[authMeta.currentHelper]] = authMeta.helperAttributes; item.request.auth = new sdk.RequestAuth(thisAuthObject); } - else { + else if (!options.alwaysInheritAuthentication) { item.request.auth = authHelper; } diff --git a/test/data/valid_openapi/security-test-inheritance.yaml b/test/data/valid_openapi/security-test-inheritance.yaml new file mode 100644 index 000000000..191fd945a --- /dev/null +++ b/test/data/valid_openapi/security-test-inheritance.yaml @@ -0,0 +1,48 @@ +openapi: 3.0.0 +info: + title: "Reproduce Authorization issue" + version: 0.0.1 +security: + - MyAuth: [] + - BearerAuth: [] +paths: + /health: + get: + summary: "health" + description: "Health check - always returns OK" + operationId: "get_healthz" + security: + - BearerAuth: [] + responses: + '200': + description: "OK" + content: + text/plain: + schema: + type: "string" + default: "OK" + /status: + get: + summary: "status" + description: "Returns the service version" + operationId: "get_status" + security: + - MyAuth: [] + responses: + '200': + description: "Service info multi-line string" + content: + text/plain: + schema: + type: "string" +components: + securitySchemes: + BearerAuth: + type: http + scheme: bearer + bearerFormat: token + MyAuth: + type: apiKey + description: "This is my auth" + name: Mera-Auth + in: header \ No newline at end of file diff --git a/test/system/structure.test.js b/test/system/structure.test.js index 20699e779..1c42d0e65 100644 --- a/test/system/structure.test.js +++ b/test/system/structure.test.js @@ -23,7 +23,8 @@ const optionIds = [ 'optimizeConversion', 'strictRequestMatching', 'disableOptionalParameters', - 'keepImplicitHeaders' + 'keepImplicitHeaders', + 'alwaysInheritAuthentication' ], expectedOptions = { collapseFolders: { @@ -171,6 +172,15 @@ const optionIds = [ description: 'Whether to keep implicit headers from the OpenAPI specification, which are removed by default.', external: true, usage: ['CONVERSION'] + }, + alwaysInheritAuthentication: { + name: 'Always inherit authentication', + type: 'boolean', + default: false, + description: 'Whether authentication details should be included on every request, or always inherited from ' + + 'the collection.', + external: true, + usage: ['CONVERSION'] } }; diff --git a/test/unit/base.test.js b/test/unit/base.test.js index 92d36d55e..c974621e7 100644 --- a/test/unit/base.test.js +++ b/test/unit/base.test.js @@ -40,10 +40,38 @@ describe('CONVERT FUNCTION TESTS ', function() { tooManyRefs = path.join(__dirname, VALID_OPENAPI_PATH, '/too-many-refs.json'), tagsFolderSpec = path.join(__dirname, VALID_OPENAPI_PATH + '/petstore-detailed.yaml'), securityTestCases = path.join(__dirname, VALID_OPENAPI_PATH + '/security-test-cases.yaml'), + securityTestInheritance = path.join(__dirname, VALID_OPENAPI_PATH + '/security-test-inheritance.yaml'), emptySecurityTestCase = path.join(__dirname, VALID_OPENAPI_PATH + '/empty-security-test-case.yaml'), rootUrlServerWithVariables = path.join(__dirname, VALID_OPENAPI_PATH + '/root_url_server_with_variables.json'), parameterExamples = path.join(__dirname, VALID_OPENAPI_PATH + '/parameteres_with_examples.yaml'); + it('Should explicitly set auth when specified on a request ' + + securityTestInheritance, function(done) { + var openapi = fs.readFileSync(securityTestInheritance, 'utf8'); + Converter.convert({ type: 'string', data: openapi }, {}, (err, conversionResult) => { + + expect(err).to.be.null; + expect(conversionResult.output[0].data.auth.type).to.equal('apikey'); + expect(conversionResult.output[0].data.item[0].request.auth.type).to.equal('bearer'); + expect(conversionResult.output[0].data.item[1].request.auth.type).to.equal('apikey'); + done(); + }); + }); + + it('Should not explicitly set auth when specified on a request when passed alwaysInheritAuthentication ' + + securityTestInheritance, function(done) { + var openapi = fs.readFileSync(securityTestInheritance, 'utf8'); + Converter.convert( + { type: 'string', data: openapi }, + { alwaysInheritAuthentication: true }, (err, conversionResult) => { + + expect(err).to.be.null; + expect(conversionResult.output[0].data.auth.type).to.equal('apikey'); + expect(conversionResult.output[0].data.item[0].request.auth).to.be.undefined; + expect(conversionResult.output[0].data.item[1].request.auth).to.be.undefined; + done(); + }); + }); it('Should add collection level auth with type as `bearer`' + securityTestCases, function(done) {