123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- import React from "react"
- import PropTypes from "prop-types"
- import oauth2Authorize from "core/oauth2-authorize"
- export default class Oauth2 extends React.Component {
- static propTypes = {
- name: PropTypes.string,
- authorized: PropTypes.object,
- getComponent: PropTypes.func.isRequired,
- schema: PropTypes.object.isRequired,
- authSelectors: PropTypes.object.isRequired,
- authActions: PropTypes.object.isRequired,
- errSelectors: PropTypes.object.isRequired,
- oas3Selectors: PropTypes.object.isRequired,
- specSelectors: PropTypes.object.isRequired,
- errActions: PropTypes.object.isRequired,
- getConfigs: PropTypes.any
- }
- constructor(props, context) {
- super(props, context)
- let { name, schema, authorized, authSelectors } = this.props
- let auth = authorized && authorized.get(name)
- let authConfigs = authSelectors.getConfigs() || {}
- let username = auth && auth.get("username") || ""
- let clientId = auth && auth.get("clientId") || authConfigs.clientId || ""
- let clientSecret = auth && auth.get("clientSecret") || authConfigs.clientSecret || ""
- let passwordType = auth && auth.get("passwordType") || "basic"
- let scopes = auth && auth.get("scopes") || authConfigs.scopes || []
- if (typeof scopes === "string") {
- scopes = scopes.split(authConfigs.scopeSeparator || " ")
- }
- this.state = {
- appName: authConfigs.appName,
- name: name,
- schema: schema,
- scopes: scopes,
- clientId: clientId,
- clientSecret: clientSecret,
- username: username,
- password: "",
- passwordType: passwordType
- }
- }
- close = (e) => {
- e.preventDefault()
- let { authActions } = this.props
- authActions.showDefinitions(false)
- }
- authorize =() => {
- let { authActions, errActions, getConfigs, authSelectors, oas3Selectors } = this.props
- let configs = getConfigs()
- let authConfigs = authSelectors.getConfigs()
- errActions.clear({authId: name,type: "auth", source: "auth"})
- oauth2Authorize({
- auth: this.state,
- currentServer: oas3Selectors.serverEffectiveValue(oas3Selectors.selectedServer()),
- authActions,
- errActions,
- configs,
- authConfigs
- })
- }
- onScopeChange =(e) => {
- let { target } = e
- let { checked } = target
- let scope = target.dataset.value
- if ( checked && this.state.scopes.indexOf(scope) === -1 ) {
- let newScopes = this.state.scopes.concat([scope])
- this.setState({ scopes: newScopes })
- } else if ( !checked && this.state.scopes.indexOf(scope) > -1) {
- this.setState({ scopes: this.state.scopes.filter((val) => val !== scope) })
- }
- }
- onInputChange =(e) => {
- let { target : { dataset : { name }, value } } = e
- let state = {
- [name]: value
- }
- this.setState(state)
- }
- selectScopes =(e) => {
- if (e.target.dataset.all) {
- this.setState({
- scopes: Array.from((this.props.schema.get("allowedScopes") || this.props.schema.get("scopes")).keys())
- })
- } else {
- this.setState({ scopes: [] })
- }
- }
- logout =(e) => {
- e.preventDefault()
- let { authActions, errActions, name } = this.props
- errActions.clear({authId: name, type: "auth", source: "auth"})
- authActions.logoutWithPersistOption([ name ])
- }
- render() {
- let {
- schema, getComponent, authSelectors, errSelectors, name, specSelectors
- } = this.props
- const Input = getComponent("Input")
- const Row = getComponent("Row")
- const Col = getComponent("Col")
- const Button = getComponent("Button")
- const AuthError = getComponent("authError")
- const JumpToPath = getComponent("JumpToPath", true)
- const Markdown = getComponent("Markdown", true)
- const InitializedInput = getComponent("InitializedInput")
- const { isOAS3 } = specSelectors
- let oidcUrl = isOAS3() ? schema.get("openIdConnectUrl") : null
- // Auth type consts
- const IMPLICIT = "implicit"
- const PASSWORD = "password"
- const ACCESS_CODE = isOAS3() ? (oidcUrl ? "authorization_code" : "authorizationCode") : "accessCode"
- const APPLICATION = isOAS3() ? (oidcUrl ? "client_credentials" : "clientCredentials") : "application"
- let flow = schema.get("flow")
- let scopes = schema.get("allowedScopes") || schema.get("scopes")
- let authorizedAuth = authSelectors.authorized().get(name)
- let isAuthorized = !!authorizedAuth
- let errors = errSelectors.allErrors().filter( err => err.get("authId") === name)
- let isValid = !errors.filter( err => err.get("source") === "validation").size
- let description = schema.get("description")
- return (
- <div>
- <h4>{name} (OAuth2, { schema.get("flow") }) <JumpToPath path={[ "securityDefinitions", name ]} /></h4>
- { !this.state.appName ? null : <h5>Application: { this.state.appName } </h5> }
- { description && <Markdown source={ schema.get("description") } /> }
- { isAuthorized && <h6>Authorized</h6> }
- { oidcUrl && <p>OpenID Connect URL: <code>{ oidcUrl }</code></p> }
- { ( flow === IMPLICIT || flow === ACCESS_CODE ) && <p>Authorization URL: <code>{ schema.get("authorizationUrl") }</code></p> }
- { ( flow === PASSWORD || flow === ACCESS_CODE || flow === APPLICATION ) && <p>Token URL:<code> { schema.get("tokenUrl") }</code></p> }
- <p className="flow">Flow: <code>{ schema.get("flow") }</code></p>
- {
- flow !== PASSWORD ? null
- : <Row>
- <Row>
- <label htmlFor="oauth_username">username:</label>
- {
- isAuthorized ? <code> { this.state.username } </code>
- : <Col tablet={10} desktop={10}>
- <input id="oauth_username" type="text" data-name="username" onChange={ this.onInputChange } autoFocus/>
- </Col>
- }
- </Row>
- {
- }
- <Row>
- <label htmlFor="oauth_password">password:</label>
- {
- isAuthorized ? <code> ****** </code>
- : <Col tablet={10} desktop={10}>
- <input id="oauth_password" type="password" data-name="password" onChange={ this.onInputChange }/>
- </Col>
- }
- </Row>
- <Row>
- <label htmlFor="password_type">Client credentials location:</label>
- {
- isAuthorized ? <code> { this.state.passwordType } </code>
- : <Col tablet={10} desktop={10}>
- <select id="password_type" data-name="passwordType" onChange={ this.onInputChange }>
- <option value="basic">Authorization header</option>
- <option value="request-body">Request body</option>
- </select>
- </Col>
- }
- </Row>
- </Row>
- }
- {
- ( flow === APPLICATION || flow === IMPLICIT || flow === ACCESS_CODE || flow === PASSWORD ) &&
- ( !isAuthorized || isAuthorized && this.state.clientId) && <Row>
- <label htmlFor="client_id">client_id:</label>
- {
- isAuthorized ? <code> ****** </code>
- : <Col tablet={10} desktop={10}>
- <InitializedInput id="client_id"
- type="text"
- required={ flow === PASSWORD }
- initialValue={ this.state.clientId }
- data-name="clientId"
- onChange={ this.onInputChange }/>
- </Col>
- }
- </Row>
- }
- {
- ( (flow === APPLICATION || flow === ACCESS_CODE || flow === PASSWORD) && <Row>
- <label htmlFor="client_secret">client_secret:</label>
- {
- isAuthorized ? <code> ****** </code>
- : <Col tablet={10} desktop={10}>
- <InitializedInput id="client_secret"
- initialValue={ this.state.clientSecret }
- type="password"
- data-name="clientSecret"
- onChange={ this.onInputChange }/>
- </Col>
- }
- </Row>
- )}
- {
- !isAuthorized && scopes && scopes.size ? <div className="scopes">
- <h2>
- Scopes:
- <a onClick={this.selectScopes} data-all={true}>select all</a>
- <a onClick={this.selectScopes}>select none</a>
- </h2>
- { scopes.map((description, name) => {
- return (
- <Row key={ name }>
- <div className="checkbox">
- <Input data-value={ name }
- id={`${name}-${flow}-checkbox-${this.state.name}`}
- disabled={ isAuthorized }
- checked={ this.state.scopes.includes(name) }
- type="checkbox"
- onChange={ this.onScopeChange }/>
- <label htmlFor={`${name}-${flow}-checkbox-${this.state.name}`}>
- <span className="item"></span>
- <div className="text">
- <p className="name">{name}</p>
- <p className="description">{description}</p>
- </div>
- </label>
- </div>
- </Row>
- )
- }).toArray()
- }
- </div> : null
- }
- {
- errors.valueSeq().map( (error, key) => {
- return <AuthError error={ error }
- key={ key }/>
- } )
- }
- <div className="auth-btn-wrapper">
- { isValid &&
- ( isAuthorized ? <Button className="btn modal-btn auth authorize" onClick={ this.logout }>Logout</Button>
- : <Button className="btn modal-btn auth authorize" onClick={ this.authorize }>Authorize</Button>
- )
- }
- <Button className="btn modal-btn auth btn-done" onClick={ this.close }>Close</Button>
- </div>
- </div>
- )
- }
- }
|