From c9674a1fc5ff463d4d53b09581aa1af91cf47c4b Mon Sep 17 00:00:00 2001 From: Kyle Shockey Date: Wed, 18 Oct 2017 21:23:28 -0700 Subject: [PATCH] Refactor Auths component flow; create component that supports HTTP auths --- src/core/components/auth/api-key-auth.jsx | 9 +- src/core/components/auth/auth-item.jsx | 59 ++++++++ src/core/components/auth/auths.jsx | 40 ++---- src/core/plugins/auth/reducers.js | 2 +- .../oas3/auth-extensions/wrap-selectors.js | 37 +++-- .../plugins/oas3/components/http-auth.jsx | 134 ++++++++++++++++++ src/core/plugins/oas3/components/index.js | 2 + .../oas3/wrap-components/auth-item.jsx | 23 +++ .../plugins/oas3/wrap-components/index.js | 2 + src/core/presets/base.js | 2 + 10 files changed, 261 insertions(+), 49 deletions(-) create mode 100644 src/core/components/auth/auth-item.jsx create mode 100644 src/core/plugins/oas3/components/http-auth.jsx create mode 100644 src/core/plugins/oas3/wrap-components/auth-item.jsx diff --git a/src/core/components/auth/api-key-auth.jsx b/src/core/components/auth/api-key-auth.jsx index d9796f76..2d8a5f52 100644 --- a/src/core/components/auth/api-key-auth.jsx +++ b/src/core/components/auth/api-key-auth.jsx @@ -51,14 +51,15 @@ export default class ApiKeyAuth extends React.Component { return (
-

Api key authorization

+

+ { name || schema.get("name") }  + (apiKey) + +

{ value &&
Authorized
} - -

Name: { schema.get("name") }

-

In: { schema.get("in") }

diff --git a/src/core/components/auth/auth-item.jsx b/src/core/components/auth/auth-item.jsx new file mode 100644 index 00000000..bdff2c39 --- /dev/null +++ b/src/core/components/auth/auth-item.jsx @@ -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 = + break + case "basic": authEl = + break + default: authEl =
Unknown security definition type { type }
+ } + + return (
+ { authEl } +
) + } + + 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 + } +} diff --git a/src/core/components/auth/auths.jsx b/src/core/components/auth/auths.jsx index f03837d6..2110c6cc 100644 --- a/src/core/components/auth/auths.jsx +++ b/src/core/components/auth/auths.jsx @@ -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 &&
{ nonOauthDefinitions.map( (schema, name) => { - let type = schema.get("type") - let authEl - - switch(type) { - case "apiKey": authEl = - break - case "basic": authEl = - break - default: authEl =
Unknown security definition type { type }
- } - - return (
- { authEl } -
) - + return }).toArray() }
diff --git a/src/core/plugins/auth/reducers.js b/src/core/plugins/auth/reducers.js index 2eca5c08..ae283477 100644 --- a/src/core/plugins/auth/reducers.js +++ b/src/core/plugins/auth/reducers.js @@ -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"]) diff --git a/src/core/plugins/oas3/auth-extensions/wrap-selectors.js b/src/core/plugins/oas3/auth-extensions/wrap-selectors.js index 68f02ddd..4d7cdce8 100644 --- a/src/core/plugins/oas3/auth-extensions/wrap-selectors.js +++ b/src/core/plugins/oas3/auth-extensions/wrap-selectors.js @@ -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 diff --git a/src/core/plugins/oas3/components/http-auth.jsx b/src/core/plugins/oas3/components/http-auth.jsx new file mode 100644 index 00000000..bb4727ee --- /dev/null +++ b/src/core/plugins/oas3/components/http-auth.jsx @@ -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
+

+ { name || schema.get("name") }  + (http, Basic) + +

+ { username &&
Authorized
} + + + + + + { + username ? { username } + : + } + + + + { + username ? ****** + : + } + + { + errors.valueSeq().map( (error, key) => { + return + } ) + } +
+ } + + if(scheme === "bearer") { + return ( +
+

+ { name || schema.get("name") }  + (http, Bearer) + +

+ { value &&
Authorized
} + + + + +

In: { schema.get("in") }

+
+ + + { + value ? ****** + : + } + + { + errors.valueSeq().map( (error, key) => { + return + } ) + } +
+ ) + } + return
+ {name} HTTP authentication: unsupported or missing scheme +
+ } +} diff --git a/src/core/plugins/oas3/components/index.js b/src/core/plugins/oas3/components/index.js index 642c6689..edd409a1 100644 --- a/src/core/plugins/oas3/components/index.js +++ b/src/core/plugins/oas3/components/index.js @@ -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, diff --git a/src/core/plugins/oas3/wrap-components/auth-item.jsx b/src/core/plugins/oas3/wrap-components/auth-item.jsx new file mode 100644 index 00000000..bd6df5cb --- /dev/null +++ b/src/core/plugins/oas3/wrap-components/auth-item.jsx @@ -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 + } else { + return + } +}) diff --git a/src/core/plugins/oas3/wrap-components/index.js b/src/core/plugins/oas3/wrap-components/index.js index 8b105b38..910dcf29 100644 --- a/src/core/plugins/oas3/wrap-components/index.js +++ b/src/core/plugins/oas3/wrap-components/index.js @@ -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, diff --git a/src/core/presets/base.js b/src/core/presets/base.js index 10a12645..ec005b37 100644 --- a/src/core/presets/base.js +++ b/src/core/presets/base.js @@ -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,