improvement: oauth "scopes" improvements (#6037)
* improvement: oauth "scopes" init parameter * improvement: add "select all" and "select none" to oauth scopes popup
This commit is contained in:
committed by
GitHub
parent
4497387d62
commit
275c8f2ccf
@@ -62,6 +62,7 @@
|
||||
realm: "your-realms",
|
||||
appName: "your-app-name",
|
||||
scopeSeparator: " ",
|
||||
scopes: "openid profile email phone address",
|
||||
additionalQueryStringParams: {},
|
||||
usePkceWithAuthorizationCodeGrant: false
|
||||
})
|
||||
|
||||
@@ -23,6 +23,10 @@ const oauthBlockSchema = {
|
||||
type: "string",
|
||||
name: "scopeSeparator"
|
||||
},
|
||||
OAUTH_SCOPES: {
|
||||
type: "string",
|
||||
name: "scopes"
|
||||
},
|
||||
OAUTH_ADDITIONAL_PARAMS: {
|
||||
type: "object",
|
||||
name: "additionalQueryStringParams"
|
||||
@@ -44,4 +48,4 @@ ${indent(translatorResult, 2)}
|
||||
}
|
||||
|
||||
return ``
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ clientSecret | `OAUTH_CLIENT_SECRET` | **🚨 Never use this parameter in your p
|
||||
realm | `OAUTH_REALM` |realm query parameter (for oauth1) added to `authorizationUrl` and `tokenUrl`. MUST be a string
|
||||
appName | `OAUTH_APP_NAME` |application name, displayed in authorization popup. MUST be a string
|
||||
scopeSeparator | `OAUTH_SCOPE_SEPARATOR` |scope separator for passing scopes, encoded before calling, default value is a space (encoded value `%20`). MUST be a string
|
||||
scopes | `OAUTH_SCOPES` |string array or scope separator (i.e. space) separated string of initially selected oauth scopes, default is empty array
|
||||
additionalQueryStringParams | `OAUTH_ADDITIONAL_PARAMS` |Additional query parameters added to `authorizationUrl` and `tokenUrl`. MUST be an object
|
||||
useBasicAuthenticationWithAccessCodeGrant | _Unavailable_ |Only activated for the `accessCode` flow. During the `authorization_code` request to the `tokenUrl`, pass the [Client Password](https://tools.ietf.org/html/rfc6749#section-2.3.1) using the HTTP Basic Authentication scheme (`Authorization` header with `Basic base64encode(client_id + client_secret)`). The default is `false`
|
||||
usePkceWithAuthorizationCodeGrant | `OAUTH_USE_PKCE` | Only applies to `authorizatonCode` flows. [Proof Key for Code Exchange](https://tools.ietf.org/html/rfc7636) brings enhanced security for OAuth public clients. The default is `false`
|
||||
@@ -22,6 +23,7 @@ ui.initOAuth({
|
||||
realm: "your-realms",
|
||||
appName: "your-app-name",
|
||||
scopeSeparator: " ",
|
||||
scopes: "openid profile",
|
||||
additionalQueryStringParams: {test: "hello"},
|
||||
usePkceWithAuthorizationCodeGrant: true
|
||||
})
|
||||
|
||||
@@ -25,12 +25,16 @@ export default class Oauth2 extends React.Component {
|
||||
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: scopes,
|
||||
clientId: clientId,
|
||||
clientSecret: clientSecret,
|
||||
username: username,
|
||||
@@ -77,6 +81,16 @@ export default class Oauth2 extends React.Component {
|
||||
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
|
||||
@@ -201,7 +215,11 @@ export default class Oauth2 extends React.Component {
|
||||
|
||||
{
|
||||
!isAuthorized && scopes && scopes.size ? <div className="scopes">
|
||||
<h2>Scopes:</h2>
|
||||
<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 }>
|
||||
@@ -209,6 +227,7 @@ export default class Oauth2 extends React.Component {
|
||||
<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}`}>
|
||||
|
||||
@@ -76,6 +76,15 @@
|
||||
font-size: 14px;
|
||||
|
||||
@include text_headline();
|
||||
|
||||
a
|
||||
{
|
||||
font-size: 12px;
|
||||
color: $auth-select-all-none-link-font-color;
|
||||
cursor: pointer;
|
||||
padding-left: 10px;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ $_color-options: #0d5aa7 !default;
|
||||
// Authorize
|
||||
|
||||
$auth-container-border-color: $gray-50 !default;
|
||||
|
||||
$auth-select-all-none-link-font-color: $color-info !default;
|
||||
// Buttons
|
||||
|
||||
$btn-background-color: transparent !default;
|
||||
|
||||
@@ -70,6 +70,18 @@ module.exports = {
|
||||
authorizationUrl: {
|
||||
selector: ".auth-container code"
|
||||
},
|
||||
readPetsScope: {
|
||||
selector: "input[data-value='read:pets']"
|
||||
},
|
||||
writePetsScope: {
|
||||
selector: "input[data-value='write:pets']"
|
||||
},
|
||||
selectAllScopes: {
|
||||
selector: ".auth-container h2 a[data-all]"
|
||||
},
|
||||
selectNoneScopes: {
|
||||
selector: ".auth-container h2 a:not([data-all])"
|
||||
},
|
||||
flow: {
|
||||
selector: ".flow code"
|
||||
},
|
||||
|
||||
@@ -45,6 +45,16 @@ describe("Render scheme", function () {
|
||||
.assert.containsText("@authorizationUrl", "http://petstore.swagger.io/oauth/dialog")
|
||||
.assert.containsText("@flow", "implicit")
|
||||
.assert.value("@inputClientID", "your-client-id")
|
||||
schemeContainer.expect.element("@readPetsScope").to.be.selected
|
||||
schemeContainer.expect.element("@writePetsScope").to.not.be.selected
|
||||
|
||||
schemeContainer.click("@selectAllScopes")
|
||||
schemeContainer.expect.element("@readPetsScope").to.be.selected
|
||||
schemeContainer.expect.element("@writePetsScope").to.be.selected
|
||||
|
||||
schemeContainer.click("@selectNoneScopes")
|
||||
schemeContainer.expect.element("@readPetsScope").to.not.be.selected
|
||||
schemeContainer.expect.element("@writePetsScope").to.not.be.selected
|
||||
|
||||
client.end()
|
||||
})
|
||||
|
||||
@@ -101,6 +101,7 @@
|
||||
realm: "your-realms",
|
||||
appName: "your-app-name",
|
||||
scopeSeparator: " ",
|
||||
scopes: "read:pets profile openid",
|
||||
additionalQueryStringParams: {}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user