Skip to content

Commit

Permalink
fix(oauth2): only display scopes relevant for current endpoint (#8229)
Browse files Browse the repository at this point in the history
* 'available authorization' popup: only show oauth2 scopes relevant for current endpoint (issue #8219)

* unit tests for oauth2 scope filter

Co-authored-by: Kai Morich <kai.morich@sap.com>
Co-authored-by: Tim Lai <timothy.lai@smartbear.com>
  • Loading branch information
3 people committed Oct 24, 2022
1 parent 9546375 commit 9457566
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 2 deletions.
23 changes: 21 additions & 2 deletions src/core/plugins/auth/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,28 @@ export const getDefinitionsByNames = ( state, securities ) => ( { specSelectors

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()))
let result = List()
allDefinitions.forEach( (definition) => {
let security = securities.find(sec => sec.get(definition.keySeq().first()))
if ( security ) {
definition.forEach( (props, name) => {
if ( props.get("type") === "oauth2" ) {
const securityScopes = security.get(name)
let definitionScopes = props.get("scopes")
if( List.isList(securityScopes) && Map.isMap(definitionScopes) ) {
definitionScopes.keySeq().forEach( (key) => {
if ( !securityScopes.contains(key) ) {
definitionScopes = definitionScopes.delete(key)
}
})
definition = definition.set(name, props.set("scopes", definitionScopes))
}
}
})
result = result.push(definition)
}
})
return result
}

export const authorized = createSelector(
Expand Down
96 changes: 96 additions & 0 deletions test/unit/core/plugins/auth/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,100 @@ describe("auth plugin - selectors", () => {
expect(res.toJS()).toEqual([])
})
})

it("should return only security definitions used by the endpoint", () => {
const securityDefinitions = {
"used": {
"type": "http",
"scheme": "basic",
},
"unused": {
"type": "http",
"scheme": "basic",
}
}

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

const securities = fromJS([
{
"used": [],
"undefined": [],
}
])

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

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

it("should return only oauth scopes used by the endpoint", () => {
const securityDefinitions = {
"oauth2": {
"type": "oauth2",
"flow": "clientCredentials",
"tokenUrl": "https://api.testserver.com/oauth2/token/",
"scopes": {
"used": "foo",
"unused": "bar"
}
},
"other": {
"type": "apiKey",
"name": "api_key",
"in": "header"
}

}

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

const securities = fromJS([
{
"oauth2": ["used", "undefined"],
"other": [],
}
])

let expectedOauth2Definitions = {...securityDefinitions["oauth2"]}
expectedOauth2Definitions["scopes"] = {"used": "foo"}

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

expect(res.toJS()).toEqual([
{
"oauth2": expectedOauth2Definitions,
"other": securityDefinitions["other"]
}
])
})

})

0 comments on commit 9457566

Please sign in to comment.