Under the hood, this uses AuthProvider as supplied by oidc-react. Most of the theory is explained in the comment in ZuulAuthProvider.jsx The benefit of doing this is that we allow the AuthProvider and userManager to handle the callback logic, so we don't need to handle the callback logic ourselves. A callback page is still required though in order to deal with the parameters passed in a successful redirection from the Identity Provider. The challenge in using these classes as-is is that our authority endpoints (eg, the IDP itself) may change from one tenant to the next; these classes aren't set up for that. So we need to be careful about how and when we change those authority URLs. In terms of functionalities: if the default realm's authentication driver is set to "OpenIDConnect", display a "Sign in" button. If the the user is logged in, redirect to the last page visited prior to logging in; fetch user authorizations and add them to the redux store; display the user's preferred username in the upper right corner. Clicking on the user icon in the right corner displays a modal with user information such as the user's zuul-client configuration, and a sign out button. Clicking on the sign out button removes user information from the store (note that it does not log the user out from the Identity Provider). Add some basic documentation explaining how to configure Zuul with Google's authentication, and with a Keycloak server. (This squashes https://review.opendev.org/c/zuul/zuul/+/816208 into https://review.opendev.org/c/zuul/zuul/+/734082 ) Co-authored-by: James E. Blair <jim@acmegating.com> Change-Id: I31e71f2795f3f7c4253d0d5b8ed309bfd7d4f98e
111 lines
3.0 KiB
React
111 lines
3.0 KiB
React
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
// not use this file except in compliance with the License. You may obtain
|
|
// a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
// License for the specific language governing permissions and limitations
|
|
// under the License.
|
|
|
|
import PropTypes from 'prop-types'
|
|
import React from 'react'
|
|
import { connect } from 'react-redux'
|
|
import {
|
|
Button,
|
|
ButtonVariant,
|
|
Modal,
|
|
ModalVariant,
|
|
Switch
|
|
} from '@patternfly/react-core'
|
|
import { CogIcon } from '@patternfly/react-icons'
|
|
import { setPreference } from '../../actions/preferences'
|
|
|
|
class ConfigModal extends React.Component {
|
|
|
|
static propTypes = {
|
|
location: PropTypes.object,
|
|
tenant: PropTypes.object,
|
|
preferences: PropTypes.object,
|
|
timezone: PropTypes.string,
|
|
remoteData: PropTypes.object,
|
|
dispatch: PropTypes.func
|
|
}
|
|
|
|
constructor(props) {
|
|
super(props)
|
|
this.state = {
|
|
isModalOpen: false,
|
|
autoReload: false,
|
|
}
|
|
this.handleModalToggle = () => {
|
|
this.setState(({ isModalOpen }) => ({
|
|
isModalOpen: !isModalOpen
|
|
}))
|
|
this.resetState()
|
|
}
|
|
|
|
this.handleSave = () => {
|
|
this.handleModalToggle()
|
|
this.props.dispatch(setPreference('autoReload', this.state.autoReload))
|
|
}
|
|
|
|
this.handleAutoReload = () => {
|
|
this.setState(({ autoReload }) => ({
|
|
autoReload: !autoReload
|
|
}))
|
|
}
|
|
}
|
|
|
|
resetState() {
|
|
this.setState({
|
|
autoReload: this.props.preferences.autoReload,
|
|
})
|
|
}
|
|
|
|
render() {
|
|
const { isModalOpen, autoReload } = this.state
|
|
return (
|
|
<React.Fragment>
|
|
<Button
|
|
variant={ButtonVariant.plain}
|
|
key="cog"
|
|
onClick={this.handleModalToggle}>
|
|
<CogIcon />
|
|
</Button>
|
|
<Modal
|
|
variant={ModalVariant.small}
|
|
title="Preferences"
|
|
isOpen={isModalOpen}
|
|
onClose={this.handleModalToggle}
|
|
actions={[
|
|
<Button key="confirm" variant="primary" onClick={this.handleSave}>
|
|
Confirm
|
|
</Button>,
|
|
<Button key="cancel" variant="link" onClick={this.handleModalToggle}>
|
|
Cancel
|
|
</Button>
|
|
]}
|
|
>
|
|
<div>
|
|
<p key="info">Application settings are saved in browser local storage only. They are applied whether authenticated or not.</p>
|
|
<Switch
|
|
key="autoreload"
|
|
id="autoreload"
|
|
label="Auto reload status page"
|
|
isChecked={autoReload}
|
|
onChange={this.handleAutoReload}
|
|
/>
|
|
</div>
|
|
</Modal>
|
|
</React.Fragment>
|
|
)
|
|
}
|
|
}
|
|
|
|
export default connect(state => ({
|
|
preferences: state.preferences,
|
|
}))(ConfigModal)
|