From 8515052e1a6de2de56effbc61c73d3aa80169a93 Mon Sep 17 00:00:00 2001 From: Aijana Schumann Date: Mon, 15 Feb 2021 18:22:28 +0100 Subject: 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 Change-Id: Id5772e0026fa7ebda22c41c2620a7868598f41aa --- sdnr/wt/odlux/framework/pom.xml | 70 +++++++++++++++- .../odlux/framework/src/actions/authentication.ts | 13 ++- .../odlux/framework/src/actions/loginProvider.ts | 36 +++++++++ sdnr/wt/odlux/framework/src/app.tsx | 30 ++++--- sdnr/wt/odlux/framework/src/assets/version.json | 4 +- .../wt/odlux/framework/src/components/titleBar.tsx | 4 +- .../src/handlers/applicationStateHandler.ts | 52 +++++++++--- .../src/handlers/authenticationHandler.ts | 28 +++---- sdnr/wt/odlux/framework/src/index.html | 1 + .../odlux/framework/src/middleware/navigation.ts | 19 ++++- sdnr/wt/odlux/framework/src/middleware/policies.ts | 41 ++++++++++ .../framework/src/models/applicationConfig.ts | 4 + .../odlux/framework/src/models/authentication.ts | 10 +++ .../framework/src/models/externalLoginProvider.ts | 23 ++++++ sdnr/wt/odlux/framework/src/run.ts | 1 + .../src/services/authenticationService.ts | 32 +++++--- .../framework/src/services/forceLogoutService.ts | 4 +- .../odlux/framework/src/store/applicationStore.ts | 3 +- sdnr/wt/odlux/framework/src/views/frame.tsx | 40 +++++----- sdnr/wt/odlux/framework/src/views/login.tsx | 92 +++++++++++++++++++--- .../framework/src2/main/resources/version.json | 17 +++- sdnr/wt/odlux/framework/webpack.config.js | 47 ++++++++--- 22 files changed, 469 insertions(+), 102 deletions(-) create mode 100644 sdnr/wt/odlux/framework/src/actions/loginProvider.ts create mode 100644 sdnr/wt/odlux/framework/src/middleware/policies.ts create mode 100644 sdnr/wt/odlux/framework/src/models/applicationConfig.ts create mode 100644 sdnr/wt/odlux/framework/src/models/externalLoginProvider.ts (limited to 'sdnr/wt/odlux/framework') diff --git a/sdnr/wt/odlux/framework/pom.xml b/sdnr/wt/odlux/framework/pom.xml index daedd9d3c..23854b55a 100644 --- a/sdnr/wt/odlux/framework/pom.xml +++ b/sdnr/wt/odlux/framework/pom.xml @@ -46,7 +46,7 @@ ${maven.build.timestamp} ONAP Frankfurt (Neon, mdsal ${odl.mdsal.version}) - 88.1c38886(20/12/04) + 89.977e4de(21/02/10) ONAP SDN-R | ONF Wireless for ${distversion} - Build: ${buildtime} ${buildno} ${project.version} @@ -158,6 +158,24 @@ org.apache.maven.plugins maven-jar-plugin + + + org.codehaus.mojo + properties-maven-plugin + 1.0.0 + + + initialize + + read-project-properties + + + + ${basedir}/../odlux.properties + + + + com.google.code.maven-replacer-plugin @@ -183,7 +201,7 @@ ##odlux.version## ${odlux.version} - + ##buildno## ${buildno} @@ -191,6 +209,54 @@ ##build-timestamp## ${buildtime} + + ##odlux.framework.buildno## + ${odlux.framework.buildno} + + + ##odlux.apps.configurationApp.buildno## + ${odlux.apps.configurationApp.buildno} + + + ##odlux.apps.connectApp.buildno## + ${odlux.apps.connectApp.buildno} + + + ##odlux.apps.eventLogApp.buildno## + ${odlux.apps.eventLogApp.buildno} + + + ##odlux.apps.faultApp.buildno## + ${odlux.apps.faultApp.buildno} + + + ##odlux.apps.helpApp.buildno## + ${odlux.apps.helpApp.buildno} + + + ##odlux.apps.inventoryApp.buildno## + ${odlux.apps.inventoryApp.buildno} + + + ##odlux.apps.linkCalculationApp.buildno## + ${odlux.apps.linkCalculationApp.buildno} + + + ##odlux.apps.maintenanceApp.buildno## + ${odlux.apps.maintenanceApp.buildno} + + + ##odlux.apps.mediatorApp.buildno## + ${odlux.apps.mediatorApp.buildno} + + + ##odlux.apps.networkMapApp.buildno## + ${odlux.apps.networkMapApp.buildno} + + + ##odlux.apps.permanceHistoryApp.buildno## + ${odlux.apps.permanceHistoryApp.buildno} + diff --git a/sdnr/wt/odlux/framework/src/actions/authentication.ts b/sdnr/wt/odlux/framework/src/actions/authentication.ts index b28100035..de8093573 100644 --- a/sdnr/wt/odlux/framework/src/actions/authentication.ts +++ b/sdnr/wt/odlux/framework/src/actions/authentication.ts @@ -16,11 +16,18 @@ * ============LICENSE_END========================================================================== */ import { Action } from '../flux/action'; -import { AuthToken } from '../models/authentication'; +import { AuthPolicy, User } from '../models/authentication'; -export class UpdateAuthentication extends Action { +export class UpdateUser extends Action { - constructor (public bearerToken: AuthToken | null) { + constructor (public user?: User) { + super(); + } +} + +export class UpdatePolicies extends Action { + + constructor (public authPolicies?: AuthPolicy[]) { super(); } } \ No newline at end of file diff --git a/sdnr/wt/odlux/framework/src/actions/loginProvider.ts b/sdnr/wt/odlux/framework/src/actions/loginProvider.ts new file mode 100644 index 000000000..e6467111e --- /dev/null +++ b/sdnr/wt/odlux/framework/src/actions/loginProvider.ts @@ -0,0 +1,36 @@ +/** + * ============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 { Action } from '../flux/action'; +import { Dispatch } from '../flux/store'; + +import { IApplicationStoreState } from '../store/applicationStore'; +import { ExternalLoginProvider } from '../models/externalLoginProvider'; + +import authenticationService from '../services/authenticationService'; + +export class SetExternalLoginProviderAction extends Action { + constructor(public externalLoginProvders: ExternalLoginProvider[] | null) { + super(); + } +} + +export const updateExternalLoginProviderAsyncActionCreator = () => async (dispatch: Dispatch, getState: () => IApplicationStoreState ) => { + const providers = await authenticationService.getAvaliableExteralProvider(); + dispatch(new SetExternalLoginProviderAction(providers || null)); +} \ No newline at end of file diff --git a/sdnr/wt/odlux/framework/src/app.tsx b/sdnr/wt/odlux/framework/src/app.tsx index 6a24bfb2a..23ae2fbc9 100644 --- a/sdnr/wt/odlux/framework/src/app.tsx +++ b/sdnr/wt/odlux/framework/src/app.tsx @@ -23,7 +23,10 @@ import { MuiThemeProvider } from '@material-ui/core/styles'; import { Frame } from './views/frame'; +import { User } from './models/authentication'; + import { AddErrorInfoAction } from './actions/errorActions'; +import { UpdateUser } from './actions/authentication'; import { applicationStoreCreator } from './store/applicationStore'; import { ApplicationStoreProvider } from './flux/connect'; @@ -31,12 +34,11 @@ import { ApplicationStoreProvider } from './flux/connect'; import { startHistoryListener } from './middleware/navigation'; import { startRestService } from './services/restService'; +import { startForceLogoutService } from './services/forceLogoutService'; +import { startNotificationService } from './services/notificationService'; import theme from './design/default'; import '!style-loader!css-loader!./app.css'; -import { ReplaceAction } from './actions/navigationActions'; -import { startForceLogoutService } from './services/forceLogoutService'; -import { startNotificationService } from './services/notificationService'; declare module '@material-ui/core/styles/createMuiTheme' { @@ -57,9 +59,13 @@ declare module '@material-ui/core/styles/createMuiTheme' { } } +export { configureApplication } from "./handlers/applicationStateHandler"; + export const transportPCEUrl = "transportPCEUrl"; export const runApplication = () => { + + const initialToken = localStorage.getItem("userToken"); const applicationStore = applicationStoreCreator(); window.onerror = function (msg: string, url: string, line: number, col: number, error: Error) { @@ -81,7 +87,6 @@ export const runApplication = () => { startHistoryListener(applicationStore); startForceLogoutService(applicationStore); startNotificationService(applicationStore); - addTransportPCEUrl(); const App = (): JSX.Element => ( @@ -93,12 +98,19 @@ export const runApplication = () => { ReactDOM.render(, document.getElementById('app')); + if (initialToken) { + applicationStore.dispatch(new UpdateUser(User.fromString(initialToken) || undefined)); + } + }; -const addTransportPCEUrl = () =>{ - const url = window.localStorage.getItem(transportPCEUrl); - if(url === null){ - window.localStorage.setItem(transportPCEUrl, "http://10.20.6.32:18082/"); - console.log("set transport url :D") +if (process.env.NODE_ENV === "development") { + const addTransportPCEUrl = () =>{ + const url = window.localStorage.getItem(transportPCEUrl); + if(url === null){ + window.localStorage.setItem(transportPCEUrl, "http://10.20.6.32:18082/"); + console.log("set transport url :D") + } } + addTransportPCEUrl(); } diff --git a/sdnr/wt/odlux/framework/src/assets/version.json b/sdnr/wt/odlux/framework/src/assets/version.json index 260aec4ea..6d4eb0cc6 100644 --- a/sdnr/wt/odlux/framework/src/assets/version.json +++ b/sdnr/wt/odlux/framework/src/assets/version.json @@ -1,4 +1,4 @@ { - "version":"88.1c38886(20/12/04)", - "build":"2020-12-04T06:06:24Z" + "version":"56.139cd6d(20/07/08)", + "build":"2020-07-16T06:06:24Z" } \ No newline at end of file diff --git a/sdnr/wt/odlux/framework/src/components/titleBar.tsx b/sdnr/wt/odlux/framework/src/components/titleBar.tsx index 49c096691..62db1de40 100644 --- a/sdnr/wt/odlux/framework/src/components/titleBar.tsx +++ b/sdnr/wt/odlux/framework/src/components/titleBar.tsx @@ -35,7 +35,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faBan } from '@fortawesome/free-solid-svg-icons'; import { faDotCircle } from '@fortawesome/free-solid-svg-icons'; -import { UpdateAuthentication } from '../actions/authentication'; +import { UpdateUser } from '../actions/authentication'; import { ReplaceAction } from '../actions/navigationActions'; import connect, { Connect, IDispatcher } from '../flux/connect'; @@ -71,7 +71,7 @@ const styles = (theme: Theme) => createStyles({ const mapDispatch = (dispatcher: IDispatcher) => { return { logout: () => { - dispatcher.dispatch(new UpdateAuthentication(null)); + dispatcher.dispatch(new UpdateUser(undefined)); dispatcher.dispatch(new ReplaceAction("/login")); }, toggleMainMenu: (value: boolean, value2: boolean) => { diff --git a/sdnr/wt/odlux/framework/src/handlers/applicationStateHandler.ts b/sdnr/wt/odlux/framework/src/handlers/applicationStateHandler.ts index a93f96a82..b5c1ee7b1 100644 --- a/sdnr/wt/odlux/framework/src/handlers/applicationStateHandler.ts +++ b/sdnr/wt/odlux/framework/src/handlers/applicationStateHandler.ts @@ -16,16 +16,19 @@ * ============LICENSE_END========================================================================== */ import { IActionHandler } from '../flux/action'; -import { SetTitleAction } from '../actions/titleActions'; +import { SetTitleAction } from '../actions/titleActions'; +import { SetExternalLoginProviderAction } from '../actions/loginProvider'; import { AddSnackbarNotification, RemoveSnackbarNotification } from '../actions/snackbarActions'; import { AddErrorInfoAction, RemoveErrorInfoAction, ClearErrorInfoAction } from '../actions/errorActions'; import { MenuAction, MenuClosedByUser } from '../actions/menuAction' -import { IconType } from '../models/iconDefinition'; +import { SetWebsocketAction } from '../actions/websocketAction'; +import { IconType } from '../models/iconDefinition'; import { ErrorInfo } from '../models/errorInfo'; import { SnackbarItem } from '../models/snackbarItem'; -import { SetWebsocketAction } from '../actions/websocketAction'; +import { ExternalLoginProvider } from '../models/externalLoginProvider'; +import { ApplicationConfig } from '../models/applicationConfig'; export interface IApplicationState { title: string; @@ -36,9 +39,27 @@ export interface IApplicationState { errors: ErrorInfo[]; snackBars: SnackbarItem[]; isWebsocketAvailable: boolean | undefined; + externalLoginProviders: ExternalLoginProvider[] | null; + authentication: "basic"|"oauth", // basic + enablePolicy: boolean // false } -const applicationStateInit: IApplicationState = { title: "Loading ...", errors: [], snackBars: [], isMenuOpen: true, isMenuClosedByUser: false, isWebsocketAvailable: undefined }; +const applicationStateInit: IApplicationState = { + title: "Loading ...", + errors: [], + snackBars: [], + isMenuOpen: true, + isMenuClosedByUser: false, + isWebsocketAvailable: undefined, + externalLoginProviders: null, + authentication: "basic", + enablePolicy: false, +}; + +export const configureApplication = (config: ApplicationConfig) => { + applicationStateInit.authentication = config.authentication === "oauth" ? "oauth" : "basic"; + applicationStateInit.enablePolicy = config.authentication ? true : false; +} export const applicationStateHandler: IActionHandler = (state = applicationStateInit, action) => { if (action instanceof SetTitleAction) { @@ -46,14 +67,14 @@ export const applicationStateHandler: IActionHandler = (state ...state, title: action.title, icon: action.icon, - appId: action.appId + appId: action.appId, }; } else if (action instanceof AddErrorInfoAction) { state = { ...state, errors: [ ...state.errors, - action.errorInfo + action.errorInfo, ] }; } else if (action instanceof RemoveErrorInfoAction) { @@ -63,7 +84,7 @@ export const applicationStateHandler: IActionHandler = (state ...state, errors: [ ...state.errors.slice(0, index), - ...state.errors.slice(index + 1) + ...state.errors.slice(index + 1), ] }; } @@ -71,7 +92,7 @@ export const applicationStateHandler: IActionHandler = (state if (state.errors && state.errors.length) { state = { ...state, - errors: [] + errors: [], }; } } else if (action instanceof AddSnackbarNotification) { @@ -79,29 +100,34 @@ export const applicationStateHandler: IActionHandler = (state ...state, snackBars: [ ...state.snackBars, - action.notification + action.notification, ] }; } else if (action instanceof RemoveSnackbarNotification) { state = { ...state, - snackBars: state.snackBars.filter(s => s.key !== action.key) + snackBars: state.snackBars.filter(s => s.key !== action.key), }; } else if (action instanceof MenuAction) { state = { ...state, - isMenuOpen: action.isOpen + isMenuOpen: action.isOpen, } } else if (action instanceof MenuClosedByUser) { state = { ...state, - isMenuClosedByUser: action.isClosed + isMenuClosedByUser: action.isClosed, } } else if (action instanceof SetWebsocketAction) { state = { ...state, - isWebsocketAvailable: action.isConnected + isWebsocketAvailable: action.isConnected, + } + } else if (action instanceof SetExternalLoginProviderAction){ + state = { + ...state, + externalLoginProviders: action.externalLoginProvders, } } return state; diff --git a/sdnr/wt/odlux/framework/src/handlers/authenticationHandler.ts b/sdnr/wt/odlux/framework/src/handlers/authenticationHandler.ts index 82b228dc0..5217bd414 100644 --- a/sdnr/wt/odlux/framework/src/handlers/authenticationHandler.ts +++ b/sdnr/wt/odlux/framework/src/handlers/authenticationHandler.ts @@ -16,31 +16,26 @@ * ============LICENSE_END========================================================================== */ import { IActionHandler } from '../flux/action'; -import { UpdateAuthentication } from '../actions/authentication'; +import { UpdatePolicies, UpdateUser } from '../actions/authentication'; -import { User } from '../models/authentication'; +import { AuthPolicy, User } from '../models/authentication'; import { onLogin, onLogout } from '../services/applicationApi'; import { startWebsocketSession, endWebsocketSession } from '../services/notificationService'; export interface IAuthenticationState { user?: User; -} - -const initialToken = localStorage.getItem("userToken"); - -if (initialToken !== null) { - startWebsocketSession(); + policies?: AuthPolicy[]; } const authenticationStateInit: IAuthenticationState = { - user: initialToken && User.fromString(initialToken) || undefined + user: undefined }; export const authenticationStateHandler: IActionHandler = (state = authenticationStateInit, action) => { - if (action instanceof UpdateAuthentication) { - - const user = action.bearerToken && new User(action.bearerToken) || undefined; + if (action instanceof UpdateUser) { + const {user} = action; + if (user) { localStorage.setItem("userToken", user.toString()); startWebsocketSession(); @@ -53,9 +48,14 @@ export const authenticationStateHandler: IActionHandler = state = { ...state, - user + user, }; + } else if (action instanceof UpdatePolicies) { + state = { + ...state, + policies: action.authPolicies, + }; } - return state; }; + diff --git a/sdnr/wt/odlux/framework/src/index.html b/sdnr/wt/odlux/framework/src/index.html index d51c448a9..5cd2805c1 100644 --- a/sdnr/wt/odlux/framework/src/index.html +++ b/sdnr/wt/odlux/framework/src/index.html @@ -16,6 +16,7 @@