aboutsummaryrefslogtreecommitdiffstats
path: root/sdnr/wt/odlux/framework/src/views/login.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'sdnr/wt/odlux/framework/src/views/login.tsx')
-rw-r--r--sdnr/wt/odlux/framework/src/views/login.tsx210
1 files changed, 210 insertions, 0 deletions
diff --git a/sdnr/wt/odlux/framework/src/views/login.tsx b/sdnr/wt/odlux/framework/src/views/login.tsx
new file mode 100644
index 000000000..3f6ef6134
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/views/login.tsx
@@ -0,0 +1,210 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * 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.
+ * ============LICENSE_END==========================================================================
+ */
+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(3),
+ marginRight: theme.spacing(3),
+ [theme.breakpoints.up(400 + theme.spacing(3) * 2)]: {
+ width: 400,
+ marginLeft: 'auto',
+ marginRight: 'auto',
+ },
+ },
+ paper: {
+ marginTop: theme.spacing(8),
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ padding: `${theme.spacing(2)}px ${theme.spacing(3)}px ${theme.spacing(3)}px`,
+ },
+ avatar: {
+ margin: theme.spacing(1),
+ backgroundColor: theme.palette.secondary.main,
+ },
+ form: {
+ width: '100%', // Fix IE11 issue.
+ marginTop: theme.spacing(1),
+ },
+ submit: {
+ marginTop: theme.spacing(3),
+ },
+});
+
+type LoginProps = RouteComponentProps<{}> & WithStyles<typeof styles> & Connect;
+
+interface ILoginState {
+ busy: boolean;
+ username: string;
+ password: string;
+ scope: string;
+ message: string;
+}
+
+
+// todo: ggf. redirect to einbauen
+class LoginComponent extends React.Component<LoginProps, ILoginState> {
+
+ constructor(props: LoginProps) {
+ super(props);
+
+ this.state = {
+ busy: false,
+ username: '',
+ password: '',
+ scope: 'sdn',
+ message: ''
+ };
+ }
+
+ render(): JSX.Element {
+ const { classes } = this.props;
+ return (
+ <React.Fragment>
+ <CssBaseline />
+ <main className={classes.layout}>
+ <Paper className={classes.paper}>
+ <Avatar className={classes.avatar}>
+ <LockIcon />
+ </Avatar>
+ <Typography variant="caption">Sign in</Typography>
+ <form className={classes.form}>
+ <FormControl margin="normal" required fullWidth>
+ <InputLabel htmlFor="username">Username</InputLabel>
+ <Input id="username" name="username" autoComplete="username" autoFocus
+ disabled={this.state.busy}
+ value={this.state.username}
+ onChange={event => { this.setState({ username: event.target.value }) }} />
+ </FormControl>
+ <FormControl margin="normal" required fullWidth>
+ <InputLabel htmlFor="password">Password</InputLabel>
+ <Input
+ name="password"
+ type="password"
+ id="password"
+ autoComplete="current-password"
+ disabled={this.state.busy}
+ value={this.state.password}
+ onChange={event => { this.setState({ password: event.target.value }) }}
+ />
+ </FormControl>
+ <FormControl margin="normal" required fullWidth>
+ <InputLabel htmlFor="password">Domain</InputLabel>
+ <Input
+ name="scope"
+ type="scope"
+ id="scope"
+ disabled={this.state.busy}
+ value={this.state.scope}
+ onChange={event => { this.setState({ scope: event.target.value }) }}
+ />
+ </FormControl>
+ <FormControlLabel
+ control={<Checkbox value="remember" color="secondary" />}
+ label="Remember me"
+ />
+ <Button
+ type="submit"
+ fullWidth
+ variant="contained"
+ color="primary"
+ disabled={this.state.busy}
+ className={classes.submit}
+ onClick={this.onSignIn}
+ >
+ Sign in
+ </Button>
+ </form>
+ </Paper>
+ </main>
+ <Dialog
+ open={!!this.state.message}
+ onClose={() => { this.setState({ message: '' }) }}
+ aria-labelledby="alert-dialog-title"
+ aria-describedby="alert-dialog-description"
+ >
+ <DialogTitle id="alert-dialog-title">{"Error"}</DialogTitle>
+ <DialogContent>
+ <DialogContentText id="alert-dialog-description">
+ {this.state.message}
+ </DialogContentText>
+ </DialogContent>
+ <DialogActions>
+ <Button onClick={() => { this.setState({ message: '' }) }} color="secondary" autoFocus>
+ OK
+ </Button>
+ </DialogActions>
+ </Dialog>
+ </React.Fragment>
+ );
+ }
+
+ private onSignIn = async (event: React.MouseEvent<HTMLButtonElement>) => {
+ event.preventDefault();
+
+ this.setState({ busy: true });
+ const token = await authenticationService.authenticateUser(this.state.username, 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