Skip to content

Commit b5f9fb1

Browse files
VShingalaVishal Shingala
andauthored
Added support for Auth params in response/example. (#286)
* Added support for correct auth params in original request of response * Updated collection json schema to latest * Added tests for feature - response auth params support * Moved auth params in response behind an option * Updated option name and description to follow consistent casing * Updated option id for including auth params in response to be more suitable Co-authored-by: Vishal Shingala <vishalkumar.shingala@postman.com>
1 parent 70f3749 commit b5f9fb1

File tree

7 files changed

+310
-80
lines changed

7 files changed

+310
-80
lines changed

lib/options.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,15 @@ module.exports = {
116116
external: false,
117117
usage: ['CONVERSION']
118118
},
119+
{
120+
name: 'Include auth info in example requests',
121+
id: 'includeAuthInfoInExample',
122+
type: 'boolean',
123+
default: true,
124+
description: 'Select whether to include authentication parameters in the example request',
125+
external: true,
126+
usage: ['CONVERSION']
127+
},
119128
{
120129
name: 'Short error messages during request <> schema validation',
121130
id: 'shortValidationErrors',

lib/schemaUtils.js

Lines changed: 162 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,13 +1007,45 @@ module.exports = {
10071007

10081008
securitySet.forEach((security) => {
10091009
securityDef = openapi.securityDefs[Object.keys(security)[0]];
1010-
if (!securityDef) {
1011-
return false;
1010+
if (!_.isObject(securityDef)) {
1011+
return;
10121012
}
10131013
else if (securityDef.type === 'http') {
1014-
helper = {
1015-
type: securityDef.scheme
1016-
};
1014+
if (_.toLower(securityDef.scheme) === 'basic') {
1015+
helper = {
1016+
type: 'basic',
1017+
basic: [
1018+
{ key: 'username', value: '<Basic Auth Username>' },
1019+
{ key: 'password', value: '<Basic Auth Password>' }
1020+
]
1021+
};
1022+
}
1023+
else if (_.toLower(securityDef.scheme) === 'bearer') {
1024+
helper = {
1025+
type: 'bearer',
1026+
bearer: [{ key: 'token', value: '<Bearer Token>' }]
1027+
};
1028+
}
1029+
else if (_.toLower(securityDef.scheme) === 'digest') {
1030+
helper = {
1031+
type: 'digest',
1032+
digest: [
1033+
{ key: 'username', value: '<Digest Auth Username>' },
1034+
{ key: 'password', value: '<Digest Auth Password>' },
1035+
{ key: 'realm', value: '<realm>' }
1036+
]
1037+
};
1038+
}
1039+
else if (_.toLower(securityDef.scheme) === 'oauth' || _.toLower(securityDef.scheme) === 'oauth1') {
1040+
helper = {
1041+
type: 'oauth1',
1042+
oauth1: [
1043+
{ key: 'consumerSecret', value: '<OAuth 1.0 Consumer Key>' },
1044+
{ key: 'consumerKey', value: '<OAuth 1.0 Consumer Secret>' },
1045+
{ key: 'addParamsToHeader', value: true }
1046+
]
1047+
};
1048+
}
10171049
}
10181050
else if (securityDef.type === 'oauth2') {
10191051
helper = {
@@ -1022,15 +1054,103 @@ module.exports = {
10221054
}
10231055
else if (securityDef.type === 'apiKey') {
10241056
helper = {
1025-
type: 'api-key',
1026-
properties: securityDef
1057+
type: 'apikey',
1058+
apikey: [
1059+
{
1060+
key: 'key',
1061+
value: _.isString(securityDef.name) ? securityDef.name : '<API Key Name>'
1062+
},
1063+
{ key: 'value', value: true },
1064+
{
1065+
key: 'in',
1066+
value: _.includes(['query', 'header'], securityDef.in) ? securityDef.in : 'header'
1067+
}
1068+
]
10271069
};
10281070
}
1029-
return false;
1071+
1072+
// stop searching for helper if valid auth scheme is found
1073+
if (!_.isEmpty(helper)) {
1074+
return false;
1075+
}
10301076
});
10311077
return helper;
10321078
},
10331079

1080+
/**
1081+
* Generates Auth helper for response, params (query, headers) in helper object is added in
1082+
* request (originalRequest) part of example.
1083+
*
1084+
* @param {*} requestAuthHelper - Auth helper object of corresponding request
1085+
* @returns {Object} - Response Auth helper object containing params to be added
1086+
*/
1087+
getResponseAuthHelper: function (requestAuthHelper) {
1088+
var responseAuthHelper = {
1089+
query: [],
1090+
header: []
1091+
},
1092+
getValueFromHelper = function (authParams, keyName) {
1093+
return _.find(authParams, { key: keyName }).value;
1094+
},
1095+
paramLocation,
1096+
description;
1097+
1098+
if (!_.isObject(requestAuthHelper)) {
1099+
return responseAuthHelper;
1100+
}
1101+
description = 'Added as a part of security scheme: ' + requestAuthHelper.type;
1102+
1103+
switch (requestAuthHelper.type) {
1104+
case 'apikey':
1105+
// find location of parameter from auth helper
1106+
paramLocation = getValueFromHelper(requestAuthHelper.apikey, 'in');
1107+
responseAuthHelper[paramLocation].push({
1108+
key: getValueFromHelper(requestAuthHelper.apikey, 'key'),
1109+
value: '<API Key>',
1110+
description
1111+
});
1112+
break;
1113+
case 'basic':
1114+
responseAuthHelper.header.push({
1115+
key: 'Authorization',
1116+
value: 'Basic <credentials>',
1117+
description
1118+
});
1119+
break;
1120+
case 'bearer':
1121+
responseAuthHelper.header.push({
1122+
key: 'Authorization',
1123+
value: 'Bearer <token>',
1124+
description
1125+
});
1126+
break;
1127+
case 'digest':
1128+
responseAuthHelper.header.push({
1129+
key: 'Authorization',
1130+
value: 'Digest <credentials>',
1131+
description
1132+
});
1133+
break;
1134+
case 'oauth1':
1135+
responseAuthHelper.header.push({
1136+
key: 'Authorization',
1137+
value: 'OAuth <credentials>',
1138+
description
1139+
});
1140+
break;
1141+
case 'oauth2':
1142+
responseAuthHelper.header.push({
1143+
key: 'Authorization',
1144+
value: '<token>',
1145+
description
1146+
});
1147+
break;
1148+
default:
1149+
break;
1150+
}
1151+
return responseAuthHelper;
1152+
},
1153+
10341154
/**
10351155
* Converts a 'content' object into Postman response body. Any content-type header determined
10361156
* from the body is returned as well
@@ -2077,25 +2197,6 @@ module.exports = {
20772197
thisAuthObject[authMap[authMeta.currentHelper]] = authMeta.helperAttributes;
20782198
item.request.auth = new sdk.RequestAuth(thisAuthObject);
20792199
}
2080-
// TODO: Figure out what happens if type!=api-key
2081-
else if (authHelper && authHelper.type === 'api-key') {
2082-
if (authHelper.properties.in === 'header') {
2083-
item.request.addHeader(this.convertToPmHeader(authHelper.properties,
2084-
REQUEST_TYPE.ROOT, PARAMETER_SOURCE.REQUEST, components, options, schemaCache));
2085-
item.request.auth = {
2086-
type: 'noauth'
2087-
};
2088-
}
2089-
else if (authHelper.properties.in === 'query') {
2090-
this.convertToPmQueryParameters(authHelper.properties, REQUEST_TYPE.ROOT,
2091-
components, options, schemaCache).forEach((pmParam) => {
2092-
item.request.url.addQueryParams(pmParam);
2093-
});
2094-
item.request.auth = {
2095-
type: 'noauth'
2096-
};
2097-
}
2098-
}
20992200
else {
21002201
item.request.auth = authHelper;
21012202
}
@@ -2162,27 +2263,57 @@ module.exports = {
21622263
// adding responses to request item
21632264
if (operation.responses) {
21642265
let thisOriginalRequest = {},
2266+
responseAuthHelper,
2267+
authQueryParams,
21652268
convertedResponse;
2269+
2270+
if (options.includeAuthInfoInExample) {
2271+
responseAuthHelper = this.getResponseAuthHelper(authHelper);
2272+
2273+
// override auth helper with global security definition if no operation security definition found
2274+
if (_.isEmpty(authHelper)) {
2275+
responseAuthHelper = this.getResponseAuthHelper(this.getAuthHelper(openapi, openapi.security));
2276+
}
2277+
2278+
authQueryParams = _.map(responseAuthHelper.query, (queryParam) => {
2279+
// key-value pair will be added as transformed query string
2280+
return queryParam.key + '=' + queryParam.value;
2281+
});
2282+
}
2283+
21662284
_.forOwn(operation.responses, (response, code) => {
2167-
let originalRequestHeaders = [];
2285+
let originalRequestHeaders = [],
2286+
originalRequestQueryParams = this.convertToPmQueryArray(reqParams, REQUEST_TYPE.EXAMPLE,
2287+
components, options, schemaCache);
2288+
21682289
swagResponse = response;
21692290
if (response.$ref) {
21702291
swagResponse = this.getRefObject(response.$ref, components, options);
21712292
}
21722293

2294+
if (options.includeAuthInfoInExample) {
2295+
// add Authorization params if present
2296+
originalRequestQueryParams = _.concat(originalRequestQueryParams, authQueryParams);
2297+
originalRequestHeaders = _.concat(originalRequestHeaders, responseAuthHelper.header);
2298+
}
2299+
21732300
// Try and set fields for originalRequest (example.request)
21742301
thisOriginalRequest.method = item.request.method;
21752302
// setting URL
21762303
thisOriginalRequest.url = displayUrl;
2304+
21772305
// setting query params
2178-
thisOriginalRequest.url += '?';
2179-
thisOriginalRequest.url += this.convertToPmQueryArray(reqParams, REQUEST_TYPE.EXAMPLE, components,
2180-
options, schemaCache).join('&');
2306+
if (originalRequestQueryParams.length) {
2307+
thisOriginalRequest.url += '?';
2308+
thisOriginalRequest.url += originalRequestQueryParams.join('&');
2309+
}
2310+
21812311
// setting headers
21822312
_.forEach(reqParams.header, (header) => {
21832313
originalRequestHeaders.push(this.convertToPmHeader(header, REQUEST_TYPE.EXAMPLE,
21842314
PARAMETER_SOURCE.REQUEST, components, options, schemaCache));
21852315
});
2316+
21862317
thisOriginalRequest.header = originalRequestHeaders;
21872318
// setting request body
21882319
try {

lib/schemapack.js

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -266,15 +266,6 @@ class SchemaPack {
266266
if (openapi.security) {
267267
authHelper = schemaUtils.getAuthHelper(openapi, openapi.security);
268268
if (authHelper) {
269-
if (authHelper.type === 'api-key') {
270-
// if authHelper has type apikey and has properties in header or query
271-
// we override authHelper to 'noauth'
272-
if (authHelper.properties.in === 'header' || authHelper.properties.in === 'query') {
273-
authHelper = {
274-
type: 'noauth'
275-
};
276-
}
277-
}
278269
generatedStore.collection.auth = authHelper;
279270
}
280271
}

0 commit comments

Comments
 (0)