Skip to content

Commit

Permalink
fix: provide fixes for mutualTLS (#9195)
Browse files Browse the repository at this point in the history
  • Loading branch information
char0n authored Sep 6, 2023
1 parent 88b8345 commit b35fd47
Show file tree
Hide file tree
Showing 6 changed files with 244 additions and 152 deletions.
103 changes: 59 additions & 44 deletions src/core/plugins/oas31/auth-extensions/wrap-selectors.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/**
* @prettier
*/

import { fromJS, Map, List } from "immutable"
import { createOnlyOAS31SelectorWrapper } from "../fn"

Expand All @@ -12,73 +11,89 @@ export const selectLicenseUrl = createOnlyOAS31SelectorWrapper(
)

export const definitionsToAuthorize = createOnlyOAS31SelectorWrapper(
() => (oriSelector, system) => {
() => (oriSelector, system) => {
const definitions = system.getSystem().specSelectors.securityDefinitions()
let list = List()

if(!definitions) {
return list
}
if (!definitions) {
return list
}

definitions.entrySeq().forEach( ([ defName, definition ]) => {
const type = definition.get("type")
if(type === "oauth2") {
definition.get("flows").entrySeq().forEach(([flowKey, flowVal]) => {
definitions.entrySeq().forEach(([defName, definition]) => {
const type = definition.get("type")
if (type === "oauth2") {
definition
.get("flows")
.entrySeq()
.forEach(([flowKey, flowVal]) => {
let translatedDef = fromJS({
flow: flowKey,
authorizationUrl: flowVal.get("authorizationUrl"),
tokenUrl: flowVal.get("tokenUrl"),
scopes: flowVal.get("scopes"),
type: definition.get("type"),
description: definition.get("description")
description: definition.get("description"),
})
const w1 = new Map({
[defName]: translatedDef.filter((v) => {
// filter out unset values, sometimes `authorizationUrl`
// and `tokenUrl` come out as `undefined` in the data
return v !== undefined
})
}),
})
list = list.push(w1)
})
}
if(type === "http" || type === "apiKey") {
list = list.push(new Map({
[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())
}
if (type === "http" || type === "apiKey") {
list = list.push(
new Map({
[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")
})
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({
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
})
}))
}),
})
)
})
}

if (type === "mutualTLS") {
list = list.push(
new Map({
[defName]: definition,
})
}

if(type === "mutualTLS") {
list = list.push(new Map({
[defName]: definition
}))
}
})
return list
)
}
})
return list
}
)
189 changes: 114 additions & 75 deletions src/core/plugins/oas31/components/auths.jsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
/**
* @prettier
*/
import React from "react"
import PropTypes from "prop-types"
import ImPropTypes from "react-immutable-proptypes"

export default class Auths extends React.Component {
class Auths extends React.Component {
static propTypes = {
definitions: ImPropTypes.iterable.isRequired,
getComponent: PropTypes.func.isRequired,
authSelectors: PropTypes.object.isRequired,
authActions: PropTypes.object.isRequired,
errSelectors: PropTypes.object.isRequired,
specSelectors: PropTypes.object.isRequired
specSelectors: PropTypes.object.isRequired,
}

constructor(props, context) {
Expand All @@ -24,30 +27,34 @@ export default class Auths extends React.Component {
this.setState({ [name]: auth })
}

submitAuth =(e) => {
submitAuth = (e) => {
e.preventDefault()

let { authActions } = this.props
authActions.authorizeWithPersistOption(this.state)
}

logoutClick =(e) => {
logoutClick = (e) => {
e.preventDefault()

let { authActions, definitions } = this.props
let auths = definitions.map( (val, key) => {
return key
}).toArray()

this.setState(auths.reduce((prev, auth) => {
prev[auth] = ""
return prev
}, {}))
let auths = definitions
.map((val, key) => {
return key
})
.toArray()

this.setState(
auths.reduce((prev, auth) => {
prev[auth] = ""
return prev
}, {})
)

authActions.logoutWithPersistOption(auths)
}

close =(e) => {
close = (e) => {
e.preventDefault()
let { authActions } = this.props

Expand All @@ -59,83 +66,115 @@ export default class Auths extends React.Component {
const AuthItem = getComponent("AuthItem")
const Oauth2 = getComponent("oauth2", true)
const Button = getComponent("Button")
let authorized = authSelectors.authorized()

let authorizedAuth = definitions.filter( (definition, key) => {
const authorized = authSelectors.authorized()
const authorizedAuth = definitions.filter((definition, key) => {
return !!authorized.get(key)
})

let nonOauthDefinitions = definitions.filter( schema => schema.get("type") !== "oauth2" && schema.get("type") !== "mutualTLS")
let oauthDefinitions = definitions.filter( schema => schema.get("type") === "oauth2")
let mutualTLSDefinitions = definitions.filter( schema => schema.get("type") === "mutualTLS")
const nonOauthDefinitions = definitions.filter(
(schema) =>
schema.get("type") !== "oauth2" && schema.get("type") !== "mutualTLS"
)
const oauthDefinitions = definitions.filter(
(schema) => schema.get("type") === "oauth2"
)
const mutualTLSDefinitions = definitions.filter(
(schema) => schema.get("type") === "mutualTLS"
)

return (
<div className="auth-container">
{
!!nonOauthDefinitions.size && <form onSubmit={ this.submitAuth }>
{
nonOauthDefinitions.map( (schema, name) => {
return <AuthItem
key={name}
schema={schema}
name={name}
getComponent={getComponent}
onAuthChange={this.onAuthChange}
authorized={authorized}
errSelectors={errSelectors}
{nonOauthDefinitions.size > 0 && (
<form onSubmit={this.submitAuth}>
{nonOauthDefinitions
.map((schema, name) => {
return (
<AuthItem
key={name}
schema={schema}
name={name}
getComponent={getComponent}
onAuthChange={this.onAuthChange}
authorized={authorized}
errSelectors={errSelectors}
/>
}).toArray()
}
)
})
.toArray()}
<div className="auth-btn-wrapper">
{
nonOauthDefinitions.size === authorizedAuth.size ? <Button className="btn modal-btn auth" onClick={ this.logoutClick }>Logout</Button>
: <Button type="submit" className="btn modal-btn auth authorize">Authorize</Button>
}
<Button className="btn modal-btn auth btn-done" onClick={ this.close }>Close</Button>
{nonOauthDefinitions.size === authorizedAuth.size ? (
<Button
className="btn modal-btn auth"
onClick={this.logoutClick}
>
Logout
</Button>
) : (
<Button type="submit" className="btn modal-btn auth authorize">
Authorize
</Button>
)}
<Button
className="btn modal-btn auth btn-done"
onClick={this.close}
>
Close
</Button>
</div>
</form>
}

{
oauthDefinitions && oauthDefinitions.size ? <div>
<div className="scope-def">
<p>Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.</p>
<p>API requires the following scopes. Select which ones you want to grant to Swagger UI.</p>
)}

{oauthDefinitions.size > 0 ? (
<div>
<div className="scope-def">
<p>
Scopes are used to grant an application different levels of
access to data on behalf of the end user. Each API may declare
one or more scopes.
</p>
<p>
API requires the following scopes. Select which ones you want to
grant to Swagger UI.
</p>
</div>
{definitions
.filter((schema) => schema.get("type") === "oauth2")
.map((schema, name) => {
return (
<div key={name}>
<Oauth2
authorized={authorized}
schema={schema}
name={name}
/>
</div>
)
})
.toArray()}
</div>
{
definitions.filter( schema => schema.get("type") === "oauth2")
.map( (schema, name) =>{
return (<div key={ name }>
<Oauth2 authorized={ authorized }
schema={ schema }
name={ name } />
</div>)
}
).toArray()
}
</div> : null
}
{
!!mutualTLSDefinitions.size && <div>
{
mutualTLSDefinitions.map( (schema, name) => {
return <AuthItem
key={name}
schema={schema}
name={name}
getComponent={getComponent}
onAuthChange={this.onAuthChange}
authorized={authorized}
errSelectors={errSelectors}
) : null}
{mutualTLSDefinitions.size > 0 && (
<div>
{mutualTLSDefinitions
.map((schema, name) => {
return (
<AuthItem
key={name}
schema={schema}
name={name}
getComponent={getComponent}
onAuthChange={this.onAuthChange}
authorized={authorized}
errSelectors={errSelectors}
/>
}).toArray()
}
)
})
.toArray()}
</div>
}

)}
</div>
)
}

}

export default Auths
Loading

0 comments on commit b35fd47

Please sign in to comment.