Merge pull request #3780 from swagger-api/ft/oas3-authorization
OAS 3.0 Authorization
This commit is contained in:
@@ -27,7 +27,10 @@
|
|||||||
|
|
||||||
isValid = qp.state === sentState
|
isValid = qp.state === sentState
|
||||||
|
|
||||||
if (oauth2.auth.schema.get("flow") === "accessCode" && !oauth2.auth.code) {
|
if ((
|
||||||
|
oauth2.auth.schema.get("flow") === "accessCode"||
|
||||||
|
oauth2.auth.schema.get("flow") === "authorizationCode"
|
||||||
|
) && !oauth2.auth.code) {
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
oauth2.errCb({
|
oauth2.errCb({
|
||||||
authId: oauth2.auth.name,
|
authId: oauth2.auth.name,
|
||||||
|
|||||||
5
dist/oauth2-redirect.html
vendored
5
dist/oauth2-redirect.html
vendored
@@ -27,7 +27,10 @@
|
|||||||
|
|
||||||
isValid = qp.state === sentState
|
isValid = qp.state === sentState
|
||||||
|
|
||||||
if (oauth2.auth.schema.get("flow") === "accessCode" && !oauth2.auth.code) {
|
if ((
|
||||||
|
oauth2.auth.schema.get("flow") === "accessCode"||
|
||||||
|
oauth2.auth.schema.get("flow") === "authorizationCode"
|
||||||
|
) && !oauth2.auth.code) {
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
oauth2.errCb({
|
oauth2.errCb({
|
||||||
authId: oauth2.auth.name,
|
authId: oauth2.auth.name,
|
||||||
|
|||||||
@@ -51,14 +51,15 @@ export default class ApiKeyAuth extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h4>Api key authorization<JumpToPath path={[ "securityDefinitions", name ]} /></h4>
|
<h4>
|
||||||
|
<code>{ name || schema.get("name") }</code>
|
||||||
|
(apiKey)
|
||||||
|
<JumpToPath path={[ "securityDefinitions", name ]} />
|
||||||
|
</h4>
|
||||||
{ value && <h6>Authorized</h6>}
|
{ value && <h6>Authorized</h6>}
|
||||||
<Row>
|
<Row>
|
||||||
<Markdown source={ schema.get("description") } />
|
<Markdown source={ schema.get("description") } />
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
|
||||||
<p>Name: <code>{ schema.get("name") }</code></p>
|
|
||||||
</Row>
|
|
||||||
<Row>
|
<Row>
|
||||||
<p>In: <code>{ schema.get("in") }</code></p>
|
<p>In: <code>{ schema.get("in") }</code></p>
|
||||||
</Row>
|
</Row>
|
||||||
|
|||||||
62
src/core/components/auth/auth-item.jsx
Normal file
62
src/core/components/auth/auth-item.jsx
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
import React from "react"
|
||||||
|
import PropTypes from "prop-types"
|
||||||
|
import ImPropTypes from "react-immutable-proptypes"
|
||||||
|
|
||||||
|
export default class Auths extends React.Component {
|
||||||
|
static propTypes = {
|
||||||
|
schema: ImPropTypes.orderedMap.isRequired,
|
||||||
|
name: PropTypes.string.isRequired,
|
||||||
|
onAuthChange: PropTypes.func.isRequired,
|
||||||
|
authorized: ImPropTypes.orderedMap.isRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let {
|
||||||
|
schema,
|
||||||
|
name,
|
||||||
|
getComponent,
|
||||||
|
onAuthChange,
|
||||||
|
authorized,
|
||||||
|
errSelectors
|
||||||
|
} = this.props
|
||||||
|
const ApiKeyAuth = getComponent("apiKeyAuth")
|
||||||
|
const BasicAuth = getComponent("basicAuth")
|
||||||
|
|
||||||
|
let authEl
|
||||||
|
|
||||||
|
const type = schema.get("type")
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case "apiKey": authEl = <ApiKeyAuth key={ name }
|
||||||
|
schema={ schema }
|
||||||
|
name={ name }
|
||||||
|
errSelectors={ errSelectors }
|
||||||
|
authorized={ authorized }
|
||||||
|
getComponent={ getComponent }
|
||||||
|
onChange={ onAuthChange } />
|
||||||
|
break
|
||||||
|
case "basic": authEl = <BasicAuth key={ name }
|
||||||
|
schema={ schema }
|
||||||
|
name={ name }
|
||||||
|
errSelectors={ errSelectors }
|
||||||
|
authorized={ authorized }
|
||||||
|
getComponent={ getComponent }
|
||||||
|
onChange={ onAuthChange } />
|
||||||
|
break
|
||||||
|
default: authEl = <div key={ name }>Unknown security definition type { type }</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
return (<div key={`${name}-jump`}>
|
||||||
|
{ authEl }
|
||||||
|
</div>)
|
||||||
|
}
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
errSelectors: PropTypes.object.isRequired,
|
||||||
|
getComponent: PropTypes.func.isRequired,
|
||||||
|
authSelectors: PropTypes.object.isRequired,
|
||||||
|
specSelectors: PropTypes.object.isRequired,
|
||||||
|
authActions: PropTypes.object.isRequired,
|
||||||
|
definitions: ImPropTypes.iterable.isRequired
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,7 +27,6 @@ export default class Auths extends React.Component {
|
|||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
||||||
let { authActions } = this.props
|
let { authActions } = this.props
|
||||||
|
|
||||||
authActions.authorize(this.state)
|
authActions.authorize(this.state)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,8 +43,7 @@ export default class Auths extends React.Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
let { definitions, getComponent, authSelectors, errSelectors } = this.props
|
let { definitions, getComponent, authSelectors, errSelectors } = this.props
|
||||||
const ApiKeyAuth = getComponent("apiKeyAuth")
|
const AuthItem = getComponent("AuthItem")
|
||||||
const BasicAuth = getComponent("basicAuth")
|
|
||||||
const Oauth2 = getComponent("oauth2", true)
|
const Oauth2 = getComponent("oauth2", true)
|
||||||
const Button = getComponent("Button")
|
const Button = getComponent("Button")
|
||||||
|
|
||||||
@@ -64,33 +62,15 @@ export default class Auths extends React.Component {
|
|||||||
!!nonOauthDefinitions.size && <form onSubmit={ this.submitAuth }>
|
!!nonOauthDefinitions.size && <form onSubmit={ this.submitAuth }>
|
||||||
{
|
{
|
||||||
nonOauthDefinitions.map( (schema, name) => {
|
nonOauthDefinitions.map( (schema, name) => {
|
||||||
let type = schema.get("type")
|
return <AuthItem
|
||||||
let authEl
|
key={name}
|
||||||
|
schema={schema}
|
||||||
switch(type) {
|
name={name}
|
||||||
case "apiKey": authEl = <ApiKeyAuth key={ name }
|
getComponent={getComponent}
|
||||||
schema={ schema }
|
onAuthChange={this.onAuthChange}
|
||||||
name={ name }
|
authorized={authorized}
|
||||||
errSelectors={ errSelectors }
|
errSelectors={errSelectors}
|
||||||
authorized={ authorized }
|
/>
|
||||||
getComponent={ getComponent }
|
|
||||||
onChange={ this.onAuthChange } />
|
|
||||||
break
|
|
||||||
case "basic": authEl = <BasicAuth key={ name }
|
|
||||||
schema={ schema }
|
|
||||||
name={ name }
|
|
||||||
errSelectors={ errSelectors }
|
|
||||||
authorized={ authorized }
|
|
||||||
getComponent={ getComponent }
|
|
||||||
onChange={ this.onAuthChange } />
|
|
||||||
break
|
|
||||||
default: authEl = <div key={ name }>Unknown security definition type { type }</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
return (<div key={`${name}-jump`}>
|
|
||||||
{ authEl }
|
|
||||||
</div>)
|
|
||||||
|
|
||||||
}).toArray()
|
}).toArray()
|
||||||
}
|
}
|
||||||
<div className="auth-btn-wrapper">
|
<div className="auth-btn-wrapper">
|
||||||
|
|||||||
@@ -2,11 +2,6 @@ import React from "react"
|
|||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import oauth2Authorize from "core/oauth2-authorize"
|
import oauth2Authorize from "core/oauth2-authorize"
|
||||||
|
|
||||||
const IMPLICIT = "implicit"
|
|
||||||
const ACCESS_CODE = "accessCode"
|
|
||||||
const PASSWORD = "password"
|
|
||||||
const APPLICATION = "application"
|
|
||||||
|
|
||||||
export default class Oauth2 extends React.Component {
|
export default class Oauth2 extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
name: PropTypes.string,
|
name: PropTypes.string,
|
||||||
@@ -16,6 +11,7 @@ export default class Oauth2 extends React.Component {
|
|||||||
authSelectors: PropTypes.object.isRequired,
|
authSelectors: PropTypes.object.isRequired,
|
||||||
authActions: PropTypes.object.isRequired,
|
authActions: PropTypes.object.isRequired,
|
||||||
errSelectors: PropTypes.object.isRequired,
|
errSelectors: PropTypes.object.isRequired,
|
||||||
|
specSelectors: PropTypes.object.isRequired,
|
||||||
errActions: PropTypes.object.isRequired,
|
errActions: PropTypes.object.isRequired,
|
||||||
getConfigs: PropTypes.any
|
getConfigs: PropTypes.any
|
||||||
}
|
}
|
||||||
@@ -83,7 +79,9 @@ export default class Oauth2 extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let { schema, getComponent, authSelectors, errSelectors, name } = this.props
|
let {
|
||||||
|
schema, getComponent, authSelectors, errSelectors, name, specSelectors
|
||||||
|
} = this.props
|
||||||
const Input = getComponent("Input")
|
const Input = getComponent("Input")
|
||||||
const Row = getComponent("Row")
|
const Row = getComponent("Row")
|
||||||
const Col = getComponent("Col")
|
const Col = getComponent("Col")
|
||||||
@@ -92,6 +90,14 @@ export default class Oauth2 extends React.Component {
|
|||||||
const JumpToPath = getComponent("JumpToPath", true)
|
const JumpToPath = getComponent("JumpToPath", true)
|
||||||
const Markdown = getComponent( "Markdown" )
|
const Markdown = getComponent( "Markdown" )
|
||||||
|
|
||||||
|
const { isOAS3 } = specSelectors
|
||||||
|
|
||||||
|
// Auth type consts
|
||||||
|
const IMPLICIT = "implicit"
|
||||||
|
const PASSWORD = "password"
|
||||||
|
const ACCESS_CODE = isOAS3() ? "authorizationCode" : "accessCode"
|
||||||
|
const APPLICATION = isOAS3() ? "clientCredentials" : "application"
|
||||||
|
|
||||||
let flow = schema.get("flow")
|
let flow = schema.get("flow")
|
||||||
let scopes = schema.get("allowedScopes") || schema.get("scopes")
|
let scopes = schema.get("allowedScopes") || schema.get("scopes")
|
||||||
let authorizedAuth = authSelectors.authorized().get(name)
|
let authorizedAuth = authSelectors.authorized().get(name)
|
||||||
@@ -102,7 +108,7 @@ export default class Oauth2 extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h4>OAuth2.0 <JumpToPath path={[ "securityDefinitions", name ]} /></h4>
|
<h4>{name} (OAuth2, { schema.get("flow") }) <JumpToPath path={[ "securityDefinitions", name ]} /></h4>
|
||||||
{ !this.state.appName ? null : <h5>Application: { this.state.appName } </h5> }
|
{ !this.state.appName ? null : <h5>Application: { this.state.appName } </h5> }
|
||||||
{ description && <Markdown source={ schema.get("description") } /> }
|
{ description && <Markdown source={ schema.get("description") } /> }
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,16 @@ export default function authorize ( { auth, authActions, errActions, configs, au
|
|||||||
case "implicit":
|
case "implicit":
|
||||||
query.push("response_type=token")
|
query.push("response_type=token")
|
||||||
break
|
break
|
||||||
|
|
||||||
|
case "clientCredentials":
|
||||||
|
// OAS3
|
||||||
|
authActions.authorizeApplication(auth)
|
||||||
|
return
|
||||||
|
|
||||||
|
case "authorizationCode":
|
||||||
|
// OAS3
|
||||||
|
query.push("response_type=code")
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof clientId === "string") {
|
if (typeof clientId === "string") {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export default {
|
|||||||
securities.entrySeq().forEach( ([ key, security ]) => {
|
securities.entrySeq().forEach( ([ key, security ]) => {
|
||||||
let type = security.getIn(["schema", "type"])
|
let type = security.getIn(["schema", "type"])
|
||||||
|
|
||||||
if ( type === "apiKey" ) {
|
if ( type === "apiKey" || type === "http" ) {
|
||||||
map = map.set(key, security)
|
map = map.set(key, security)
|
||||||
} else if ( type === "basic" ) {
|
} else if ( type === "basic" ) {
|
||||||
let username = security.getIn(["value", "username"])
|
let username = security.getIn(["value", "username"])
|
||||||
|
|||||||
@@ -1,29 +1,60 @@
|
|||||||
import { createSelector } from "reselect"
|
import { createSelector } from "reselect"
|
||||||
import { List } from "immutable"
|
import { List, Map, fromJS } from "immutable"
|
||||||
import { isOAS3 as isOAS3Helper } from "../helpers"
|
import { isOAS3 as isOAS3Helper } from "../helpers"
|
||||||
|
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
|
|
||||||
|
const state = state => state
|
||||||
|
|
||||||
function onlyOAS3(selector) {
|
function onlyOAS3(selector) {
|
||||||
return (ori, system) => (state, ...args) => {
|
return (ori, system) => (state, ...args) => {
|
||||||
const spec = system.getSystem().specSelectors.specJson()
|
const spec = system.getSystem().specSelectors.specJson()
|
||||||
if(isOAS3Helper(spec)) {
|
if(isOAS3Helper(spec)) {
|
||||||
return selector(...args)
|
return selector(system, ...args)
|
||||||
} else {
|
} else {
|
||||||
return ori(...args)
|
return ori(...args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const nullSelector = createSelector(() => null)
|
export const definitionsToAuthorize = onlyOAS3(createSelector(
|
||||||
|
state,
|
||||||
|
({ specSelectors }) => {
|
||||||
|
// Coerce our OpenAPI 3.0 definitions into monoflow definitions
|
||||||
|
// that look like Swagger2 definitions.
|
||||||
|
let definitions = specSelectors.securityDefinitions()
|
||||||
|
let list = List()
|
||||||
|
|
||||||
const OAS3NullSelector = onlyOAS3(nullSelector)
|
definitions.entrySeq().forEach( ([ defName, definition ]) => {
|
||||||
|
const type = definition.get("type")
|
||||||
|
|
||||||
// Hasta la vista, authorization!
|
if(type === "oauth2") {
|
||||||
export const shownDefinitions = OAS3NullSelector
|
definition.get("flows").entrySeq().forEach(([flowKey, flowVal]) => {
|
||||||
export const definitionsToAuthorize = OAS3NullSelector
|
let translatedDef = fromJS({
|
||||||
export const getDefinitionsByNames = OAS3NullSelector
|
flow: flowKey,
|
||||||
export const authorized = onlyOAS3(() => List())
|
authorizationUrl: flowVal.get("authorizationUrl"),
|
||||||
export const isAuthorized = OAS3NullSelector
|
tokenUrl: flowVal.get("tokenUrl"),
|
||||||
export const getConfigs = OAS3NullSelector
|
scopes: flowVal.get("scopes"),
|
||||||
|
type: definition.get("type")
|
||||||
|
})
|
||||||
|
|
||||||
|
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 === "http" || type === "apiKey") {
|
||||||
|
list = list.push(new Map({
|
||||||
|
[defName]: definition
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
))
|
||||||
134
src/core/plugins/oas3/components/http-auth.jsx
Normal file
134
src/core/plugins/oas3/components/http-auth.jsx
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
import React from "react"
|
||||||
|
import PropTypes from "prop-types"
|
||||||
|
|
||||||
|
export default class HttpAuth extends React.Component {
|
||||||
|
static propTypes = {
|
||||||
|
authorized: PropTypes.object,
|
||||||
|
getComponent: PropTypes.func.isRequired,
|
||||||
|
errSelectors: PropTypes.object.isRequired,
|
||||||
|
schema: PropTypes.object.isRequired,
|
||||||
|
name: PropTypes.string.isRequired,
|
||||||
|
onChange: PropTypes.func
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(props, context) {
|
||||||
|
super(props, context)
|
||||||
|
let { name, schema } = this.props
|
||||||
|
let value = this.getValue()
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
name: name,
|
||||||
|
schema: schema,
|
||||||
|
value: value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getValue () {
|
||||||
|
let { name, authorized } = this.props
|
||||||
|
|
||||||
|
return authorized && authorized.getIn([name, "value"])
|
||||||
|
}
|
||||||
|
|
||||||
|
onChange =(e) => {
|
||||||
|
let { onChange } = this.props
|
||||||
|
let { value, name } = e.target
|
||||||
|
|
||||||
|
let newValue = this.state.value || {}
|
||||||
|
if(name) {
|
||||||
|
newValue[name] = value
|
||||||
|
} else {
|
||||||
|
newValue = value
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({ value: newValue }, () => onChange(this.state))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let { schema, getComponent, errSelectors, name } = this.props
|
||||||
|
const Input = getComponent("Input")
|
||||||
|
const Row = getComponent("Row")
|
||||||
|
const Col = getComponent("Col")
|
||||||
|
const AuthError = getComponent("authError")
|
||||||
|
const Markdown = getComponent( "Markdown" )
|
||||||
|
const JumpToPath = getComponent("JumpToPath", true)
|
||||||
|
|
||||||
|
const scheme = schema.get("scheme")
|
||||||
|
let value = this.getValue()
|
||||||
|
let errors = errSelectors.allErrors().filter( err => err.get("authId") === name)
|
||||||
|
|
||||||
|
if(scheme === "basic") {
|
||||||
|
let username = value ? value.get("username") : null
|
||||||
|
return <div>
|
||||||
|
<h4>
|
||||||
|
<code>{ name || schema.get("name") }</code>
|
||||||
|
(http, Basic)
|
||||||
|
<JumpToPath path={[ "securityDefinitions", name ]} />
|
||||||
|
</h4>
|
||||||
|
{ username && <h6>Authorized</h6> }
|
||||||
|
<Row>
|
||||||
|
<Markdown source={ schema.get("description") } />
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<label>Username:</label>
|
||||||
|
{
|
||||||
|
username ? <code> { username } </code>
|
||||||
|
: <Col><Input type="text" required="required" name="username" onChange={ this.onChange }/></Col>
|
||||||
|
}
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<label>Password:</label>
|
||||||
|
{
|
||||||
|
username ? <code> ****** </code>
|
||||||
|
: <Col><Input required="required"
|
||||||
|
autoComplete="new-password"
|
||||||
|
name="password"
|
||||||
|
type="password"
|
||||||
|
onChange={ this.onChange }/></Col>
|
||||||
|
}
|
||||||
|
</Row>
|
||||||
|
{
|
||||||
|
errors.valueSeq().map( (error, key) => {
|
||||||
|
return <AuthError error={ error }
|
||||||
|
key={ key }/>
|
||||||
|
} )
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
if(scheme === "bearer") {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h4>
|
||||||
|
<code>{ name || schema.get("name") }</code>
|
||||||
|
(http, Bearer)
|
||||||
|
<JumpToPath path={[ "securityDefinitions", name ]} />
|
||||||
|
</h4>
|
||||||
|
{ value && <h6>Authorized</h6>}
|
||||||
|
<Row>
|
||||||
|
<Markdown source={ schema.get("description") } />
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<p>In: <code>{ schema.get("in") }</code></p>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<label>Value:</label>
|
||||||
|
{
|
||||||
|
value ? <code> ****** </code>
|
||||||
|
: <Col><Input type="text" onChange={ this.onChange }/></Col>
|
||||||
|
}
|
||||||
|
</Row>
|
||||||
|
{
|
||||||
|
errors.valueSeq().map( (error, key) => {
|
||||||
|
return <AuthError error={ error }
|
||||||
|
key={ key }/>
|
||||||
|
} )
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return <div>
|
||||||
|
<em><b>{name}</b> HTTP authentication: unsupported or missing scheme</em>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,9 +3,11 @@ import RequestBody from "./request-body"
|
|||||||
import OperationLink from "./operation-link.jsx"
|
import OperationLink from "./operation-link.jsx"
|
||||||
import Servers from "./servers"
|
import Servers from "./servers"
|
||||||
import RequestBodyEditor from "./request-body-editor"
|
import RequestBodyEditor from "./request-body-editor"
|
||||||
|
import HttpAuth from "./http-auth"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
Callbacks,
|
Callbacks,
|
||||||
|
HttpAuth,
|
||||||
RequestBody,
|
RequestBody,
|
||||||
Servers,
|
Servers,
|
||||||
RequestBodyEditor,
|
RequestBodyEditor,
|
||||||
|
|||||||
@@ -48,12 +48,16 @@ export const definitions = onlyOAS3(createSelector(
|
|||||||
spec => spec.getIn(["components", "schemas"]) || Map()
|
spec => spec.getIn(["components", "schemas"]) || Map()
|
||||||
))
|
))
|
||||||
|
|
||||||
|
export const securityDefinitions = onlyOAS3(createSelector(
|
||||||
|
spec,
|
||||||
|
spec => spec.getIn(["components", "securitySchemes"]) || Map()
|
||||||
|
))
|
||||||
|
|
||||||
export const host = OAS3NullSelector
|
export const host = OAS3NullSelector
|
||||||
export const basePath = OAS3NullSelector
|
export const basePath = OAS3NullSelector
|
||||||
export const consumes = OAS3NullSelector
|
export const consumes = OAS3NullSelector
|
||||||
export const produces = OAS3NullSelector
|
export const produces = OAS3NullSelector
|
||||||
export const schemes = OAS3NullSelector
|
export const schemes = OAS3NullSelector
|
||||||
export const securityDefinitions = OAS3NullSelector
|
|
||||||
|
|
||||||
// New selectors
|
// New selectors
|
||||||
|
|
||||||
|
|||||||
23
src/core/plugins/oas3/wrap-components/auth-item.jsx
Normal file
23
src/core/plugins/oas3/wrap-components/auth-item.jsx
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import React from "react"
|
||||||
|
import { OAS3ComponentWrapFactory } from "../helpers"
|
||||||
|
|
||||||
|
export default OAS3ComponentWrapFactory(({ Ori, ...props }) => {
|
||||||
|
const {
|
||||||
|
schema, getComponent, errSelectors, authorized, onAuthChange, name
|
||||||
|
} = props
|
||||||
|
|
||||||
|
const HttpAuth = getComponent("HttpAuth")
|
||||||
|
const type = schema.get("type")
|
||||||
|
|
||||||
|
if(type === "http") {
|
||||||
|
return <HttpAuth key={ name }
|
||||||
|
schema={ schema }
|
||||||
|
name={ name }
|
||||||
|
errSelectors={ errSelectors }
|
||||||
|
authorized={ authorized }
|
||||||
|
getComponent={ getComponent }
|
||||||
|
onChange={ onAuthChange }/>
|
||||||
|
} else {
|
||||||
|
return <Ori {...props} />
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import Markdown from "./markdown"
|
import Markdown from "./markdown"
|
||||||
|
import AuthItem from "./auth-item"
|
||||||
import parameters from "./parameters"
|
import parameters from "./parameters"
|
||||||
import VersionStamp from "./version-stamp"
|
import VersionStamp from "./version-stamp"
|
||||||
import OnlineValidatorBadge from "./online-validator-badge"
|
import OnlineValidatorBadge from "./online-validator-badge"
|
||||||
@@ -6,6 +7,7 @@ import Model from "./model"
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
Markdown,
|
Markdown,
|
||||||
|
AuthItem,
|
||||||
parameters,
|
parameters,
|
||||||
VersionStamp,
|
VersionStamp,
|
||||||
model: Model,
|
model: Model,
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import AuthorizationPopup from "core/components/auth/authorization-popup"
|
|||||||
import AuthorizeBtn from "core/components/auth/authorize-btn"
|
import AuthorizeBtn from "core/components/auth/authorize-btn"
|
||||||
import AuthorizeOperationBtn from "core/components/auth/authorize-operation-btn"
|
import AuthorizeOperationBtn from "core/components/auth/authorize-operation-btn"
|
||||||
import Auths from "core/components/auth/auths"
|
import Auths from "core/components/auth/auths"
|
||||||
|
import AuthItem from "core/components/auth/auth-item"
|
||||||
import AuthError from "core/components/auth/error"
|
import AuthError from "core/components/auth/error"
|
||||||
import ApiKeyAuth from "core/components/auth/api-key-auth"
|
import ApiKeyAuth from "core/components/auth/api-key-auth"
|
||||||
import BasicAuth from "core/components/auth/basic-auth"
|
import BasicAuth from "core/components/auth/basic-auth"
|
||||||
@@ -70,6 +71,7 @@ export default function() {
|
|||||||
authorizeBtn: AuthorizeBtn,
|
authorizeBtn: AuthorizeBtn,
|
||||||
authorizeOperationBtn: AuthorizeOperationBtn,
|
authorizeOperationBtn: AuthorizeOperationBtn,
|
||||||
auths: Auths,
|
auths: Auths,
|
||||||
|
AuthItem: AuthItem,
|
||||||
authError: AuthError,
|
authError: AuthError,
|
||||||
oauth2: Oauth2,
|
oauth2: Oauth2,
|
||||||
apiKeyAuth: ApiKeyAuth,
|
apiKeyAuth: ApiKeyAuth,
|
||||||
|
|||||||
116
test/core/plugins/oas3/wrap-auth-selectors.js
Normal file
116
test/core/plugins/oas3/wrap-auth-selectors.js
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
/* eslint-env mocha */
|
||||||
|
import expect, { createSpy } from "expect"
|
||||||
|
import { Map, fromJS } from "immutable"
|
||||||
|
import {
|
||||||
|
definitionsToAuthorize
|
||||||
|
} from "corePlugins/oas3/auth-extensions/wrap-selectors"
|
||||||
|
|
||||||
|
describe.only("oas3 plugin - auth extensions - wrapSelectors", function(){
|
||||||
|
|
||||||
|
describe("execute", function(){
|
||||||
|
|
||||||
|
it("should add `securities` to the oriAction call", function(){
|
||||||
|
// Given
|
||||||
|
const system = {
|
||||||
|
getSystem: () => system,
|
||||||
|
specSelectors: {
|
||||||
|
specJson: () => fromJS({
|
||||||
|
openapi: "3.0.0"
|
||||||
|
}),
|
||||||
|
securityDefinitions: () => {
|
||||||
|
return fromJS({
|
||||||
|
"oauth2AuthorizationCode": {
|
||||||
|
"type": "oauth2",
|
||||||
|
"flows": {
|
||||||
|
"authorizationCode": {
|
||||||
|
"authorizationUrl": "http://google.com/",
|
||||||
|
"tokenUrl": "http://google.com/",
|
||||||
|
"scopes": {
|
||||||
|
"myScope": "our only scope"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"oauth2Multiflow": {
|
||||||
|
"type": "oauth2",
|
||||||
|
"flows": {
|
||||||
|
"clientCredentials": {
|
||||||
|
"tokenUrl": "http://google.com/",
|
||||||
|
"scopes": {
|
||||||
|
"myScope": "our only scope"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"tokenUrl": "http://google.com/",
|
||||||
|
"scopes": {
|
||||||
|
"myScope": "our only scope"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"authorizationCode": {
|
||||||
|
"authorizationUrl": "http://google.com/",
|
||||||
|
"tokenUrl": "http://google.com/",
|
||||||
|
"scopes": {
|
||||||
|
"myScope": "our only scope"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// When
|
||||||
|
let res = definitionsToAuthorize(() => null, system)()
|
||||||
|
|
||||||
|
// Then
|
||||||
|
expect(res.toJS()).toEqual([
|
||||||
|
{
|
||||||
|
oauth2AuthorizationCode: {
|
||||||
|
flow: "authorizationCode",
|
||||||
|
authorizationUrl: "http://google.com/",
|
||||||
|
tokenUrl: "http://google.com/",
|
||||||
|
scopes: {
|
||||||
|
"myScope": "our only scope"
|
||||||
|
},
|
||||||
|
type: "oauth2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
oauth2Multiflow: {
|
||||||
|
flow: "clientCredentials",
|
||||||
|
tokenUrl: "http://google.com/",
|
||||||
|
scopes: {
|
||||||
|
"myScope": "our only scope"
|
||||||
|
},
|
||||||
|
type: "oauth2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
oauth2Multiflow: {
|
||||||
|
flow: "password",
|
||||||
|
tokenUrl: "http://google.com/",
|
||||||
|
scopes: {
|
||||||
|
"myScope": "our only scope"
|
||||||
|
},
|
||||||
|
type: "oauth2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
oauth2Multiflow: {
|
||||||
|
flow: "authorizationCode",
|
||||||
|
authorizationUrl: "http://google.com/",
|
||||||
|
tokenUrl: "http://google.com/",
|
||||||
|
scopes: {
|
||||||
|
"myScope": "our only scope"
|
||||||
|
},
|
||||||
|
type: "oauth2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user