From 2d4424c28ac35763ef44c42ae2f01664d42b268c Mon Sep 17 00:00:00 2001 From: Herbert Eiselt Date: Tue, 12 Mar 2019 18:00:21 +0100 Subject: Security provider for UX-Client-Login Use ODL provided oauth2/token for UX clients Change-Id: I9f9ae931fc5e74dc13076bd23551d163c0685606 Issue-ID: SDNC-648 Signed-off-by: Herbert Eiselt --- sdnr/wt/odlux/framework/src/views/login.tsx | 336 ++++++++++++++++------------ 1 file changed, 192 insertions(+), 144 deletions(-) (limited to 'sdnr/wt/odlux/framework/src/views/login.tsx') diff --git a/sdnr/wt/odlux/framework/src/views/login.tsx b/sdnr/wt/odlux/framework/src/views/login.tsx index 6fa24e4ab..513e24712 100644 --- a/sdnr/wt/odlux/framework/src/views/login.tsx +++ b/sdnr/wt/odlux/framework/src/views/login.tsx @@ -1,145 +1,193 @@ -import * as React from 'react'; -import { withRouter, RouteComponentProps } from 'react-router-dom'; - -import Avatar from '@material-ui/core/Avatar'; -import Button from '@material-ui/core/Button'; -import CssBaseline from '@material-ui/core/CssBaseline'; -import FormControl from '@material-ui/core/FormControl'; -import FormControlLabel from '@material-ui/core/FormControlLabel'; -import Checkbox from '@material-ui/core/Checkbox'; -import Input from '@material-ui/core/Input'; -import InputLabel from '@material-ui/core/InputLabel'; -import LockIcon from '@material-ui/icons/LockOutlined'; -import Paper from '@material-ui/core/Paper'; -import Typography from '@material-ui/core/Typography'; -import { withStyles, WithStyles, createStyles, Theme } from '@material-ui/core/styles'; - -import connect, { Connect } from '../flux/connect'; -import authenticationService from '../services/authenticationService'; - -import { UpdateAuthentication } from '../actions/authentication'; - -const styles = (theme: Theme) => createStyles({ - layout: { - width: 'auto', - display: 'block', // Fix IE11 issue. - marginLeft: theme.spacing.unit * 3, - marginRight: theme.spacing.unit * 3, - [theme.breakpoints.up(400 + theme.spacing.unit * 3 * 2)]: { - width: 400, - marginLeft: 'auto', - marginRight: 'auto', - }, - }, - paper: { - marginTop: theme.spacing.unit * 8, - display: 'flex', - flexDirection: 'column', - alignItems: 'center', - padding: `${ theme.spacing.unit * 2 }px ${ theme.spacing.unit * 3 }px ${ theme.spacing.unit * 3 }px`, - }, - avatar: { - margin: theme.spacing.unit, - backgroundColor: theme.palette.secondary.main, - }, - form: { - width: '100%', // Fix IE11 issue. - marginTop: theme.spacing.unit, - }, - submit: { - marginTop: theme.spacing.unit * 3, - }, -}); - -type LoginProps = RouteComponentProps<{}> & WithStyles & Connect ; - -interface ILoginState { - busy: boolean; - email: string; - password: string; -} - - -// todo: ggf. redirect to einbauen -class LoginComponent extends React.Component { - - constructor(props: LoginProps) { - super(props); - - this.state = { - busy: false, - email: '', - password: '' - }; - } - - render(): JSX.Element { - const { classes } = this.props; - return ( - - -
- - - - - Sign in -
- - Email Address - { this.setState({ email: event.target.value }) } }/> - - - Password - { this.setState({ password: event.target.value }) } } - /> - - } - label="Remember me" - /> - - -
-
-
- ); - } - - private onSignIn = async (event: React.MouseEvent) => { - event.preventDefault(); - - this.setState({ busy: true }); - const token = await authenticationService.authenticateUser(this.state.email, this.state.password); - this.props.dispatch(new UpdateAuthentication(token)); - this.setState({ busy: false }); - - if (token) { - this.props.history.replace("/"); - } - - } -} - -export const Login = withStyles(styles)(withRouter(connect()(LoginComponent))); +import * as React from 'react'; +import { withRouter, RouteComponentProps } from 'react-router-dom'; + +import Avatar from '@material-ui/core/Avatar'; +import Button from '@material-ui/core/Button'; +import Dialog from '@material-ui/core/Dialog'; +import DialogActions from '@material-ui/core/DialogActions'; +import DialogContent from '@material-ui/core/DialogContent'; +import DialogContentText from '@material-ui/core/DialogContentText'; +import DialogTitle from '@material-ui/core/DialogTitle'; +import CssBaseline from '@material-ui/core/CssBaseline'; +import FormControl from '@material-ui/core/FormControl'; +import FormControlLabel from '@material-ui/core/FormControlLabel'; +import Checkbox from '@material-ui/core/Checkbox'; +import Input from '@material-ui/core/Input'; +import InputLabel from '@material-ui/core/InputLabel'; +import LockIcon from '@material-ui/icons/LockOutlined'; +import Paper from '@material-ui/core/Paper'; +import Typography from '@material-ui/core/Typography'; +import { withStyles, WithStyles, createStyles, Theme } from '@material-ui/core/styles'; + +import connect, { Connect } from '../flux/connect'; +import authenticationService from '../services/authenticationService'; + +import { UpdateAuthentication } from '../actions/authentication'; + +const styles = (theme: Theme) => createStyles({ + layout: { + width: 'auto', + display: 'block', // Fix IE11 issue. + marginLeft: theme.spacing.unit * 3, + marginRight: theme.spacing.unit * 3, + [theme.breakpoints.up(400 + theme.spacing.unit * 3 * 2)]: { + width: 400, + marginLeft: 'auto', + marginRight: 'auto', + }, + }, + paper: { + marginTop: theme.spacing.unit * 8, + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + padding: `${ theme.spacing.unit * 2 }px ${ theme.spacing.unit * 3 }px ${ theme.spacing.unit * 3 }px`, + }, + avatar: { + margin: theme.spacing.unit, + backgroundColor: theme.palette.secondary.main, + }, + form: { + width: '100%', // Fix IE11 issue. + marginTop: theme.spacing.unit, + }, + submit: { + marginTop: theme.spacing.unit * 3, + }, +}); + +type LoginProps = RouteComponentProps<{}> & WithStyles & Connect ; + +interface ILoginState { + busy: boolean; + email: string; + password: string; + scope: string; + message: string; +} + + +// todo: ggf. redirect to einbauen +class LoginComponent extends React.Component { + + constructor(props: LoginProps) { + super(props); + + this.state = { + busy: false, + email: '', + password: '', + scope: 'sdn', + message: '' + }; + } + + render(): JSX.Element { + const { classes } = this.props; + return ( + + +
+ + + + + Sign in +
+ + Email Address + { this.setState({ email: event.target.value }) } }/> + + + Password + { this.setState({ password: event.target.value }) } } + /> + + + Scope + { this.setState({ scope: event.target.value }) }} + /> + + } + label="Remember me" + /> + + +
+
+ { this.setState({message: ''})}} + aria-labelledby="alert-dialog-title" + aria-describedby="alert-dialog-description" + > + {"Error"} + + + { this.state.message } + + + + + + +
+ ); + } + + private onSignIn = async (event: React.MouseEvent) => { + event.preventDefault(); + + this.setState({ busy: true }); + const token = await authenticationService.authenticateUser(this.state.email, this.state.password, this.state.scope); + this.props.dispatch(new UpdateAuthentication(token)); + this.setState({ busy: false }); + + if (token) { + const query = + this.props.state.framework.navigationState.search && + this.props.state.framework.navigationState.search.replace(/^\?/, "") + .split('&').map(e => e.split("=")); + const returnTo = query && query.find(e => e[0] === "returnTo"); + this.props.history.replace(returnTo && returnTo[1] || "/"); + } + else { + this.setState({ + message: "Could not log in. Please check your credentials or ask your administrator for assistence.", + password: "" + }) + } + } +} + +export const Login = withStyles(styles)(withRouter(connect()(LoginComponent))); export default Login; \ No newline at end of file -- cgit 1.2.3-korg