Add swagger-ui auth hooks
Save authorization to local storage, refetch spec on auth, etc.
This commit is contained in:
@@ -33,7 +33,7 @@ SWAGGER_DEFAULTS = {
|
||||
|
||||
'USE_SESSION_AUTH': True,
|
||||
'SECURITY_DEFINITIONS': {
|
||||
'basic': {
|
||||
'Basic': {
|
||||
'type': 'basic'
|
||||
}
|
||||
},
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -1,27 +1,60 @@
|
||||
"use strict";
|
||||
var currentPath = window.location.protocol + "//" + window.location.host + window.location.pathname;
|
||||
var specURL = currentPath + '?format=openapi';
|
||||
var defaultSpecUrl = currentPath + '?format=openapi';
|
||||
var savedAuth = Immutable.fromJS({});
|
||||
try {
|
||||
savedAuth = Immutable.fromJS(JSON.parse(localStorage.getItem("drf-yasg-auth")) || {});
|
||||
} catch (e) {
|
||||
localStorage.removeItem("drf-yasg-auth");
|
||||
}
|
||||
var swaggerUiConfig = {
|
||||
url: defaultSpecUrl,
|
||||
dom_id: '#swagger-ui',
|
||||
displayRequestDuration: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout",
|
||||
filter: true,
|
||||
requestInterceptor: function (request) {
|
||||
var headers = request.headers || {};
|
||||
var csrftoken = document.querySelector("[name=csrfmiddlewaretoken]");
|
||||
if (csrftoken) {
|
||||
headers["X-CSRFToken"] = csrftoken.value;
|
||||
}
|
||||
|
||||
if (request.loadSpec) {
|
||||
applyAuth(savedAuth, headers);
|
||||
}
|
||||
return request;
|
||||
},
|
||||
onComplete: function () {
|
||||
preauthorizeAny(savedAuth, window.ui);
|
||||
hookAuthActions(window.ui);
|
||||
},
|
||||
};
|
||||
|
||||
function patchSwaggerUi() {
|
||||
if (document.querySelector('.auth-wrapper #django-session-auth')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var authWrapper = document.querySelector('.auth-wrapper');
|
||||
var authorizeButton = document.querySelector('.auth-wrapper .authorize');
|
||||
var djangoSessionAuth = document.querySelector('#django-session-auth');
|
||||
|
||||
if (!djangoSessionAuth) {
|
||||
console.log("WARNING: session auth disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
if (document.querySelector('.auth-wrapper #django-session-auth')) {
|
||||
console.log("WARNING: session auth already patched; skipping patchSwaggerUi()");
|
||||
return;
|
||||
}
|
||||
|
||||
djangoSessionAuth = djangoSessionAuth.cloneNode(true);
|
||||
authWrapper.insertBefore(djangoSessionAuth, authorizeButton);
|
||||
djangoSessionAuth.classList.remove("hidden");
|
||||
|
||||
var divider = document.createElement("div");
|
||||
divider.classList.add("divider");
|
||||
authWrapper.insertBefore(divider, authorizeButton);
|
||||
}
|
||||
|
||||
function initSwaggerUi() {
|
||||
@@ -29,28 +62,6 @@ function initSwaggerUi() {
|
||||
console.log("WARNING: skipping initSwaggerUi() because window.ui is already defined");
|
||||
return;
|
||||
}
|
||||
var swaggerConfig = {
|
||||
url: specURL,
|
||||
dom_id: '#swagger-ui',
|
||||
displayRequestDuration: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout",
|
||||
filter: true,
|
||||
requestInterceptor: function (request) {
|
||||
var headers = request.headers || {};
|
||||
var csrftoken = document.querySelector("[name=csrfmiddlewaretoken]");
|
||||
if (csrftoken) {
|
||||
headers["X-CSRFToken"] = csrftoken.value;
|
||||
}
|
||||
return request;
|
||||
}
|
||||
};
|
||||
|
||||
var swaggerSettings = JSON.parse(document.getElementById('swagger-settings').innerHTML);
|
||||
if (!('oauth2RedirectUrl' in swaggerSettings)) {
|
||||
@@ -64,23 +75,82 @@ function initSwaggerUi() {
|
||||
console.log('swaggerSettings', swaggerSettings);
|
||||
for (var p in swaggerSettings) {
|
||||
if (swaggerSettings.hasOwnProperty(p)) {
|
||||
swaggerConfig[p] = swaggerSettings[p];
|
||||
swaggerUiConfig[p] = swaggerSettings[p];
|
||||
}
|
||||
}
|
||||
window.ui = SwaggerUIBundle(swaggerConfig);
|
||||
|
||||
var oauth2Config = JSON.parse(document.getElementById('oauth2-config').innerHTML);
|
||||
console.log('oauth2Config', oauth2Config);
|
||||
window.ui = SwaggerUIBundle(swaggerUiConfig);
|
||||
window.ui.initOAuth(oauth2Config);
|
||||
}
|
||||
|
||||
window.onload = function () {
|
||||
initSwaggerUi();
|
||||
};
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (document.querySelector('.auth-wrapper .authorize')) {
|
||||
patchSwaggerUi();
|
||||
function applyAuth(savedAuth, requestHeaders) {
|
||||
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) {
|
||||
requestHeaders["Authorization"] = "Basic " + btoa(username + ":" + password);
|
||||
}
|
||||
} else if (schemeType === "apiKey" && schemeName) {
|
||||
var key = savedAuth.get("value"), _in = savedAuth.getIn(["schema", "in"]);
|
||||
var paramName = savedAuth.getIn(["schema", "name"]);
|
||||
if (key && paramName && _in === "header") {
|
||||
requestHeaders[paramName] = key;
|
||||
}
|
||||
if (_in === "query") {
|
||||
console.warn("WARNING: cannot apply apiKey query parameter via interceptor");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
insertionQ('.auth-wrapper .authorize').every(patchSwaggerUi);
|
||||
|
||||
function hookAuthActions(sui) {
|
||||
var originalAuthorize = sui.authActions.authorize;
|
||||
sui.authActions.authorize = function (authorization) {
|
||||
originalAuthorize(authorization);
|
||||
// authorization is map of scheme name to scheme object
|
||||
// need to use ImmutableJS because schema is already an ImmutableJS object
|
||||
var schemes = Immutable.fromJS(authorization);
|
||||
var auth = schemes.valueSeq().first();
|
||||
localStorage.setItem("drf-yasg-auth", JSON.stringify(auth.toJSON()));
|
||||
savedAuth = auth;
|
||||
sui.specActions.download();
|
||||
};
|
||||
|
||||
var originalLogout = sui.authActions.logout;
|
||||
sui.authActions.logout = function (authorization) {
|
||||
if (savedAuth.get("name") === authorization[0]) {
|
||||
localStorage.removeItem("drf-yasg-auth");
|
||||
savedAuth = Immutable.fromJS({});
|
||||
}
|
||||
originalLogout(authorization);
|
||||
};
|
||||
}
|
||||
|
||||
window.addEventListener('load', function () {
|
||||
initSwaggerUi();
|
||||
|
||||
if (document.querySelector('.auth-wrapper .authorize')) {
|
||||
patchSwaggerUi();
|
||||
}
|
||||
else {
|
||||
insertionQ('.auth-wrapper .authorize').every(patchSwaggerUi);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
<script src="{% static 'drf-yasg/swagger-ui-dist/swagger-ui-bundle.js' %}"></script>
|
||||
<script src="{% static 'drf-yasg/swagger-ui-dist/swagger-ui-standalone-preset.js' %}"></script>
|
||||
<script src="{% static 'drf-yasg/insQ.min.js' %}"></script>
|
||||
<script src="{% static 'drf-yasg/immutable.js' %}"></script>
|
||||
<script src="{% static 'drf-yasg/swagger-ui-init.js' %}"></script>
|
||||
{% block extra_scripts %}
|
||||
{# -- Add any additional scripts here -- #}
|
||||
|
||||
Reference in New Issue
Block a user