Skip to content
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

Added alwaysInheritAuthentication option to v2 #728

Merged
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 3 additions & 1 deletion 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 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