feat(auth): Add OIDC support (#3517) (#6549)

spec/actions.js: Add OIDC metadata fetching

components/auth/oauth2: Add OIDC URL to the Authorization popup
This commit is contained in:
Ilya Lipnitskiy
2020-12-09 10:11:33 -08:00
committed by GitHub
parent 20a89877b2
commit 0807687f91
5 changed files with 186 additions and 6 deletions

View File

@@ -8,10 +8,13 @@ import { isOAS3 as isOAS3Helper } from "../helpers"
const state = state => state
function onlyOAS3(selector) {
return (ori, system) => (state, ...args) => {
return (ori, system) => (...args) => {
const spec = system.getSystem().specSelectors.specJson()
if(isOAS3Helper(spec)) {
return selector(system, ...args)
// Pass the spec plugin state to Reselect to trigger on securityDefinitions update
let resolvedSchemes = system.getState().getIn(["spec", "resolvedSubtrees",
"components", "securitySchemes"])
return selector(system, resolvedSchemes, ...args)
} else {
return ori(...args)
}
@@ -57,6 +60,32 @@ export const definitionsToAuthorize = onlyOAS3(createSelector(
[defName]: definition
}))
}
if(type === "openIdConnect" && definition.get("openIdConnectData")) {
let oidcData = definition.get("openIdConnectData")
let grants = oidcData.get("grant_types_supported") || ["authorization_code", "implicit"]
grants.forEach((grant) => {
// Convert from OIDC list of scopes to the OAS-style map with empty descriptions
let translatedScopes = oidcData.get("scopes_supported") &&
oidcData.get("scopes_supported").reduce((acc, cur) => acc.set(cur, ""), new Map())
let translatedDef = fromJS({
flow: grant,
authorizationUrl: oidcData.get("authorization_endpoint"),
tokenUrl: oidcData.get("token_endpoint"),
scopes: translatedScopes,
type: "oauth2",
openIdConnectUrl: definition.get("openIdConnectUrl")
})
list = list.push(new Map({
[defName]: translatedDef.filter((v) => {
// filter out unset values, sometimes `authorizationUrl`
// and `tokenUrl` come out as `undefined` in the data
return v !== undefined
})
}))
})
}
})
return list

View File

@@ -150,6 +150,7 @@ const debResolveSubtrees = debounce(async () => {
errSelectors,
fn: {
resolveSubtree,
fetch,
AST = {}
},
specSelectors,
@@ -206,6 +207,28 @@ const debResolveSubtrees = debounce(async () => {
errActions.newThrownErrBatch(preparedErrors)
}
if (spec && specSelectors.isOAS3() && path[0] === "components" && path[1] === "securitySchemes") {
// Resolve OIDC URLs if present
await Promise.all(Object.values(spec)
.filter((scheme) => scheme.type === "openIdConnect")
.map(async (oidcScheme) => {
const req = {
url: oidcScheme.openIdConnectUrl,
requestInterceptor: requestInterceptor,
responseInterceptor: responseInterceptor
}
try {
const res = await fetch(req)
if (res instanceof Error || res.status >= 400) {
console.error(res.statusText + " " + req.url)
} else {
oidcScheme.openIdConnectData = JSON.parse(res.text)
}
} catch (e) {
console.error(e)
}
}))
}
set(resultMap, path, spec)
set(specWithCurrentSubtrees, path, spec)