Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions OPTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ allowUrlPathVarMatching|boolean|-|false|Whether to allow matching path variables
enableOptionalParameters|boolean|-|true|Optional parameters aren't selected in the collection. Once enabled they will be selected in the collection and request as well.|CONVERSION|v2, v1
keepImplicitHeaders|boolean|-|false|Whether to keep implicit headers from the OpenAPI specification, which are removed by default.|CONVERSION|v2, v1
includeDeprecated|boolean|-|true|Select whether to include deprecated operations, parameters, and properties in generated collection or not|CONVERSION, VALIDATION|v2, v1
alwaysInheritAuthentication|boolean|-|false|Whether authentication details should be included on every request, or always inherited from the collection.|CONVERSION|v2, v1
12 changes: 12 additions & 0 deletions lib/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,18 @@ module.exports = {
usage: ['CONVERSION', 'VALIDATION'],
supportedIn: [VERSION20, VERSION30, VERSION31],
supportedModuleVersion: [MODULE_VERSION.V2, MODULE_VERSION.V1]
},
{
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'],
supportedIn: [VERSION20, VERSION30, VERSION31],
supportedModuleVersion: [MODULE_VERSION.V2, MODULE_VERSION.V1]
}
];

Expand Down
6 changes: 4 additions & 2 deletions lib/schemaUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2647,7 +2647,9 @@ module.exports = {
}

// handling authentication here (for http type only)
authHelper = this.getAuthHelper(openapi, operation.security);
if (!options.alwaysInheritAuthentication) {
authHelper = this.getAuthHelper(openapi, operation.security);
}

// creating the request object
item = new sdk.Item({
Expand All @@ -2670,7 +2672,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;
}

Expand Down
5 changes: 3 additions & 2 deletions libV2/schemaUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -1866,7 +1866,8 @@ module.exports = {
requestBody = resolveRequestBodyForPostmanRequest(context, operationItem[method]),
request,
securitySchema = _.get(operationItem, [method, 'security']),
authHelper = generateAuthForCollectionFromOpenAPI(context.openapi, securitySchema);
authHelper = generateAuthForCollectionFromOpenAPI(context.openapi, securitySchema),
{ alwaysInheritAuthentication } = context.computedOptions;

headers.push(..._.get(requestBody, 'headers', []));
pathVariables.push(...baseUrlData.pathVariables);
Expand All @@ -1885,7 +1886,7 @@ module.exports = {
},
headers,
body: _.get(requestBody, 'body'),
auth: authHelper
auth: alwaysInheritAuthentication ? undefined : authHelper
};

const { responses, acceptHeader } = resolveResponseForPostmanRequest(context, operationItem[method], request);
Expand Down
48 changes: 48 additions & 0 deletions test/data/valid_openapi/security-test-inheritance.yaml
Original file line number Diff line number Diff line change
@@ -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
12 changes: 11 additions & 1 deletion test/system/structure.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ const optionIds = [
'includeReferenceMap',
'includeDeprecated',
'parametersResolution',
'disabledParametersValidation'
'disabledParametersValidation',
'alwaysInheritAuthentication'
],
expectedOptions = {
collapseFolders: {
Expand Down Expand Up @@ -222,6 +223,15 @@ const optionIds = [
description: 'Whether disabled parameters of collection should be validated',
external: false,
usage: ['VALIDATION']
},
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']
}
};

Expand Down
29 changes: 29 additions & 0 deletions test/unit/base.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ 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'),
Expand Down Expand Up @@ -97,6 +98,34 @@ describe('CONVERT FUNCTION TESTS ', function() {
path.join(__dirname, VALID_OPENAPI_PATH, '/recursiveRefComponents.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) {
var openapi = fs.readFileSync(securityTestCases, 'utf8'),
Expand Down
32 changes: 32 additions & 0 deletions test/unit/convertV2.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const expect = require('chai').expect,
issue193 = path.join(__dirname, VALID_OPENAPI_PATH, '/issue#193.yml'),
tooManyRefs = path.join(__dirname, VALID_OPENAPI_PATH, '/too_many_ref_example.json'),
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'),
Expand Down Expand Up @@ -94,6 +95,37 @@ const expect = require('chai').expect,

describe('The convert v2 Function', function() {

it('Should explicitly set auth when specified on a request ' +
securityTestInheritance, function(done) {
var openapi = fs.readFileSync(securityTestInheritance, 'utf8');
Converter.convertV2({ 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].item[0].request.auth.type).to.equal('apikey');
expect(conversionResult.output[0].data.item[1].item[0].request.auth.type).to.equal('bearer');
done();
});
});

it('Should not explicitly set auth when specified on a request when passed alwaysInheritAuthentication ' +
securityTestInheritance, function(done) {
const isEmptyArrayOrNull = (value) => {
return Array.isArray(value) && value.length === 0 || value === null;
};
var openapi = fs.readFileSync(securityTestInheritance, 'utf8');
Converter.convertV2(
{ 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].item[0].request.auth).to.satisfy(isEmptyArrayOrNull);
expect(conversionResult.output[0].data.item[1].item[0].request.auth).to.satisfy(isEmptyArrayOrNull);
done();
});
});

it('Should add collection level auth with type as `bearer`' +
securityTestCases, function(done) {
var openapi = fs.readFileSync(securityTestCases, 'utf8'),
Expand Down