switch to rfc8040 restconf
[ccsdk/features.git] / sdnr / wt / odlux / framework / src / views / login.tsx
1 /**
2  * ============LICENSE_START========================================================================
3  * ONAP : ccsdk feature sdnr wt odlux
4  * =================================================================================================
5  * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
6  * =================================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software distributed under the License
13  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14  * or implied. See the License for the specific language governing permissions and limitations under
15  * the License.
16  * ============LICENSE_END==========================================================================
17  */
18 import * as React from 'react';
19 import { withRouter, RouteComponentProps } from 'react-router-dom';
20
21 import Alert from '@material-ui/lab/Alert';
22 import Avatar from '@material-ui/core/Avatar';
23 import Button from '@material-ui/core/Button';
24 import CssBaseline from '@material-ui/core/CssBaseline';
25 import FormControl from '@material-ui/core/FormControl';
26 import FormControlLabel from '@material-ui/core/FormControlLabel';
27 import Checkbox from '@material-ui/core/Checkbox';
28 import Input from '@material-ui/core/Input';
29 import InputLabel from '@material-ui/core/InputLabel';
30 import LockIcon from '@material-ui/icons/LockOutlined';
31 import Paper from '@material-ui/core/Paper';
32 import Typography from '@material-ui/core/Typography';
33 import { withStyles, WithStyles, createStyles, Theme } from '@material-ui/core/styles';
34
35 import connect, { Connect } from '../flux/connect';
36 import authenticationService from '../services/authenticationService';
37
38 import { UpdateAuthentication } from '../actions/authentication';
39
40 const styles = (theme: Theme) => createStyles({
41   layout: {
42     width: 'auto',
43     display: 'block', // Fix IE11 issue.
44     marginLeft: theme.spacing(3),
45     marginRight: theme.spacing(3),
46     [theme.breakpoints.up(400 + theme.spacing(3) * 2)]: {
47       width: 400,
48       marginLeft: 'auto',
49       marginRight: 'auto',
50     },
51   },
52   paper: {
53     marginTop: theme.spacing(8),
54     display: 'flex',
55     flexDirection: 'column',
56     alignItems: 'center',
57     padding: `${theme.spacing(2)}px ${theme.spacing(3)}px ${theme.spacing(3)}px`,
58   },
59   avatar: {
60     margin: theme.spacing(1),
61     backgroundColor: theme.palette.secondary.main,
62   },
63   form: {
64     width: '100%', // Fix IE11 issue.
65     marginTop: theme.spacing(1),
66   },
67   submit: {
68     marginTop: theme.spacing(3),
69   },
70 });
71
72 type LoginProps = RouteComponentProps<{}> & WithStyles<typeof styles> & Connect;
73
74 interface ILoginState {
75   busy: boolean;
76   username: string;
77   password: string;
78   scope: string;
79   message: string;
80 }
81
82
83 // todo: ggf. redirect to einbauen
84 class LoginComponent extends React.Component<LoginProps, ILoginState> {
85
86   constructor(props: LoginProps) {
87     super(props);
88
89     this.state = {
90       busy: false,
91       username: '',
92       password: '',
93       scope: 'sdn',
94       message: ''
95     };
96   }
97
98   render(): JSX.Element {
99     const { classes } = this.props;
100     return (
101       <>
102         <CssBaseline />
103         <main className={classes.layout}>
104           <Paper className={classes.paper}>
105             <Avatar className={classes.avatar}>
106               <LockIcon />
107             </Avatar>
108             <Typography variant="caption">Sign in</Typography>
109             <form className={classes.form}>
110               <FormControl margin="normal" required fullWidth>
111                 <InputLabel htmlFor="username">Username</InputLabel>
112                 <Input id="username" name="username" autoComplete="username" autoFocus
113                   disabled={this.state.busy}
114                   value={this.state.username}
115                   onChange={event => { this.setState({ username: event.target.value }) }} />
116               </FormControl>
117               <FormControl margin="normal" required fullWidth>
118                 <InputLabel htmlFor="password">Password</InputLabel>
119                 <Input
120                   name="password"
121                   type="password"
122                   id="password"
123                   autoComplete="current-password"
124                   disabled={this.state.busy}
125                   value={this.state.password}
126                   onChange={event => { this.setState({ password: event.target.value }) }}
127                 />
128               </FormControl>
129               <FormControl margin="normal" required fullWidth>
130                 <InputLabel htmlFor="password">Domain</InputLabel>
131                 <Input
132                   name="scope"
133                   type="scope"
134                   id="scope"
135                   disabled={this.state.busy}
136                   value={this.state.scope}
137                   onChange={event => { this.setState({ scope: event.target.value }) }}
138                 />
139               </FormControl>
140               <FormControlLabel
141                 control={<Checkbox value="remember" color="secondary" />}
142                 label="Remember me"
143               />
144               <Button
145                 type="submit"
146                 fullWidth
147                 variant="contained"
148                 color="primary"
149                 disabled={this.state.busy}
150                 className={classes.submit}
151                 onClick={this.onSignIn}
152               >
153                 Sign in
154             </Button>
155             </form>
156             {this.state.message && <Alert severity="error">{this.state.message}</Alert>}
157           </Paper>
158         </main>
159       </>
160     );
161   }
162
163   private onSignIn = async (event: React.MouseEvent<HTMLButtonElement>) => {
164     event.preventDefault();
165
166     this.setState({ busy: true });
167     // const token = await authenticationService.authenticateUserOAuth(this.state.username, this.state.password, this.state.scope);
168     const token = await authenticationService.authenticateUserBasicAuth(this.state.username, this.state.password, this.state.scope); 
169     this.props.dispatch(new UpdateAuthentication(token));
170     this.setState({ busy: false });
171
172     if (token) {
173       const query =
174         this.props.state.framework.navigationState.search &&
175         this.props.state.framework.navigationState.search.replace(/^\?/, "")
176           .split('&').map(e => e.split("="));
177       const returnTo = query && query.find(e => e[0] === "returnTo");
178       this.props.history.replace(returnTo && returnTo[1] || "/");
179     }
180     else {
181       this.setState({
182         message: "Could not log in. Please check your credentials or ask your administrator for assistence.",
183         password: ""
184       })
185     }
186   }
187 }
188
189 export const Login = withStyles(styles)(withRouter(connect()(LoginComponent)));
190 export default Login;