From 1eb2840b3d7739f3fdb5a4a29bd5f8c008bc98a1 Mon Sep 17 00:00:00 2001 From: Johannes Tamm Date: Wed, 8 Sep 2021 18:17:54 +0300 Subject: [PATCH] feat: re-retch schema, when authorization is changed #7425 --- docker/configurator/variables.js | 6 ++- docs/usage/configuration.md | 1 + .../components/auth/authorization-popup.jsx | 4 +- src/core/components/auth/auths.jsx | 17 ++++++-- src/core/plugins/download-url.js | 39 +++++++++++++++++-- 5 files changed, 58 insertions(+), 9 deletions(-) diff --git a/docker/configurator/variables.js b/docker/configurator/variables.js index 8f4870eb281..805c063a0d5 100644 --- a/docker/configurator/variables.js +++ b/docker/configurator/variables.js @@ -102,7 +102,11 @@ const standardVariables = { WITH_CREDENTIALS: { type: "boolean", name: "withCredentials", - } + }, + RE_FETCH_SCHEMA_ON_AUTH_CHANGED: { + type: "boolean", + name: "reFetchSchemaOnAuthChanged", + }, } const legacyVariables = { diff --git a/docs/usage/configuration.md b/docs/usage/configuration.md index 17faa008e64..b4e2054650f 100644 --- a/docs/usage/configuration.md +++ b/docs/usage/configuration.md @@ -100,6 +100,7 @@ Parameter name | Docker variable | Description Parameter name | Docker variable | Description --- | --- | ----- `persistAuthorization` | `PERSIST_AUTHORIZATION` | `Boolean=false`. If set to `true`, it persists authorization data and it would not be lost on browser close/refresh +`reFetchSchemaOnAuthChanged` | `RE_FETCH_SCHEMA_ON_AUTH_CHANGED` | `Boolean=false`. If set to `true`, refresh to fetch schema, when authorization is changed ### Instance methods diff --git a/src/core/components/auth/authorization-popup.jsx b/src/core/components/auth/authorization-popup.jsx index 14406c877cc..eb35355062f 100644 --- a/src/core/components/auth/authorization-popup.jsx +++ b/src/core/components/auth/authorization-popup.jsx @@ -9,7 +9,7 @@ export default class AuthorizationPopup extends React.Component { } render() { - let { authSelectors, authActions, getComponent, errSelectors, specSelectors, fn: { AST = {} } } = this.props + let { authSelectors, authActions, getComponent, errSelectors, specSelectors, fn: { AST = {} }, specActions, getConfigs } = this.props let definitions = authSelectors.shownDefinitions() const Auths = getComponent("auths") @@ -38,6 +38,8 @@ export default class AuthorizationPopup extends React.Component { errSelectors={ errSelectors } authSelectors={ authSelectors } authActions={ authActions } + specActions={specActions} + getConfigs={getConfigs} specSelectors={ specSelectors }/> }) } diff --git a/src/core/components/auth/auths.jsx b/src/core/components/auth/auths.jsx index 62a9bd61e9d..0c84081cac4 100644 --- a/src/core/components/auth/auths.jsx +++ b/src/core/components/auth/auths.jsx @@ -26,14 +26,17 @@ export default class Auths extends React.Component { submitAuth =(e) => { e.preventDefault() - let { authActions } = this.props + let { authActions, getConfigs } = this.props authActions.authorizeWithPersistOption(this.state) + if(getConfigs().reFetchSchemaOnAuthChanged) { + this.props.specActions.download() + this.close(e) + } } logoutClick =(e) => { e.preventDefault() - - let { authActions, definitions } = this.props + let { authActions, definitions, getConfigs } = this.props let auths = definitions.map( (val, key) => { return key }).toArray() @@ -44,6 +47,10 @@ export default class Auths extends React.Component { }, {})) authActions.logoutWithPersistOption(auths) + if(getConfigs().reFetchSchemaOnAuthChanged) { + this.props.specActions.download() + this.close(e) + } } close =(e) => { @@ -125,6 +132,8 @@ export default class Auths extends React.Component { authSelectors: PropTypes.object.isRequired, specSelectors: PropTypes.object.isRequired, authActions: PropTypes.object.isRequired, - definitions: ImPropTypes.iterable.isRequired + definitions: ImPropTypes.iterable.isRequired, + specActions: ImPropTypes.iterable.isRequired, + getConfigs: ImPropTypes.iterable.isRequired, } } diff --git a/src/core/plugins/download-url.js b/src/core/plugins/download-url.js index 527cc03b24d..c0e0926759c 100644 --- a/src/core/plugins/download-url.js +++ b/src/core/plugins/download-url.js @@ -1,18 +1,21 @@ import { createSelector } from "reselect" import { Map } from "immutable" import win from "../window" +import { applySecurities as applySecurities3 } from "swagger-client/lib/execute/oas3/build-request" +import { applySecurities as applySecurities2 } from "swagger-client/lib/execute/swagger2/build-request" +import { isOAS3 } from "swagger-client/es/helpers" export default function downloadUrlPlugin (toolbox) { let { fn } = toolbox const actions = { - download: (url)=> ({ errActions, specSelectors, specActions, getConfigs }) => { + download: (url)=> ({ errActions, specSelectors, specActions, getConfigs, authSelectors}) => { let { fetch } = fn const config = getConfigs() url = url || specSelectors.url() specActions.updateLoadingStatus("loading") errActions.clear({source: "fetch"}) - fetch({ + let request = { url, loadSpec: true, requestInterceptor: config.requestInterceptor || (a => a), @@ -21,7 +24,37 @@ export default function downloadUrlPlugin (toolbox) { headers: { "Accept": "application/json,*/*" } - }).then(next,next) + } + if(config.reFetchSchemaOnAuthChanged) { + const spec = specSelectors.specJsonWithResolvedSubtrees().toJS() + if(spec) { + let securities = { + authorized: authSelectors.authorized() && authSelectors.authorized().toJS(), + definitions: specSelectors.securityDefinitions() && specSelectors.securityDefinitions().toJS(), + specSecurity: specSelectors.security() && specSelectors.security().toJS() + } + const operation = { + security: Object.keys(securities.authorized).map(key => ({[key]: []})) + }; + if(isOAS3(spec)) { + applySecurities3({ + request, + securities, + operation, + spec, + }) + } + else { + applySecurities2({ + request, + securities, + operation, + spec + }) + } + } + } + fetch(request).then(next,next) function next(res) { if(res instanceof Error || res.status >= 400) {