Browse Source

Merge pull request #3870 from swagger-api/bug/auth-operation-btn-error

Bug/auth operation btn error
bubble
kyle 6 years ago
committed by GitHub
parent
commit
076f32b1f0
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 168 additions and 22 deletions
  1. +1
    -0
      .gitignore
  2. +8
    -0
      package.json
  3. +10
    -18
      src/core/components/auth/authorize-operation-btn.jsx
  4. +7
    -3
      src/core/components/operation.jsx
  5. +9
    -1
      src/core/plugins/auth/selectors.js
  6. +133
    -0
      test/core/plugins/auth/selectors.js

+ 1
- 0
.gitignore View File

@@ -2,6 +2,7 @@ node_modules
.idea
.deps_check
.DS_Store
.nyc_output
npm-debug.log*
.eslintcache
package-lock.json


+ 8
- 0
package.json View File

@@ -33,6 +33,7 @@
"test-in-node": "npm run lint-errors && npm run just-test-in-node",
"just-test": "karma start --config karma.conf.js",
"just-test-in-node": "mocha --recursive --compilers js:babel-core/register test/core test/components test/bugs test/swagger-ui-dist-package test/xss",
"just-check-coverage": "nyc npm run just-test-in-node",
"test-e2e": "sleep 3 && nightwatch test/e2e/scenarios/ --config test/e2e/nightwatch.json",
"e2e-initial-render": "nightwatch test/e2e/scenarios/ --config test/e2e/nightwatch.json --group initial-render",
"mock-api": "json-server --watch test/e2e/db.json --port 3204",
@@ -127,6 +128,7 @@
"node-sass": "^4.5.0",
"npm-run-all": "4.0.2",
"null-loader": "0.1.1",
"nyc": "^11.3.0",
"open": "0.0.5",
"postcss-loader": "2.0.6",
"raw-loader": "0.5.1",
@@ -152,5 +154,11 @@
],
"optionalDependencies": {
"webpack-dev-server": "2.5.0"
},
"nyc": {
"all": true,
"include": [
"**/src/core/plugins/**.js"
]
}
}

+ 10
- 18
src/core/components/auth/authorize-operation-btn.jsx View File

@@ -1,25 +1,23 @@
import React from "react"
import PropTypes from "prop-types"
import ImPropTypes from "react-immutable-proptypes"

export default class AuthorizeOperationBtn extends React.Component {
static propTypes = {
isAuthorized: PropTypes.bool.isRequired,
onClick: PropTypes.func
}

onClick =(e) => {
e.stopPropagation()
let { onClick } = this.props

let { security, authActions, authSelectors } = this.props
let definitions = authSelectors.getDefinitionsByNames(security)

authActions.showDefinitions(definitions)
if(onClick) {
onClick()
}
}

render() {
let { security, authSelectors } = this.props

let isAuthorized = authSelectors.isAuthorized(security)

if(isAuthorized === null) {
return null
}
let { isAuthorized } = this.props

return (
<button className={isAuthorized ? "authorization__btn locked" : "authorization__btn unlocked"} onClick={ this.onClick }>
@@ -30,10 +28,4 @@ export default class AuthorizeOperationBtn extends React.Component {

)
}

static propTypes = {
authSelectors: PropTypes.object.isRequired,
authActions: PropTypes.object.isRequired,
security: ImPropTypes.iterable.isRequired
}
}

+ 7
- 3
src/core/components/operation.jsx View File

@@ -183,9 +183,13 @@ export default class Operation extends PureComponent {

{
(!security || !security.count()) ? null :
<AuthorizeOperationBtn authActions={ authActions }
security={ security }
authSelectors={ authSelectors }/>
<AuthorizeOperationBtn
isAuthorized={ authSelectors.isAuthorized(security) }
onClick={() => {
const applicableDefinitions = authSelectors.definitionsForRequirements(security)
authActions.showDefinitions(applicableDefinitions)
}}
/>
}
</div>



+ 9
- 1
src/core/plugins/auth/selectors.js View File

@@ -11,7 +11,7 @@ export const shownDefinitions = createSelector(
export const definitionsToAuthorize = createSelector(
state,
() => ( { specSelectors } ) => {
let definitions = specSelectors.securityDefinitions()
let definitions = specSelectors.securityDefinitions() || Map({})
let list = List()

//todo refactor
@@ -28,6 +28,7 @@ export const definitionsToAuthorize = createSelector(


export const getDefinitionsByNames = ( state, securities ) => ( { specSelectors } ) => {
console.warn("WARNING: getDefinitionsByNames is deprecated and will be removed in the next major version.")
let securityDefinitions = specSelectors.securityDefinitions()
let result = List()

@@ -58,6 +59,13 @@ export const getDefinitionsByNames = ( state, securities ) => ( { specSelectors
return result
}

export const definitionsForRequirements = (state, securities = List()) => ({ authSelectors }) => {
const allDefinitions = authSelectors.definitionsToAuthorize() || List()
return allDefinitions.filter((def) => {
return securities.some(sec => sec.get(def.keySeq().first()))
})
}

export const authorized = createSelector(
state,
auth => auth.get("authorized") || Map()


+ 133
- 0
test/core/plugins/auth/selectors.js View File

@@ -0,0 +1,133 @@
/* eslint-env mocha */
import expect from "expect"
import { fromJS } from "immutable"
import { definitionsToAuthorize, definitionsForRequirements } from "corePlugins/auth/selectors"

describe("auth plugin - selectors", () => {
describe("definitionsToAuthorize", () => {
it("should return securityDefinitions as a List", () => {
const securityDefinitions = {
"petstore_auth": {
"type": "oauth2",
"authorizationUrl": "http://petstore.swagger.io/oauth/dialog",
"flow": "implicit",
"scopes": {
"write:pets": "modify pets in your account",
"read:pets": "read your pets"
}
},
"api_key": {
"type": "apiKey",
"name": "api_key",
"in": "header"
}
}

const system = {
specSelectors: {
securityDefinitions() {
return fromJS(securityDefinitions)
}
}
}

const res = definitionsToAuthorize({})(system)

expect(res.toJS()).toEqual([
{
"petstore_auth": securityDefinitions["petstore_auth"]
},
{
"api_key": securityDefinitions["api_key"]
},
])
})

it("should fail gracefully with bad data", () => {
const securityDefinitions = null

const system = {
specSelectors: {
securityDefinitions() {
return fromJS(securityDefinitions)
}
}
}

const res = definitionsToAuthorize({})(system)

expect(res.toJS()).toEqual([])
})
})

describe("definitionsForRequirements", () => {
it("should return applicable securityDefinitions as a List", () => {
const securityDefinitions = {
"petstore_auth": {
"type": "oauth2",
"authorizationUrl": "http://petstore.swagger.io/oauth/dialog",
"flow": "implicit",
"scopes": {
"write:pets": "modify pets in your account",
"read:pets": "read your pets"
}
},
"api_key": {
"type": "apiKey",
"name": "api_key",
"in": "header"
}
}

const system = {
authSelectors: {
definitionsToAuthorize() {
return fromJS([
{
"petstore_auth": securityDefinitions["petstore_auth"]
},
{
"api_key": securityDefinitions["api_key"]
},
])
}
}
}

const securities = fromJS([
{
"petstore_auth": [
"write:pets",
"read:pets"
]
}
])

const res = definitionsForRequirements({}, securities)(system)

expect(res.toJS()).toEqual([
{
"petstore_auth": securityDefinitions["petstore_auth"]
}
])
})

it("should fail gracefully with bad data", () => {
const securityDefinitions = null

const system = {
authSelectors: {
definitionsToAuthorize() {
return null
}
}
}

const securities = null

const res = definitionsForRequirements({}, securities)(system)

expect(res.toJS()).toEqual([])
})
})
})

Loading…
Cancel
Save