Support multiple auth schemes
parent
060fe1881a
commit
e1aedab73f
|
|
@ -114,7 +114,7 @@ function initSwaggerUiConfig(swaggerSettings, oauth2Settings) {
|
||||||
var oldOnComplete = swaggerUiConfig.onComplete;
|
var oldOnComplete = swaggerUiConfig.onComplete;
|
||||||
swaggerUiConfig.onComplete = function () {
|
swaggerUiConfig.onComplete = function () {
|
||||||
if (persistAuth) {
|
if (persistAuth) {
|
||||||
preauthorizeAny(savedAuth, window.ui);
|
preauthorizeAll(savedAuth, window.ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hookedAuth) {
|
if (!hookedAuth) {
|
||||||
|
|
@ -131,10 +131,7 @@ function initSwaggerUiConfig(swaggerSettings, oauth2Settings) {
|
||||||
swaggerUiConfig.requestInterceptor = function (request) {
|
swaggerUiConfig.requestInterceptor = function (request) {
|
||||||
var headers = request.headers || {};
|
var headers = request.headers || {};
|
||||||
if (refetchWithAuth && request.loadSpec) {
|
if (refetchWithAuth && request.loadSpec) {
|
||||||
var newUrl = applyAuth(savedAuth, request.url, headers) || request.url;
|
request.url = applyAuth(savedAuth, request.url, headers) || request.url;
|
||||||
if (newUrl !== request.url) {
|
|
||||||
request.url = newUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// need to manually remember requests for spec urls because
|
// need to manually remember requests for spec urls because
|
||||||
// responseInterceptor has no reference to the request...
|
// responseInterceptor has no reference to the request...
|
||||||
|
|
@ -150,7 +147,8 @@ function initSwaggerUiConfig(swaggerSettings, oauth2Settings) {
|
||||||
var oldResponseInterceptor = swaggerUiConfig.responseInterceptor;
|
var oldResponseInterceptor = swaggerUiConfig.responseInterceptor;
|
||||||
swaggerUiConfig.responseInterceptor = function (response) {
|
swaggerUiConfig.responseInterceptor = function (response) {
|
||||||
if (refetchWithAuth && specRequestsInFlight.indexOf(response.url) !== -1) {
|
if (refetchWithAuth && specRequestsInFlight.indexOf(response.url) !== -1) {
|
||||||
// need setTimeout here because swagger-ui insists to updateUrl with the initial request url...
|
// need setTimeout here because swagger-ui insists to call updateUrl
|
||||||
|
// with the initial request url after the response...
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
window.ui.specActions.updateUrl(response.url);
|
window.ui.specActions.updateUrl(response.url);
|
||||||
|
|
@ -169,27 +167,6 @@ function initSwaggerUiConfig(swaggerSettings, oauth2Settings) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Call sui.preauthorize### according to the type of savedAuth.
|
|
||||||
* @param savedAuth auth object saved from authActions.authorize
|
|
||||||
* @param sui SwaggerUI or SwaggerUIBundle instance
|
|
||||||
*/
|
|
||||||
function preauthorizeAny(savedAuth, sui) {
|
|
||||||
var schemeName = savedAuth.get("name"), schemeType = savedAuth.getIn(["schema", "type"]);
|
|
||||||
if (schemeType === "basic" && schemeName) {
|
|
||||||
var username = savedAuth.getIn(["value", "username"]);
|
|
||||||
var password = savedAuth.getIn(["value", "password"]);
|
|
||||||
if (username && password) {
|
|
||||||
sui.preauthorizeBasic(schemeName, username, password);
|
|
||||||
}
|
|
||||||
} else if (schemeType === "apiKey" && schemeName) {
|
|
||||||
var key = savedAuth.get("value");
|
|
||||||
if (key) {
|
|
||||||
sui.preauthorizeApiKey(schemeName, key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function _usp(url, fn) {
|
function _usp(url, fn) {
|
||||||
url = url.split('?');
|
url = url.split('?');
|
||||||
var usp = new URLSearchParams(url[1]);
|
var usp = new URLSearchParams(url[1]);
|
||||||
|
|
@ -210,56 +187,90 @@ function removeQueryParam(url, key) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call sui.preauthorize### for all authorizations in authorization.
|
||||||
|
* @param authorization authorization object {key => authScheme} saved from authActions.authorize
|
||||||
|
* @param sui SwaggerUI or SwaggerUIBundle instance
|
||||||
|
*/
|
||||||
|
function preauthorizeAll(authorization, sui) {
|
||||||
|
authorization.valueSeq().forEach(function (authScheme) {
|
||||||
|
var schemeName = authScheme.get("name"), schemeType = authScheme.getIn(["schema", "type"]);
|
||||||
|
if (schemeType === "basic" && schemeName) {
|
||||||
|
var username = authScheme.getIn(["value", "username"]);
|
||||||
|
var password = authScheme.getIn(["value", "password"]);
|
||||||
|
if (username && password) {
|
||||||
|
sui.preauthorizeBasic(schemeName, username, password);
|
||||||
|
}
|
||||||
|
} else if (schemeType === "apiKey" && schemeName) {
|
||||||
|
var key = authScheme.get("value");
|
||||||
|
if (key) {
|
||||||
|
sui.preauthorizeApiKey(schemeName, key);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// TODO: OAuth2
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manually apply auth headers from the given auth object.
|
* Manually apply auth headers from the given auth object.
|
||||||
* @param {object} authScheme auth object saved from authActions.authorize
|
* @param {object} authorization authorization object {key => authScheme} saved from authActions.authorize
|
||||||
* @param {string} requestUrl the request url
|
* @param {string} requestUrl the request url
|
||||||
* @param {object} requestHeaders target headers
|
* @param {object} requestHeaders target headers, modified in place by the function
|
||||||
* @return string new request url
|
* @return string new request url
|
||||||
*/
|
*/
|
||||||
function applyAuth(authScheme, requestUrl, requestHeaders) {
|
function applyAuth(authorization, requestUrl, requestHeaders) {
|
||||||
requestHeaders = requestHeaders || {};
|
authorization.valueSeq().forEach(function (authScheme) {
|
||||||
var schemeName = authScheme.get("name"), schemeType = authScheme.getIn(["schema", "type"]);
|
requestHeaders = requestHeaders || {};
|
||||||
if (schemeType === "basic" && schemeName) {
|
var schemeName = authScheme.get("name"), schemeType = authScheme.getIn(["schema", "type"]);
|
||||||
var username = authScheme.getIn(["value", "username"]);
|
if (schemeType === "basic" && schemeName) {
|
||||||
var password = authScheme.getIn(["value", "password"]);
|
var username = authScheme.getIn(["value", "username"]);
|
||||||
if (username && password) {
|
var password = authScheme.getIn(["value", "password"]);
|
||||||
requestHeaders["Authorization"] = "Basic " + btoa(username + ":" + password);
|
if (username && password) {
|
||||||
}
|
requestHeaders["Authorization"] = "Basic " + btoa(username + ":" + password);
|
||||||
} else if (schemeType === "apiKey" && schemeName) {
|
|
||||||
var _in = authScheme.getIn(["schema", "in"]), paramName = authScheme.getIn(["schema", "name"]);
|
|
||||||
var key = authScheme.get("value");
|
|
||||||
if (key && paramName) {
|
|
||||||
if (_in === "header") {
|
|
||||||
requestHeaders[paramName] = key;
|
|
||||||
}
|
}
|
||||||
if (_in === "query") {
|
} else if (schemeType === "apiKey" && schemeName) {
|
||||||
if (requestUrl) {
|
var _in = authScheme.getIn(["schema", "in"]), paramName = authScheme.getIn(["schema", "name"]);
|
||||||
requestUrl = addQueryParam(requestUrl, paramName, key);
|
var key = authScheme.get("value");
|
||||||
|
if (key && paramName) {
|
||||||
|
if (_in === "header") {
|
||||||
|
requestHeaders[paramName] = key;
|
||||||
}
|
}
|
||||||
else {
|
if (_in === "query") {
|
||||||
console.warn("WARNING: cannot apply apiKey query parameter via interceptor");
|
if (requestUrl) {
|
||||||
|
requestUrl = addQueryParam(requestUrl, paramName, key);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.warn("WARNING: cannot apply apiKey query parameter via interceptor");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// TODO: OAuth2
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
return requestUrl;
|
return requestUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the given authorization scheme from the url.
|
* Remove the given authorization scheme from the url.
|
||||||
* @param {object} authScheme
|
* @param {object} authorization authorization object {key => authScheme} containing schemes to deauthorize
|
||||||
* @param {string} requestUrl
|
* @param {string} requestUrl request url
|
||||||
|
* @return string new request url
|
||||||
*/
|
*/
|
||||||
function deauthUrl(authScheme, requestUrl) {
|
function deauthUrl(authorization, requestUrl) {
|
||||||
var schemeType = authScheme.getIn(["schema", "type"]);
|
authorization.valueSeq().forEach(function (authScheme) {
|
||||||
if (schemeType === "apiKey") {
|
var schemeType = authScheme.getIn(["schema", "type"]);
|
||||||
var _in = authScheme.getIn(["schema", "in"]), paramName = authScheme.getIn(["schema", "name"]);
|
if (schemeType === "apiKey") {
|
||||||
if (_in === "query" && requestUrl && paramName) {
|
var _in = authScheme.getIn(["schema", "in"]), paramName = authScheme.getIn(["schema", "name"]);
|
||||||
requestUrl = removeQueryParam(requestUrl, paramName);
|
if (_in === "query" && requestUrl && paramName) {
|
||||||
|
requestUrl = removeQueryParam(requestUrl, paramName);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// TODO: OAuth2?
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
return requestUrl;
|
return requestUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -282,34 +293,39 @@ function hookAuthActions(sui, persistAuth, refetchWithAuth, refetchOnLogout) {
|
||||||
originalAuthorize(authorization);
|
originalAuthorize(authorization);
|
||||||
// authorization is map of scheme name to scheme object
|
// authorization is map of scheme name to scheme object
|
||||||
// need to use ImmutableJS because schema is already an ImmutableJS object
|
// need to use ImmutableJS because schema is already an ImmutableJS object
|
||||||
var schemes = Immutable.fromJS(authorization);
|
var newAuths = Immutable.fromJS(authorization);
|
||||||
savedAuth = schemes.valueSeq().first();
|
savedAuth = savedAuth.merge(newAuths);
|
||||||
|
|
||||||
if (persistAuth) {
|
|
||||||
localStorage.setItem("drf-yasg-auth", JSON.stringify(savedAuth.toJSON()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (refetchWithAuth) {
|
if (refetchWithAuth) {
|
||||||
var url = sui.specSelectors.url();
|
var url = sui.specSelectors.url();
|
||||||
url = applyAuth(savedAuth, url) || url;
|
url = applyAuth(savedAuth, url) || url;
|
||||||
sui.specActions.download(url);
|
sui.specActions.download(url);
|
||||||
}
|
}
|
||||||
|
if (persistAuth) {
|
||||||
|
localStorage.setItem("drf-yasg-auth", JSON.stringify(savedAuth.toJSON()));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var originalLogout = sui.authActions.logout;
|
var originalLogout = sui.authActions.logout;
|
||||||
sui.authActions.logout = function (authorization) {
|
sui.authActions.logout = function (authorization) {
|
||||||
if (savedAuth.get("name") === authorization[0]) {
|
// stash logged out methods for use with deauthUrl
|
||||||
var oldAuth = savedAuth.set("value", null);
|
var loggedOut = savedAuth.filter(function (val, key) {
|
||||||
savedAuth = Immutable.fromJS({});
|
return authorization.indexOf(key) !== -1;
|
||||||
if (persistAuth) {
|
}).mapEntries(function (entry) {
|
||||||
localStorage.removeItem("drf-yasg-auth");
|
return [entry[0], entry[1].set("value", null)]
|
||||||
}
|
});
|
||||||
|
// remove logged out methods from savedAuth
|
||||||
|
savedAuth = savedAuth.filter(function (val, key) {
|
||||||
|
return authorization.indexOf(key) === -1;
|
||||||
|
});
|
||||||
|
|
||||||
if (refetchWithAuth) {
|
if (refetchWithAuth) {
|
||||||
var url = sui.specSelectors.url();
|
var url = sui.specSelectors.url();
|
||||||
url = deauthUrl(oldAuth, url) || url;
|
url = deauthUrl(loggedOut, url) || url;
|
||||||
sui.specActions.download(url);
|
sui.specActions.download(url);
|
||||||
}
|
}
|
||||||
|
if (persistAuth) {
|
||||||
|
localStorage.setItem("drf-yasg-auth", JSON.stringify(savedAuth.toJSON()));
|
||||||
}
|
}
|
||||||
originalLogout(authorization);
|
originalLogout(authorization);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue