@@ -51,14 +51,15 @@ export default class ApiKeyAuth extends React.Component { | |||
return ( | |||
<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>} | |||
<Row> | |||
<Markdown source={ schema.get("description") } /> | |||
</Row> | |||
<Row> | |||
<p>Name: <code>{ schema.get("name") }</code></p> | |||
</Row> | |||
<Row> | |||
<p>In: <code>{ schema.get("in") }</code></p> | |||
</Row> | |||
@@ -0,0 +1,59 @@ | |||
import React from "react" | |||
import PropTypes from "prop-types" | |||
import ImPropTypes from "react-immutable-proptypes" | |||
export default class Auths extends React.Component { | |||
static propTypes = { | |||
} | |||
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() | |||
let { authActions } = this.props | |||
authActions.authorize(this.state) | |||
} | |||
@@ -44,8 +43,7 @@ export default class Auths extends React.Component { | |||
render() { | |||
let { definitions, getComponent, authSelectors, errSelectors } = this.props | |||
const ApiKeyAuth = getComponent("apiKeyAuth") | |||
const BasicAuth = getComponent("basicAuth") | |||
const AuthItem = getComponent("AuthItem") | |||
const Oauth2 = getComponent("oauth2", true) | |||
const Button = getComponent("Button") | |||
@@ -64,33 +62,15 @@ export default class Auths extends React.Component { | |||
!!nonOauthDefinitions.size && <form onSubmit={ this.submitAuth }> | |||
{ | |||
nonOauthDefinitions.map( (schema, name) => { | |||
let type = schema.get("type") | |||
let authEl | |||
switch(type) { | |||
case "apiKey": authEl = <ApiKeyAuth key={ name } | |||
schema={ schema } | |||
name={ name } | |||
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>) | |||
return <AuthItem | |||
key={name} | |||
schema={schema} | |||
name={name} | |||
getComponent={getComponent} | |||
onAuthChange={this.onAuthChange} | |||
authorized={authorized} | |||
errSelectors={errSelectors} | |||
/> | |||
}).toArray() | |||
} | |||
<div className="auth-btn-wrapper"> | |||
@@ -22,7 +22,7 @@ export default { | |||
securities.entrySeq().forEach( ([ key, security ]) => { | |||
let type = security.getIn(["schema", "type"]) | |||
if ( type === "apiKey" ) { | |||
if ( type === "apiKey" || type === "http" ) { | |||
map = map.set(key, security) | |||
} else if ( type === "basic" ) { | |||
let username = security.getIn(["value", "username"]) | |||
@@ -27,23 +27,32 @@ export const definitionsToAuthorize = onlyOAS3(createSelector( | |||
let list = List() | |||
definitions.entrySeq().forEach( ([ defName, definition ]) => { | |||
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") | |||
}) | |||
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") | |||
}) | |||
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]: translatedDef.filter((v) => { | |||
// filter out unset values, sometimes `authorizationUrl` | |||
// and `tokenUrl` come out as `undefined` in the data | |||
return v !== undefined | |||
}) | |||
[defName]: definition | |||
})) | |||
}) | |||
} | |||
}) | |||
return list | |||
@@ -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 Servers from "./servers" | |||
import RequestBodyEditor from "./request-body-editor" | |||
import HttpAuth from "./http-auth" | |||
export default { | |||
Callbacks, | |||
HttpAuth, | |||
RequestBody, | |||
Servers, | |||
RequestBodyEditor, | |||
@@ -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 AuthItem from "./auth-item" | |||
import parameters from "./parameters" | |||
import VersionStamp from "./version-stamp" | |||
import OnlineValidatorBadge from "./online-validator-badge" | |||
@@ -6,6 +7,7 @@ import Model from "./model" | |||
export default { | |||
Markdown, | |||
AuthItem, | |||
parameters, | |||
VersionStamp, | |||
model: Model, | |||
@@ -17,6 +17,7 @@ import AuthorizationPopup from "core/components/auth/authorization-popup" | |||
import AuthorizeBtn from "core/components/auth/authorize-btn" | |||
import AuthorizeOperationBtn from "core/components/auth/authorize-operation-btn" | |||
import Auths from "core/components/auth/auths" | |||
import AuthItem from "core/components/auth/auth-item" | |||
import AuthError from "core/components/auth/error" | |||
import ApiKeyAuth from "core/components/auth/api-key-auth" | |||
import BasicAuth from "core/components/auth/basic-auth" | |||
@@ -70,6 +71,7 @@ export default function() { | |||
authorizeBtn: AuthorizeBtn, | |||
authorizeOperationBtn: AuthorizeOperationBtn, | |||
auths: Auths, | |||
AuthItem: AuthItem, | |||
authError: AuthError, | |||
oauth2: Oauth2, | |||
apiKeyAuth: ApiKeyAuth, | |||