Add swagger-ui auth hooks

Save authorization to local storage, refetch spec on auth, etc.
This commit is contained in:
Cristi Vîjdea
2018-10-14 04:28:42 +03:00
parent d41f0c5ac4
commit a419eec071
9 changed files with 5103 additions and 52 deletions
+1 -1
View File
@@ -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
+111 -41
View File
@@ -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 -- #}