From 5a9f7b8b3b2dc07067435a0d089eb46658df91d6 Mon Sep 17 00:00:00 2001 From: Wroud Date: Sat, 23 May 2020 21:01:32 +0300 Subject: [PATCH] feat(authentication): permission check and menu CB-110 --- .../src/AdministrationMenuService.ts | 23 ++++++++++++++----- .../AdministrationScreen.tsx | 13 +++++++++-- .../AdministrationScreenService.ts | 20 ++++++++++++++-- .../administration/src/EAdminPermission.ts | 11 +++++++++ webapp/packages/core/assets/locales/en.js | 1 + webapp/packages/core/assets/locales/ru.js | 1 + .../src/app/AppScreen/AppScreenService.ts | 2 +- .../core/src/app/Screen/ScreenService.ts | 10 +++++++- 8 files changed, 69 insertions(+), 12 deletions(-) create mode 100644 webapp/packages/administration/src/EAdminPermission.ts diff --git a/webapp/packages/administration/src/AdministrationMenuService.ts b/webapp/packages/administration/src/AdministrationMenuService.ts index 9ee4a54822..629be48fb4 100644 --- a/webapp/packages/administration/src/AdministrationMenuService.ts +++ b/webapp/packages/administration/src/AdministrationMenuService.ts @@ -6,21 +6,21 @@ * you may not use this file except in compliance with the License. */ -import { SettingsMenuService } from '@dbeaver/core/app'; +import { SettingsMenuService, ScreenService, AppScreenService } from '@dbeaver/core/app'; import { injectable, Bootstrap } from '@dbeaver/core/di'; import { PermissionsService } from '@dbeaver/core/root'; import { AdministrationScreenService } from './AdministrationScreen/AdministrationScreenService'; - -export const ADMINISTRATION_PERMISSION = 'admin'; +import { EAdminPermission } from './EAdminPermission'; @injectable() export class AdministrationMenuService extends Bootstrap { - static administrationMenuToken = 'administrationMenu'; constructor( private settingsMenuService: SettingsMenuService, private permissionsService: PermissionsService, + private screenService: ScreenService, private administrationScreenService: AdministrationScreenService, + private appScreenService: AppScreenService ) { super(); } @@ -29,12 +29,23 @@ export class AdministrationMenuService extends Bootstrap { this.settingsMenuService.addMenuItem( SettingsMenuService.settingsMenuToken, { - id: AdministrationMenuService.administrationMenuToken, + id: 'administrationMenuEnter', order: 0, - isHidden: () => !this.permissionsService.has(ADMINISTRATION_PERMISSION), + isHidden: () => !this.permissionsService.has(EAdminPermission.admin) + || this.screenService.isActive(AdministrationScreenService.screenName), title: 'administration_menu_enter', onClick: () => this.administrationScreenService.navigateToRoot(), } ); + this.settingsMenuService.addMenuItem( + SettingsMenuService.settingsMenuToken, + { + id: 'administrationMenuBack', + order: 0, + isHidden: () => !this.screenService.isActive(AdministrationScreenService.screenName), + title: 'administration_menu_back', + onClick: () => this.appScreenService.navigateToRoot(), + } + ); } } diff --git a/webapp/packages/administration/src/AdministrationScreen/AdministrationScreen.tsx b/webapp/packages/administration/src/AdministrationScreen/AdministrationScreen.tsx index a2f9455b6c..6cf20e05bc 100644 --- a/webapp/packages/administration/src/AdministrationScreen/AdministrationScreen.tsx +++ b/webapp/packages/administration/src/AdministrationScreen/AdministrationScreen.tsx @@ -6,12 +6,21 @@ * you may not use this file except in compliance with the License. */ +import { observer } from 'mobx-react'; + +import { usePermission } from '@dbeaver/core/root'; + +import { EAdminPermission } from '../EAdminPermission'; import { AdministrationTopAppBar } from './AdministrationTopAppBar/AdministrationTopAppBar'; -export function AdministrationScreen() { +export const AdministrationScreen = observer(function AdministrationScreen() { + if (!usePermission(EAdminPermission.admin)) { + return <>You has no permission; + } + return ( <> ); -} +}); diff --git a/webapp/packages/administration/src/AdministrationScreen/AdministrationScreenService.ts b/webapp/packages/administration/src/AdministrationScreen/AdministrationScreenService.ts index a4f2d74654..de9a5997ac 100644 --- a/webapp/packages/administration/src/AdministrationScreen/AdministrationScreenService.ts +++ b/webapp/packages/administration/src/AdministrationScreen/AdministrationScreenService.ts @@ -6,9 +6,11 @@ * you may not use this file except in compliance with the License. */ -import { ScreenService, RouterService } from '@dbeaver/core/app'; +import { ScreenService, RouterService, AppScreenService } from '@dbeaver/core/app'; import { injectable, Bootstrap } from '@dbeaver/core/di'; +import { PermissionsService } from '@dbeaver/core/root'; +import { EAdminPermission } from '../EAdminPermission'; import { AdministrationScreen } from './AdministrationScreen'; @injectable() @@ -19,8 +21,11 @@ export class AdministrationScreenService extends Bootstrap { constructor( private screenService: ScreenService, private routerService: RouterService, + private permissionsService: PermissionsService, + private appScreenService: AppScreenService ) { super(); + this.permissionsService.onUpdate.subscribe(this.handleActivate.bind(this)); } navigateToRoot() { @@ -28,6 +33,17 @@ export class AdministrationScreenService extends Bootstrap { } bootstrap() { - this.screenService.add({ name: AdministrationScreenService.screenName, path: '/admin', component: AdministrationScreen }); + this.screenService.create({ + name: AdministrationScreenService.screenName, + path: '/admin', + component: AdministrationScreen, + onActivate: this.handleActivate.bind(this), + }); + } + + private handleActivate() { + if (!this.permissionsService.has(EAdminPermission.admin)) { + this.appScreenService.navigateToRoot(); + } } } diff --git a/webapp/packages/administration/src/EAdminPermission.ts b/webapp/packages/administration/src/EAdminPermission.ts new file mode 100644 index 0000000000..c1c7cddd49 --- /dev/null +++ b/webapp/packages/administration/src/EAdminPermission.ts @@ -0,0 +1,11 @@ +/* + * cloudbeaver - Cloud Database Manager + * Copyright (C) 2020 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +export enum EAdminPermission { + admin = 'admin' +} diff --git a/webapp/packages/core/assets/locales/en.js b/webapp/packages/core/assets/locales/en.js index 740bb9c556..e47957ffb9 100644 --- a/webapp/packages/core/assets/locales/en.js +++ b/webapp/packages/core/assets/locales/en.js @@ -42,6 +42,7 @@ module.exports = { data_transfer_exporting_sql: 'SQL:', administration_menu_enter: 'Administration', + administration_menu_back: 'Back to app', authentication_login_dialog_title: 'Authentication', authentication_login: 'Login', diff --git a/webapp/packages/core/assets/locales/ru.js b/webapp/packages/core/assets/locales/ru.js index 4f5a6ed5db..b652c1dae6 100644 --- a/webapp/packages/core/assets/locales/ru.js +++ b/webapp/packages/core/assets/locales/ru.js @@ -41,6 +41,7 @@ module.exports = { data_transfer_exporting_sql: 'SQL:', administration_menu_enter: 'Администрирование', + administration_menu_back: 'Вернуться в приложение', authentication_login_dialog_title: 'Авторизация', authentication_login: 'Войти', diff --git a/webapp/packages/core/src/app/AppScreen/AppScreenService.ts b/webapp/packages/core/src/app/AppScreen/AppScreenService.ts index dfe4db12b7..2169015209 100644 --- a/webapp/packages/core/src/app/AppScreen/AppScreenService.ts +++ b/webapp/packages/core/src/app/AppScreen/AppScreenService.ts @@ -27,6 +27,6 @@ export class AppScreenService { } register() { - this.screenService.add({ name: AppScreenService.screenName, path: '/', component: AppScreen }); + this.screenService.create({ name: AppScreenService.screenName, path: '/', component: AppScreen }); } } diff --git a/webapp/packages/core/src/app/Screen/ScreenService.ts b/webapp/packages/core/src/app/Screen/ScreenService.ts index 998b0797ef..4b4b15827f 100644 --- a/webapp/packages/core/src/app/Screen/ScreenService.ts +++ b/webapp/packages/core/src/app/Screen/ScreenService.ts @@ -28,7 +28,7 @@ export class ScreenService { this.routerService.subscribe(this.onRouteChange.bind(this)); } - add(screen: IScreen) { + create(screen: IScreen) { if (this.screens.has(screen.name)) { return; } @@ -37,6 +37,14 @@ export class ScreenService { this.routerService.router.add({ name: screen.name, path: screen.path }); } + isActive(name: string, strict = false): boolean { + if (strict) { + return this.screen?.name === name; + } + + return this.screen?.name.startsWith(name) || false; + } + buildUrl(screen: string) { return this.routerService.router.buildUrl(screen); }