Skip to content

Commit 1817ac8

Browse files
committed
Merge branch 'TomDemeranville-clientCredentialFlowAndMultipleSchemes'
2 parents afe1b3d + 3135d23 commit 1817ac8

File tree

2 files changed

+132
-54
lines changed

2 files changed

+132
-54
lines changed

dist/lib/swagger-oauth.js

Lines changed: 66 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ var popupMask;
33
var popupDialog;
44
var clientId;
55
var realm;
6-
var oauth2KeyName;
76
var redirect_uri;
87
var clientSecret;
98
var scopeSeparator;
@@ -19,7 +18,6 @@ function handleLogin() {
1918
for(key in defs) {
2019
var auth = defs[key];
2120
if(auth.type === 'oauth2' && auth.scopes) {
22-
oauth2KeyName = key;
2321
var scope;
2422
if(Array.isArray(auth.scopes)) {
2523
// 1.2 support
@@ -31,7 +29,7 @@ function handleLogin() {
3129
else {
3230
// 2.0 support
3331
for(scope in auth.scopes) {
34-
scopes.push({scope: scope, description: auth.scopes[scope]});
32+
scopes.push({scope: scope, description: auth.scopes[scope], OAuthSchemeKey: key});
3533
}
3634
}
3735
}
@@ -61,12 +59,16 @@ function handleLogin() {
6159
'</div>'].join(''));
6260
$(document.body).append(popupDialog);
6361

62+
//TODO: only display applicable scopes (will need to pass them into handleLogin)
6463
popup = popupDialog.find('ul.api-popup-scopes').empty();
6564
for (i = 0; i < scopes.length; i ++) {
6665
scope = scopes[i];
67-
str = '<li><input type="checkbox" id="scope_' + i + '" scope="' + scope.scope + '"/>' + '<label for="scope_' + i + '">' + scope.scope;
66+
str = '<li><input type="checkbox" id="scope_' + i + '" scope="' + scope.scope + '"' +'" oauthtype="' + scope.OAuthSchemeKey +'"/>' + '<label for="scope_' + i + '">' + scope.scope ;
6867
if (scope.description) {
69-
str += '<br/><span class="api-scope-desc">' + scope.description + '</span>';
68+
if ($.map(auths, function(n, i) { return i; }).length > 1) //if we have more than one scheme, display schemes
69+
str += '<br/><span class="api-scope-desc">' + scope.description + ' ('+ scope.OAuthSchemeKey+')' +'</span>';
70+
else
71+
str += '<br/><span class="api-scope-desc">' + scope.description + '</span>';
7072
}
7173
str += '</label></li>';
7274
popup.append(str);
@@ -104,17 +106,40 @@ function handleLogin() {
104106
var defaultRedirectUrl = host.protocol + '//' + host.host + pathname + '/o2c.html';
105107
var redirectUrl = window.oAuthRedirectUrl || defaultRedirectUrl;
106108
var url = null;
107-
108-
for (var key in authSchemes) {
109-
if (authSchemes.hasOwnProperty(key)) {
109+
var scopes = []
110+
var o = popup.find('input:checked');
111+
var OAuthSchemeKeys = [];
112+
var state;
113+
for(k =0; k < o.length; k++) {
114+
var scope = $(o[k]).attr('scope');
115+
if (scopes.indexOf(scope) === -1)
116+
scopes.push(scope);
117+
var OAuthSchemeKey = $(o[k]).attr('oauthtype');
118+
if (OAuthSchemeKeys.indexOf(OAuthSchemeKey) === -1)
119+
OAuthSchemeKeys.push(OAuthSchemeKey);
120+
}
121+
122+
//TODO: merge not replace if scheme is different from any existing
123+
//(needs to be aware of schemes to do so correctly)
124+
window.enabledScopes=scopes;
125+
126+
for (var key in authSchemes) {
127+
if (authSchemes.hasOwnProperty(key) && OAuthSchemeKeys.indexOf(key) != -1) { //only look at keys that match this scope.
110128
var flow = authSchemes[key].flow;
111129

112130
if(authSchemes[key].type === 'oauth2' && flow && (flow === 'implicit' || flow === 'accessCode')) {
113131
var dets = authSchemes[key];
114132
url = dets.authorizationUrl + '?response_type=' + (flow === 'implicit' ? 'token' : 'code');
115133
window.swaggerUi.tokenName = dets.tokenName || 'access_token';
116134
window.swaggerUi.tokenUrl = (flow === 'accessCode' ? dets.tokenUrl : null);
135+
state = key;
117136
}
137+
else if(authSchemes[key].type === 'oauth2' && flow && (flow === 'application')) {
138+
var dets = authSchemes[key];
139+
window.swaggerUi.tokenName = dets.tokenName || 'access_token';
140+
clientCredentialsFlow(scopes, dets.tokenUrl, key);
141+
return;
142+
}
118143
else if(authSchemes[key].grantTypes) {
119144
// 1.2 support
120145
var o = authSchemes[key].grantTypes;
@@ -135,20 +160,6 @@ function handleLogin() {
135160
}
136161
}
137162
}
138-
var scopes = []
139-
var o = $('.api-popup-scopes').find('input:checked');
140-
141-
for(k =0; k < o.length; k++) {
142-
var scope = $(o[k]).attr('scope');
143-
144-
if (scopes.indexOf(scope) === -1)
145-
scopes.push(scope);
146-
}
147-
148-
// Implicit auth recommends a state parameter.
149-
var state = Math.random ();
150-
151-
window.enabledScopes=scopes;
152163

153164
redirect_uri = redirectUrl;
154165

@@ -213,7 +224,32 @@ function initOAuth(opts) {
213224
});
214225
}
215226

227+
function clientCredentialsFlow(scopes, tokenUrl, OAuthSchemeKey) {
228+
var params = {
229+
'client_id': clientId,
230+
'client_secret': clientSecret,
231+
'scope': scopes.join(' '),
232+
'grant_type': 'client_credentials'
233+
}
234+
$.ajax(
235+
{
236+
url : tokenUrl,
237+
type: "POST",
238+
data: params,
239+
success:function(data, textStatus, jqXHR)
240+
{
241+
onOAuthComplete(data,OAuthSchemeKey);
242+
},
243+
error: function(jqXHR, textStatus, errorThrown)
244+
{
245+
onOAuthComplete("");
246+
}
247+
});
248+
249+
}
250+
216251
window.processOAuthCode = function processOAuthCode(data) {
252+
var OAuthSchemeKey = data.state;
217253
var params = {
218254
'client_id': clientId,
219255
'code': data.code,
@@ -232,7 +268,7 @@ window.processOAuthCode = function processOAuthCode(data) {
232268
data: params,
233269
success:function(data, textStatus, jqXHR)
234270
{
235-
onOAuthComplete(data);
271+
onOAuthComplete(data, OAuthSchemeKey);
236272
},
237273
error: function(jqXHR, textStatus, errorThrown)
238274
{
@@ -241,7 +277,7 @@ window.processOAuthCode = function processOAuthCode(data) {
241277
});
242278
};
243279

244-
window.onOAuthComplete = function onOAuthComplete(token) {
280+
window.onOAuthComplete = function onOAuthComplete(token,OAuthSchemeKey) {
245281
if(token) {
246282
if(token.error) {
247283
var checkbox = $('input[type=checkbox],.secured')
@@ -251,11 +287,14 @@ window.onOAuthComplete = function onOAuthComplete(token) {
251287
alert(token.error);
252288
}
253289
else {
254-
var b = token[window.swaggerUi.tokenName];
290+
var b = token[window.swaggerUi.tokenName];
291+
if (!OAuthSchemeKey){
292+
OAuthSchemeKey = token.state;
293+
}
255294
if(b){
256295
// if all roles are satisfied
257296
var o = null;
258-
$.each($('.auth .api-ic .api_information_panel'), function(k, v) {
297+
$.each($('.auth .api-ic .api_information_panel'), function(k, v) {
259298
var children = v;
260299
if(children && children.childNodes) {
261300
var requiredScopes = [];
@@ -292,7 +331,7 @@ window.onOAuthComplete = function onOAuthComplete(token) {
292331
}
293332
}
294333
});
295-
window.swaggerUi.api.clientAuthorizations.add(oauth2KeyName, new SwaggerClient.ApiKeyAuthorization('Authorization', 'Bearer ' + b, 'header'));
334+
window.swaggerUi.api.clientAuthorizations.add(OAuthSchemeKey, new SwaggerClient.ApiKeyAuthorization('Authorization', 'Bearer ' + b, 'header'));
296335
}
297336
}
298337
}

lib/swagger-oauth.js

Lines changed: 66 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ var popupMask;
33
var popupDialog;
44
var clientId;
55
var realm;
6-
var oauth2KeyName;
76
var redirect_uri;
87
var clientSecret;
98
var scopeSeparator;
@@ -19,7 +18,6 @@ function handleLogin() {
1918
for(key in defs) {
2019
var auth = defs[key];
2120
if(auth.type === 'oauth2' && auth.scopes) {
22-
oauth2KeyName = key;
2321
var scope;
2422
if(Array.isArray(auth.scopes)) {
2523
// 1.2 support
@@ -31,7 +29,7 @@ function handleLogin() {
3129
else {
3230
// 2.0 support
3331
for(scope in auth.scopes) {
34-
scopes.push({scope: scope, description: auth.scopes[scope]});
32+
scopes.push({scope: scope, description: auth.scopes[scope], OAuthSchemeKey: key});
3533
}
3634
}
3735
}
@@ -61,12 +59,16 @@ function handleLogin() {
6159
'</div>'].join(''));
6260
$(document.body).append(popupDialog);
6361

62+
//TODO: only display applicable scopes (will need to pass them into handleLogin)
6463
popup = popupDialog.find('ul.api-popup-scopes').empty();
6564
for (i = 0; i < scopes.length; i ++) {
6665
scope = scopes[i];
67-
str = '<li><input type="checkbox" id="scope_' + i + '" scope="' + scope.scope + '"/>' + '<label for="scope_' + i + '">' + scope.scope;
66+
str = '<li><input type="checkbox" id="scope_' + i + '" scope="' + scope.scope + '"' +'" oauthtype="' + scope.OAuthSchemeKey +'"/>' + '<label for="scope_' + i + '">' + scope.scope ;
6867
if (scope.description) {
69-
str += '<br/><span class="api-scope-desc">' + scope.description + '</span>';
68+
if ($.map(auths, function(n, i) { return i; }).length > 1) //if we have more than one scheme, display schemes
69+
str += '<br/><span class="api-scope-desc">' + scope.description + ' ('+ scope.OAuthSchemeKey+')' +'</span>';
70+
else
71+
str += '<br/><span class="api-scope-desc">' + scope.description + '</span>';
7072
}
7173
str += '</label></li>';
7274
popup.append(str);
@@ -104,17 +106,40 @@ function handleLogin() {
104106
var defaultRedirectUrl = host.protocol + '//' + host.host + pathname + '/o2c.html';
105107
var redirectUrl = window.oAuthRedirectUrl || defaultRedirectUrl;
106108
var url = null;
107-
108-
for (var key in authSchemes) {
109-
if (authSchemes.hasOwnProperty(key)) {
109+
var scopes = []
110+
var o = popup.find('input:checked');
111+
var OAuthSchemeKeys = [];
112+
var state;
113+
for(k =0; k < o.length; k++) {
114+
var scope = $(o[k]).attr('scope');
115+
if (scopes.indexOf(scope) === -1)
116+
scopes.push(scope);
117+
var OAuthSchemeKey = $(o[k]).attr('oauthtype');
118+
if (OAuthSchemeKeys.indexOf(OAuthSchemeKey) === -1)
119+
OAuthSchemeKeys.push(OAuthSchemeKey);
120+
}
121+
122+
//TODO: merge not replace if scheme is different from any existing
123+
//(needs to be aware of schemes to do so correctly)
124+
window.enabledScopes=scopes;
125+
126+
for (var key in authSchemes) {
127+
if (authSchemes.hasOwnProperty(key) && OAuthSchemeKeys.indexOf(key) != -1) { //only look at keys that match this scope.
110128
var flow = authSchemes[key].flow;
111129

112130
if(authSchemes[key].type === 'oauth2' && flow && (flow === 'implicit' || flow === 'accessCode')) {
113131
var dets = authSchemes[key];
114132
url = dets.authorizationUrl + '?response_type=' + (flow === 'implicit' ? 'token' : 'code');
115133
window.swaggerUi.tokenName = dets.tokenName || 'access_token';
116134
window.swaggerUi.tokenUrl = (flow === 'accessCode' ? dets.tokenUrl : null);
135+
state = key;
117136
}
137+
else if(authSchemes[key].type === 'oauth2' && flow && (flow === 'application')) {
138+
var dets = authSchemes[key];
139+
window.swaggerUi.tokenName = dets.tokenName || 'access_token';
140+
clientCredentialsFlow(scopes, dets.tokenUrl, key);
141+
return;
142+
}
118143
else if(authSchemes[key].grantTypes) {
119144
// 1.2 support
120145
var o = authSchemes[key].grantTypes;
@@ -135,20 +160,6 @@ function handleLogin() {
135160
}
136161
}
137162
}
138-
var scopes = []
139-
var o = $('.api-popup-scopes').find('input:checked');
140-
141-
for(k =0; k < o.length; k++) {
142-
var scope = $(o[k]).attr('scope');
143-
144-
if (scopes.indexOf(scope) === -1)
145-
scopes.push(scope);
146-
}
147-
148-
// Implicit auth recommends a state parameter.
149-
var state = Math.random ();
150-
151-
window.enabledScopes=scopes;
152163

153164
redirect_uri = redirectUrl;
154165

@@ -213,7 +224,32 @@ function initOAuth(opts) {
213224
});
214225
}
215226

227+
function clientCredentialsFlow(scopes, tokenUrl, OAuthSchemeKey) {
228+
var params = {
229+
'client_id': clientId,
230+
'client_secret': clientSecret,
231+
'scope': scopes.join(' '),
232+
'grant_type': 'client_credentials'
233+
}
234+
$.ajax(
235+
{
236+
url : tokenUrl,
237+
type: "POST",
238+
data: params,
239+
success:function(data, textStatus, jqXHR)
240+
{
241+
onOAuthComplete(data,OAuthSchemeKey);
242+
},
243+
error: function(jqXHR, textStatus, errorThrown)
244+
{
245+
onOAuthComplete("");
246+
}
247+
});
248+
249+
}
250+
216251
window.processOAuthCode = function processOAuthCode(data) {
252+
var OAuthSchemeKey = data.state;
217253
var params = {
218254
'client_id': clientId,
219255
'code': data.code,
@@ -232,7 +268,7 @@ window.processOAuthCode = function processOAuthCode(data) {
232268
data: params,
233269
success:function(data, textStatus, jqXHR)
234270
{
235-
onOAuthComplete(data);
271+
onOAuthComplete(data, OAuthSchemeKey);
236272
},
237273
error: function(jqXHR, textStatus, errorThrown)
238274
{
@@ -241,7 +277,7 @@ window.processOAuthCode = function processOAuthCode(data) {
241277
});
242278
};
243279

244-
window.onOAuthComplete = function onOAuthComplete(token) {
280+
window.onOAuthComplete = function onOAuthComplete(token,OAuthSchemeKey) {
245281
if(token) {
246282
if(token.error) {
247283
var checkbox = $('input[type=checkbox],.secured')
@@ -251,11 +287,14 @@ window.onOAuthComplete = function onOAuthComplete(token) {
251287
alert(token.error);
252288
}
253289
else {
254-
var b = token[window.swaggerUi.tokenName];
290+
var b = token[window.swaggerUi.tokenName];
291+
if (!OAuthSchemeKey){
292+
OAuthSchemeKey = token.state;
293+
}
255294
if(b){
256295
// if all roles are satisfied
257296
var o = null;
258-
$.each($('.auth .api-ic .api_information_panel'), function(k, v) {
297+
$.each($('.auth .api-ic .api_information_panel'), function(k, v) {
259298
var children = v;
260299
if(children && children.childNodes) {
261300
var requiredScopes = [];
@@ -292,7 +331,7 @@ window.onOAuthComplete = function onOAuthComplete(token) {
292331
}
293332
}
294333
});
295-
window.swaggerUi.api.clientAuthorizations.add(oauth2KeyName, new SwaggerClient.ApiKeyAuthorization('Authorization', 'Bearer ' + b, 'header'));
334+
window.swaggerUi.api.clientAuthorizations.add(OAuthSchemeKey, new SwaggerClient.ApiKeyAuthorization('Authorization', 'Bearer ' + b, 'header'));
296335
}
297336
}
298337
}

0 commit comments

Comments
 (0)