aboutsummaryrefslogtreecommitdiffstats
path: root/sdnr/wt/odlux/framework/src/views
diff options
context:
space:
mode:
authorAijana Schumann <aijana.schumann@highstreet-technologies.com>2021-02-15 18:22:28 +0100
committerAijana Schumann <aijana.schumann@highstreet-technologies.com>2021-02-15 18:23:57 +0100
commit8515052e1a6de2de56effbc61c73d3aa80169a93 (patch)
tree8707b2b587890522b35cd7dd1b54ce4f006f1c3a /sdnr/wt/odlux/framework/src/views
parentdb20d36689c011333ed7216b64d3e987e473f1ee (diff)
Add OAuth support to odlux
Extend odlux to support oauth, support external login provider for sign-in Issue-ID: CCSDK-3167 Signed-off-by: Aijana Schumann <aijana.schumann@highstreet-technologies.com> Change-Id: Id5772e0026fa7ebda22c41c2620a7868598f41aa
Diffstat (limited to 'sdnr/wt/odlux/framework/src/views')
-rw-r--r--sdnr/wt/odlux/framework/src/views/frame.tsx40
-rw-r--r--sdnr/wt/odlux/framework/src/views/login.tsx92
2 files changed, 100 insertions, 32 deletions
diff --git a/sdnr/wt/odlux/framework/src/views/frame.tsx b/sdnr/wt/odlux/framework/src/views/frame.tsx
index c8e24fdb9..b4cc43e0b 100644
--- a/sdnr/wt/odlux/framework/src/views/frame.tsx
+++ b/sdnr/wt/odlux/framework/src/views/frame.tsx
@@ -80,32 +80,32 @@ class FrameComponent extends React.Component<FrameProps>{
}
<Switch>
<Route exact path="/" component={() => (
- <AppFrame title={"Home"} icon={faHome} >
- <Home />
- </AppFrame>
+ <AppFrame title={"Home"} icon={faHome} >
+ <Home />
+ </AppFrame>
)} />
<Route path="/about" component={() => (
- <AppFrame title={"About"} icon={faAddressBook} >
- <About />
- </AppFrame>
+ <AppFrame title={"About"} icon={faAddressBook} >
+ <About />
+ </AppFrame>
)} />
{process.env.NODE_ENV === "development" ? <Route path="/test" component={() => (
- <AppFrame title={"Test"} icon={faAddressBook} >
- <Test />
- </AppFrame>
+ <AppFrame title={"Test"} icon={faAddressBook} >
+ <Test />
+ </AppFrame>
)} /> : null}
<Route path="/login" component={() => (
- <AppFrame title={"Login"} icon={faSignInAlt} >
- <Login />
- </AppFrame>
- )} />
- {Object.keys(registrations).map(p => {
- const application = registrations[p];
- return (<Route key={application.name} path={application.path || `/${application.name}`} component={() => (
- <AppFrame title={application.title || (typeof application.menuEntry === 'string' && application.menuEntry) || application.name} icon={application.icon} appId={application.name} >
- <application.rootComponent />
- </AppFrame>
- )} />)
+ <AppFrame title={"Login"} icon={faSignInAlt} >
+ <Login />
+ </AppFrame>
+ )} />
+ { Object.keys(registrations).map(p => {
+ const application = registrations[p];
+ return (<Route key={application.name} path={application.path || `/${application.name}`} component={() => (
+ <AppFrame title={application.title || (typeof application.menuEntry === 'string' && application.menuEntry) || application.name} icon={application.icon} appId={application.name} >
+ <application.rootComponent />
+ </AppFrame>
+ )} />)
})}
<Redirect to="/" />
</Switch>
diff --git a/sdnr/wt/odlux/framework/src/views/login.tsx b/sdnr/wt/odlux/framework/src/views/login.tsx
index b06cf7631..be1fb801f 100644
--- a/sdnr/wt/odlux/framework/src/views/login.tsx
+++ b/sdnr/wt/odlux/framework/src/views/login.tsx
@@ -32,10 +32,16 @@ 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 connect, { Connect, IDispatcher } from '../flux/connect';
import authenticationService from '../services/authenticationService';
-import { UpdateAuthentication } from '../actions/authentication';
+import { updateExternalLoginProviderAsyncActionCreator } from '../actions/loginProvider';
+import { UpdatePolicies, UpdateUser } from '../actions/authentication';
+
+import { IApplicationStoreState } from '../store/applicationStore';
+import { AuthPolicy, AuthToken, User } from '../models/authentication';
+import Menu from '@material-ui/core/Menu';
+import { MenuItem } from '@material-ui/core';
const styles = (theme: Theme) => createStyles({
layout: {
@@ -69,14 +75,37 @@ const styles = (theme: Theme) => createStyles({
},
});
-type LoginProps = RouteComponentProps<{}> & WithStyles<typeof styles> & Connect;
+const mapProps = (state: IApplicationStoreState) => ({
+ search: state.framework.navigationState.search,
+ authentication: state.framework.applicationState.authentication,
+ externalLoginProviders: state.framework.applicationState.externalLoginProviders ,
+});
+
+const mapDispatch = (dispatcher: IDispatcher) => ({
+ updateExternalProviders: () => dispatcher.dispatch(updateExternalLoginProviderAsyncActionCreator()),
+ updateAuthentication: (token: AuthToken | null) => {
+ const user = token && new User(token) || undefined;
+ dispatcher.dispatch(new UpdateUser(user));
+ },
+ updatePolicies: (policies?: AuthPolicy[]) => {
+ return dispatcher.dispatch(new UpdatePolicies(policies));
+ },
+});
+
+type LoginProps = RouteComponentProps<{}> & WithStyles<typeof styles> & Connect<typeof mapProps, typeof mapDispatch>;
interface ILoginState {
+ externalProviderAnchor: HTMLElement | null;
busy: boolean;
username: string;
password: string;
scope: string;
message: string;
+ providers: {
+ id: string;
+ title: string;
+ loginUrl: string;
+ }[] | null;
}
@@ -87,14 +116,26 @@ class LoginComponent extends React.Component<LoginProps, ILoginState> {
super(props);
this.state = {
+ externalProviderAnchor: null,
busy: false,
username: '',
password: '',
scope: 'sdn',
- message: ''
+ message: '',
+ providers: null,
};
}
+ async componentDidMount(){
+ if (this.props.authentication === "oauth" && (this.props.externalLoginProviders == null || this.props.externalLoginProviders.length === 0)){
+ this.props.updateExternalProviders();
+ }
+ }
+
+ private setExternalProviderAnchor = (el: HTMLElement | null) => {
+ this.setState({externalProviderAnchor: el })
+ }
+
render(): JSX.Element {
const { classes } = this.props;
return (
@@ -153,6 +194,33 @@ class LoginComponent extends React.Component<LoginProps, ILoginState> {
>
Sign in
</Button>
+ { this.props.externalLoginProviders && this.props.externalLoginProviders.length > 0
+ ?
+ [
+ <Button
+ aria-controls="externalLogin"
+ aria-haspopup="true"
+ fullWidth
+ variant="contained"
+ color="primary"
+ className={classes.submit} onClick={(ev) => { this.setExternalProviderAnchor(ev.currentTarget); }}>
+ Use external Login
+ </Button>,
+ <Menu
+ anchorEl={this.state.externalProviderAnchor}
+ keepMounted
+ open={Boolean(this.state.externalProviderAnchor)}
+ onClose={() => { this.setExternalProviderAnchor(null); }}
+ >
+ {
+ this.props.externalLoginProviders.map((provider) => (
+ <MenuItem key={provider.id} onClick={() => { window.location = provider.loginUrl as any; } }>{ provider.title} </MenuItem>
+ ))
+ }
+ </Menu>
+ ]
+ : null
+ }
</form>
{this.state.message && <Alert severity="error">{this.state.message}</Alert>}
</Paper>
@@ -165,16 +233,16 @@ class LoginComponent extends React.Component<LoginProps, ILoginState> {
event.preventDefault();
this.setState({ busy: true });
- // const token = await authenticationService.authenticateUserOAuth(this.state.username, this.state.password, this.state.scope);
- const token = await authenticationService.authenticateUserBasicAuth(this.state.username, this.state.password, this.state.scope);
- this.props.dispatch(new UpdateAuthentication(token));
+
+ const token = this.props.authentication === "oauth"
+ ? await authenticationService.authenticateUserOAuth(this.state.username, this.state.password, this.state.scope)
+ : await authenticationService.authenticateUserBasicAuth(this.state.username, this.state.password, this.state.scope);
+
+ this.props.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 query = this.props.search && this.props.search.replace(/^\?/, "").split('&').map(e => e.split("="));
const returnTo = query && query.find(e => e[0] === "returnTo");
this.props.history.replace(returnTo && returnTo[1] || "/");
}
@@ -187,5 +255,5 @@ class LoginComponent extends React.Component<LoginProps, ILoginState> {
}
}
-export const Login = withStyles(styles)(withRouter(connect()(LoginComponent)));
+export const Login = withStyles(styles)(withRouter(connect(mapProps, mapDispatch)(LoginComponent)));
export default Login; \ No newline at end of file