Skip to content

Commit 320a5d7

Browse files
minor bug fixes, optimizations, added test cases
1 parent 49131c5 commit 320a5d7

File tree

2 files changed

+163
-33
lines changed

2 files changed

+163
-33
lines changed

lib/schemaUtils.js

Lines changed: 25 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,14 +1115,16 @@ module.exports = {
11151115
}
11161116
}
11171117
else if (securityDef.type === 'oauth2') {
1118+
let flowObj, currentFlowType;
1119+
11181120
helper = {
11191121
type: 'oauth2',
11201122
oauth2: []
11211123
};
11221124

1123-
let flowObj, currentFlowType, flowCollectionIdentifier;
1124-
if (securityDef.flows) {
1125+
if (_.isObject(securityDef.flows) && FLOW_TYPE[Object.keys(securityDef.flows)[0]]) {
11251126
/*
1127+
11261128
//===================[]========================\\
11271129
|| OAuth2 Flow Name || Key name in collection ||
11281130
|]===================[]========================[|
@@ -1133,36 +1135,24 @@ module.exports = {
11331135
\\===================[]========================//
11341136
Ref : https://swagger.io/docs/specification/authentication/oauth2/
11351137
1138+
In case of multiple flow types, the first one will be preferred
1139+
and passed on to the collection.
11361140
1137-
Other flow types in collection
1141+
Other flow types in collection which are not explicitly present in OA 3
11381142
• "authorization_code_with_pkce"
11391143
11401144
*/
1141-
if (securityDef.flows.hasOwnProperty('clientCredentials')) {
1142-
currentFlowType = FLOW_TYPE.clientCredentials;
1143-
flowObj = _.get(securityDef, 'flows.clientCredentials');
1144-
}
1145-
else if (securityDef.flows.hasOwnProperty('authorizationCode')) {
1146-
currentFlowType = FLOW_TYPE.authorizationCode;
1147-
flowObj = _.get(securityDef, 'flows.authorizationCode');
1148-
}
1149-
else if (securityDef.flows.hasOwnProperty('password')) {
1150-
currentFlowType = FLOW_TYPE.password;
1151-
flowObj = _.get(securityDef, 'flows.password');
1152-
}
1153-
else if (securityDef.flows.hasOwnProperty('implicit')) {
1154-
currentFlowType = FLOW_TYPE.implicit;
1155-
flowObj = _.get(securityDef, 'flows.implicit');
1156-
}
1145+
currentFlowType = FLOW_TYPE[Object.keys(securityDef.flows)[0]];
1146+
flowObj = _.get(securityDef, `flows.${Object.keys(securityDef.flows)[0]}`);
11571147
}
11581148

11591149
if (currentFlowType) { // Means the flow is of supported type
11601150

11611151
// Fields supported by all flows -> refreshUrl, scopes
1162-
if (!_.isEmpty(flowObj.scope)) {
1152+
if (!_.isEmpty(flowObj.scopes)) {
11631153
helper.oauth2.push({
11641154
key: 'scope',
1165-
value: _.isString(flowObj.scopes) ? flowObj.scopes : ''
1155+
value: Object.keys(flowObj.scopes).join(' ')
11661156
});
11671157
}
11681158

@@ -1177,25 +1167,28 @@ module.exports = {
11771167

11781168
// Fields supported by all flows except implicit -> tokenUrl
11791169
if (currentFlowType !== FLOW_TYPE.implicit) {
1180-
helper.oauth2.push({
1181-
key: 'accessTokenUrl',
1182-
value: _.isString(flowObj.tokenUrl) ? flowObj.tokenUrl : '<Access Token URL>'
1183-
});
1170+
if (!_.isEmpty(flowObj.tokenUrl)) {
1171+
helper.oauth2.push({
1172+
key: 'accessTokenUrl',
1173+
value: _.isString(flowObj.tokenUrl) ? flowObj.tokenUrl : '<Access Token URL>'
1174+
});
1175+
}
11841176
}
11851177

11861178
// Fields supported by all flows all except password, clientCredentials -> authorizationUrl
11871179
if (currentFlowType !== FLOW_TYPE.password && currentFlowType !== FLOW_TYPE.clientCredentials) {
1188-
helper.oauth2.push({
1189-
key: 'authUrl',
1190-
value: _.isString(flowObj.authUrl) ? flowObj.authUrl : '<Auth URL>'
1191-
});
1180+
if (!_.isEmpty(flowObj.authorizationUrl)) {
1181+
helper.oauth2.push({
1182+
key: 'authUrl',
1183+
value: _.isString(flowObj.authorizationUrl) ? flowObj.authorizationUrl : '<Auth URL>'
1184+
});
1185+
}
11921186
}
11931187

1194-
flowCollectionIdentifier = {
1188+
helper.oauth2.push({
11951189
key: 'grant_type',
11961190
value: currentFlowType
1197-
};
1198-
helper.oauth2.push(flowCollectionIdentifier);
1191+
});
11991192
}
12001193
}
12011194
else if (securityDef.type === 'apiKey') {

test/unit/util.test.js

Lines changed: 138 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2959,7 +2959,7 @@ describe('findCommonSubpath method', function () {
29592959
});
29602960

29612961
describe('getAuthHelper method - OAuth2 Flows', function() {
2962-
it('Should parse OAuth2 configuration to collection', function() {
2962+
it('Should parse OAuth2 configuration to collection (Single Flow) - Type 1', function() {
29632963
const openAPISpec = {
29642964
'components': {
29652965
'responses': {},
@@ -3025,4 +3025,141 @@ describe('getAuthHelper method - OAuth2 Flows', function() {
30253025
]
30263026
});
30273027
});
3028+
3029+
it('Should parse OAuth2 configuration to collection (Multiple Flow types)- Type 2', function() {
3030+
const openAPISpec = {
3031+
components: {
3032+
responses: {},
3033+
schemas: {},
3034+
securitySchemes: {
3035+
oauth2: {
3036+
type: 'oauth2',
3037+
flows: {
3038+
implicit: {
3039+
authorizationUrl: 'https://example.com/api/oauth/dialog',
3040+
scopes: {
3041+
'write:pets': 'modify pets in your account',
3042+
'read:pets': 'read your pets'
3043+
}
3044+
},
3045+
authorizationCode: {
3046+
authorizationUrl: 'https://example.com/api/oauth/dialog',
3047+
tokenUrl: 'https://example.com/api/oauth/token',
3048+
scopes: {
3049+
'write:pets': 'modify pets in your account',
3050+
'read:pets': 'read your pets'
3051+
}
3052+
}
3053+
}
3054+
}
3055+
}
3056+
},
3057+
info: { title: 'API', version: '0.2' },
3058+
openapi: '3.0.0',
3059+
paths: {},
3060+
security: [{ oauth2: [] }],
3061+
servers: [{ url: 'https://myserver.com', variables: {} }],
3062+
tags: [],
3063+
securityDefs: {
3064+
oauth2: {
3065+
type: 'oauth2',
3066+
flows: {
3067+
implicit: {
3068+
authorizationUrl: 'https://example.com/api/oauth/dialog',
3069+
scopes: {
3070+
'write:pets': 'modify pets in your account',
3071+
'read:pets': 'read your pets'
3072+
}
3073+
},
3074+
authorizationCode: {
3075+
authorizationUrl: 'https://example.com/api/oauth/dialog',
3076+
tokenUrl: 'https://example.com/api/oauth/token',
3077+
scopes: {
3078+
'write:pets': 'modify pets in your account',
3079+
'read:pets': 'read your pets'
3080+
}
3081+
}
3082+
}
3083+
}
3084+
},
3085+
baseUrl: 'https://myserver.com',
3086+
baseUrlVariables: {}
3087+
},
3088+
securitySet = [{ oauth2: [] }],
3089+
helperData = SchemaUtils.getAuthHelper(openAPISpec, securitySet);
3090+
3091+
expect(helperData.type).to.be.equal('oauth2');
3092+
expect(helperData).to.have.property('oauth2').with.lengthOf(3);
3093+
expect(helperData.oauth2[0]).to.be.an('object');
3094+
expect(helperData).to.deep.equal({
3095+
'type': 'oauth2',
3096+
'oauth2': [
3097+
{
3098+
'key': 'scope',
3099+
'value': 'write:pets read:pets'
3100+
},
3101+
{
3102+
'key': 'authUrl',
3103+
'value': 'https://example.com/api/oauth/dialog'
3104+
},
3105+
{
3106+
'key': 'grant_type',
3107+
'value': 'implicit'
3108+
}
3109+
]
3110+
});
3111+
});
3112+
3113+
it('Scopes are parsed as sequence of strings', function() {
3114+
const openAPISpec = {
3115+
components: {
3116+
responses: {},
3117+
schemas: {},
3118+
securitySchemes: {
3119+
oauth2: {
3120+
type: 'oauth2',
3121+
flows: {
3122+
implicit: {
3123+
authorizationUrl: 'https://example.com/api/oauth/dialog',
3124+
scopes: {
3125+
'write:pets': 'modify pets in your account',
3126+
'read:pets': 'read your pets'
3127+
}
3128+
}
3129+
}
3130+
}
3131+
}
3132+
},
3133+
info: { title: 'API', version: '0.2' },
3134+
openapi: '3.0.0',
3135+
paths: {},
3136+
security: [{ oauth2: [] }],
3137+
servers: [{ url: 'https://myserver.com', variables: {} }],
3138+
tags: [],
3139+
securityDefs: {
3140+
oauth2: {
3141+
type: 'oauth2',
3142+
flows: {
3143+
implicit: {
3144+
authorizationUrl: 'https://example.com/api/oauth/dialog',
3145+
scopes: {
3146+
'write:pets': 'modify pets in your account',
3147+
'read:pets': 'read your pets'
3148+
}
3149+
}
3150+
}
3151+
}
3152+
},
3153+
baseUrl: 'https://myserver.com',
3154+
baseUrlVariables: {}
3155+
},
3156+
securitySet = [{ oauth2: [] }],
3157+
helperData = SchemaUtils.getAuthHelper(openAPISpec, securitySet);
3158+
3159+
expect(helperData.type).to.be.equal('oauth2');
3160+
expect(helperData).to.have.property('oauth2').with.lengthOf(3);
3161+
expect(helperData.oauth2[0]).to.be.an('object');
3162+
expect(helperData.oauth2[0].key).to.be.equal('scope');
3163+
expect(helperData.oauth2[0].value).to.be.equal('write:pets read:pets');
3164+
});
30283165
});

0 commit comments

Comments
 (0)