Improve handling of spec request url

master
Cristi Vîjdea 2018-10-14 20:23:53 +03:00
parent e1aedab73f
commit 18ff51a025
3 changed files with 48 additions and 20 deletions

View File

@ -4,7 +4,7 @@ Customizing the web UI
The web UI can be customized using the settings available in :ref:`swagger-ui-settings` and :ref:`redoc-ui-settings`. The web UI can be customized using the settings available in :ref:`swagger-ui-settings` and :ref:`redoc-ui-settings`.
You can also extend one of the drf-yasg/swagger-ui.html_ or drf-yasg/redoc.html_ templates that are used for You can also extend one of the `drf-yasg/swagger-ui.html`_ or `drf-yasg/redoc.html`_ templates that are used for
rendering. See the template source code (linked above) for a complete list of customizable blocks. rendering. See the template source code (linked above) for a complete list of customizable blocks.
.. _drf-yasg/swagger-ui.html: https://github.com/axnsan12/drf-yasg/blob/master/src/drf_yasg/templates/drf-yasg/swagger-ui.html .. _drf-yasg/swagger-ui.html: https://github.com/axnsan12/drf-yasg/blob/master/src/drf_yasg/templates/drf-yasg/swagger-ui.html

View File

@ -226,7 +226,8 @@ PERSIST_AUTH
------------ ------------
Persist swagger-ui authorization data to local storage. |br| Persist swagger-ui authorization data to local storage. |br|
**WARNING:** this may be a security risk as the data is stored unencrypted **WARNING:** This may be a security risk as the credentials are stored unencrypted and can be accessed
by all javascript code running on the same domain.
**Default**: :python:`'False` |br| **Default**: :python:`'False` |br|
*Maps to parameter*: - *Maps to parameter*: -

View File

@ -126,16 +126,36 @@ function initSwaggerUiConfig(swaggerSettings, oauth2Settings) {
} }
}; };
var specRequestsInFlight = []; var specRequestsInFlight = {};
var oldRequestInterceptor = swaggerUiConfig.requestInterceptor; var oldRequestInterceptor = swaggerUiConfig.requestInterceptor;
swaggerUiConfig.requestInterceptor = function (request) { swaggerUiConfig.requestInterceptor = function (request) {
var headers = request.headers || {}; var headers = request.headers || {};
if (refetchWithAuth && request.loadSpec) { if (request.loadSpec) {
request.url = applyAuth(savedAuth, request.url, headers) || request.url; var newUrl = request.url;
// need to manually remember requests for spec urls because if (refetchWithAuth) {
// responseInterceptor has no reference to the request... newUrl = applyAuth(savedAuth, newUrl, headers) || newUrl;
specRequestsInFlight.push(request.url); }
if (newUrl !== request.url) {
request.url = newUrl;
if (window.ui) {
// this visually updates the spec url before the request is done, i.e. while loading
window.ui.specActions.updateUrl(request.url);
} else {
// setTimeout is needed here because the request interceptor can be called *during*
// window.ui initialization (by the SwaggerUIBundle constructor)
setTimeout(function () {
window.ui.specActions.updateUrl(request.url);
});
}
// need to manually remember requests for spec urls because
// responseInterceptor has no reference to the request...
var absUrl = new URL(request.url, currentPath);
specRequestsInFlight[absUrl.href] = request.url;
}
} }
if (oldRequestInterceptor) { if (oldRequestInterceptor) {
@ -146,17 +166,20 @@ 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) { var absUrl = new URL(response.url, currentPath);
// need setTimeout here because swagger-ui insists to call updateUrl if (absUrl.href in specRequestsInFlight) {
// with the initial request url after the response... var setToUrl = specRequestsInFlight[absUrl.href];
delete specRequestsInFlight[absUrl.href];
if (response.ok) { if (response.ok) {
// need setTimeout here because swagger-ui insists to call updateUrl
// with the initial request url after the response...
setTimeout(function () { setTimeout(function () {
window.ui.specActions.updateUrl(response.url); var currentUrl = new URL(window.ui.specSelectors.url(), currentPath);
if (currentUrl.href !== absUrl.href) {
window.ui.specActions.updateUrl(setToUrl);
}
}); });
} }
specRequestsInFlight = specRequestsInFlight.filter(function (val) {
return val !== response.url;
});
} }
if (oldResponseInterceptor) { if (oldResponseInterceptor) {
@ -172,13 +195,13 @@ function _usp(url, fn) {
var usp = new URLSearchParams(url[1]); var usp = new URLSearchParams(url[1]);
fn(usp); fn(usp);
url[1] = usp.toString(); url[1] = usp.toString();
return url.join('?'); return url[1] ? url.join('?') : url[0];
} }
function addQueryParam(url, key, value) { function setQueryParam(url, key, value) {
return _usp(url, function (usp) { return _usp(url, function (usp) {
usp.set(key, value); usp.set(key, value);
}) });
} }
function removeQueryParam(url, key) { function removeQueryParam(url, key) {
@ -238,7 +261,7 @@ function applyAuth(authorization, requestUrl, requestHeaders) {
} }
if (_in === "query") { if (_in === "query") {
if (requestUrl) { if (requestUrl) {
requestUrl = addQueryParam(requestUrl, paramName, key); requestUrl = setQueryParam(requestUrl, paramName, key);
} }
else { else {
console.warn("WARNING: cannot apply apiKey query parameter via interceptor"); console.warn("WARNING: cannot apply apiKey query parameter via interceptor");
@ -299,7 +322,9 @@ function hookAuthActions(sui, persistAuth, refetchWithAuth, refetchOnLogout) {
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.updateUrl(url);
sui.specActions.download();
sui.authActions.showDefinitions(); // hide authorize dialog
} }
if (persistAuth) { if (persistAuth) {
localStorage.setItem("drf-yasg-auth", JSON.stringify(savedAuth.toJSON())); localStorage.setItem("drf-yasg-auth", JSON.stringify(savedAuth.toJSON()));
@ -322,7 +347,9 @@ function hookAuthActions(sui, persistAuth, refetchWithAuth, refetchOnLogout) {
if (refetchWithAuth) { if (refetchWithAuth) {
var url = sui.specSelectors.url(); var url = sui.specSelectors.url();
url = deauthUrl(loggedOut, url) || url; url = deauthUrl(loggedOut, url) || url;
sui.specActions.updateUrl(url);
sui.specActions.download(url); sui.specActions.download(url);
sui.authActions.showDefinitions(); // hide authorize dialog
} }
if (persistAuth) { if (persistAuth) {
localStorage.setItem("drf-yasg-auth", JSON.stringify(savedAuth.toJSON())); localStorage.setItem("drf-yasg-auth", JSON.stringify(savedAuth.toJSON()));