From db05ee1cb8a853379c6853cbe8e79a7f835a8285 Mon Sep 17 00:00:00 2001 From: Naumov Alexey Date: Fri, 27 May 2022 01:14:14 +0200 Subject: [PATCH 01/13] fix(plugin-resource-manager-administration): CB-2066 disable rm via amin part --- .../core-root/src/ServerConfigResource.ts | 8 +++ .../src/queries/session/serverConfig.gql | 2 + webapp/packages/core-sdk/src/sdk.ts | 5 +- .../.gitignore | 17 ++++++ .../package.json | 45 ++++++++++++++++ .../src/LocaleService.ts | 36 +++++++++++++ .../src/PluginBootstrap.ts | 54 +++++++++++++++++++ .../src/ResourceManagerSettings.tsx | 35 ++++++++++++ .../src/index.ts | 3 ++ .../src/locales/en.ts | 4 ++ .../src/locales/it.ts | 4 ++ .../src/locales/ru.ts | 4 ++ .../src/locales/zh.ts | 4 ++ .../src/manifest.ts | 20 +++++++ .../tsconfig.json | 20 +++++++ 15 files changed, 260 insertions(+), 1 deletion(-) create mode 100644 webapp/packages/plugin-resource-manager-administration/.gitignore create mode 100644 webapp/packages/plugin-resource-manager-administration/package.json create mode 100644 webapp/packages/plugin-resource-manager-administration/src/LocaleService.ts create mode 100644 webapp/packages/plugin-resource-manager-administration/src/PluginBootstrap.ts create mode 100644 webapp/packages/plugin-resource-manager-administration/src/ResourceManagerSettings.tsx create mode 100644 webapp/packages/plugin-resource-manager-administration/src/index.ts create mode 100644 webapp/packages/plugin-resource-manager-administration/src/locales/en.ts create mode 100644 webapp/packages/plugin-resource-manager-administration/src/locales/it.ts create mode 100644 webapp/packages/plugin-resource-manager-administration/src/locales/ru.ts create mode 100644 webapp/packages/plugin-resource-manager-administration/src/locales/zh.ts create mode 100644 webapp/packages/plugin-resource-manager-administration/src/manifest.ts create mode 100644 webapp/packages/plugin-resource-manager-administration/tsconfig.json diff --git a/webapp/packages/core-root/src/ServerConfigResource.ts b/webapp/packages/core-root/src/ServerConfigResource.ts index 73fc6823dc..57b0bef6a9 100644 --- a/webapp/packages/core-root/src/ServerConfigResource.ts +++ b/webapp/packages/core-root/src/ServerConfigResource.ts @@ -94,6 +94,10 @@ export class ServerConfigResource extends CachedDataResource; redirectOnFederatedAuth?: Maybe; + resourceManagerEnabled?: Maybe; resourceQuotas: Scalars['Object']; rootURI: Scalars['String']; serverURL: Scalars['String']; @@ -1365,6 +1366,7 @@ export interface ServerConfigInput { enabledAuthProviders?: InputMaybe>; enabledFeatures?: InputMaybe>; publicCredentialsSaveEnabled?: InputMaybe; + resourceManagerEnabled?: InputMaybe; serverName?: InputMaybe; serverURL?: InputMaybe; sessionExpireTime?: InputMaybe; @@ -2292,7 +2294,7 @@ export type ReadSessionLogQuery = { log: Array<{ time?: any; type: string; messa export type ServerConfigQueryVariables = Exact<{ [key: string]: never }>; -export type ServerConfigQuery = { serverConfig: { name: string; version: string; workspaceId: string; serverURL: string; rootURI: string; hostName: string; productConfiguration: any; supportsCustomConnections?: boolean; supportsConnectionBrowser?: boolean; supportsWorkspaces?: boolean; sessionExpireTime?: number; anonymousAccessEnabled?: boolean; adminCredentialsSaveEnabled?: boolean; publicCredentialsSaveEnabled?: boolean; licenseRequired: boolean; licenseValid: boolean; configurationMode?: boolean; developmentMode?: boolean; redirectOnFederatedAuth?: boolean; enabledFeatures: Array; enabledAuthProviders: Array; resourceQuotas: any; disabledDrivers: Array; supportedLanguages: Array<{ isoCode: string; displayName?: string; nativeName?: string }>; defaultNavigatorSettings: { showSystemObjects: boolean; showUtilityObjects: boolean; showOnlyEntities: boolean; mergeEntities: boolean; hideFolders: boolean; hideSchemas: boolean; hideVirtualModel: boolean }; productInfo: { id: string; version: string; latestVersionInfo?: string; name: string; description?: string; buildTime: string; releaseTime: string; licenseInfo?: string } } }; +export type ServerConfigQuery = { serverConfig: { name: string; version: string; workspaceId: string; serverURL: string; rootURI: string; hostName: string; productConfiguration: any; supportsCustomConnections?: boolean; supportsConnectionBrowser?: boolean; supportsWorkspaces?: boolean; sessionExpireTime?: number; anonymousAccessEnabled?: boolean; adminCredentialsSaveEnabled?: boolean; publicCredentialsSaveEnabled?: boolean; resourceManagerEnabled?: boolean; licenseRequired: boolean; licenseValid: boolean; configurationMode?: boolean; developmentMode?: boolean; redirectOnFederatedAuth?: boolean; enabledFeatures: Array; enabledAuthProviders: Array; resourceQuotas: any; disabledDrivers: Array; supportedLanguages: Array<{ isoCode: string; displayName?: string; nativeName?: string }>; defaultNavigatorSettings: { showSystemObjects: boolean; showUtilityObjects: boolean; showOnlyEntities: boolean; mergeEntities: boolean; hideFolders: boolean; hideSchemas: boolean; hideVirtualModel: boolean }; productInfo: { id: string; version: string; latestVersionInfo?: string; name: string; description?: string; buildTime: string; releaseTime: string; licenseInfo?: string } } }; export type SessionPermissionsQueryVariables = Exact<{ [key: string]: never }>; @@ -3627,6 +3629,7 @@ export const ServerConfigDocument = ` anonymousAccessEnabled adminCredentialsSaveEnabled publicCredentialsSaveEnabled + resourceManagerEnabled licenseRequired licenseValid configurationMode diff --git a/webapp/packages/plugin-resource-manager-administration/.gitignore b/webapp/packages/plugin-resource-manager-administration/.gitignore new file mode 100644 index 0000000000..fd03da61a3 --- /dev/null +++ b/webapp/packages/plugin-resource-manager-administration/.gitignore @@ -0,0 +1,17 @@ +# dependencies +/node_modules + +# testing +/coverage + +# production +/lib + +# misc +.DS_Store +.env* + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* \ No newline at end of file diff --git a/webapp/packages/plugin-resource-manager-administration/package.json b/webapp/packages/plugin-resource-manager-administration/package.json new file mode 100644 index 0000000000..4a64eca9f9 --- /dev/null +++ b/webapp/packages/plugin-resource-manager-administration/package.json @@ -0,0 +1,45 @@ +{ + "name": "@cloudbeaver/plugin-resource-manager-administration", + "sideEffects": false, + "version": "0.1.0", + "description": "", + "license": "Apache-2.0", + "main": "lib/index.js", + "module": "lib/index.js", + "types": "src/index.ts", + "scripts": { + "prebuild": "rimraf lib/*", + "build": "webpack --config ../../configs/webpack.plugin.config.js", + "postbuild": "tsc", + "lint": "eslint ./src/ --ext .ts,.tsx", + "lint-fix": "eslint ./src/ --ext .ts,.tsx --fix" + }, + "peerDependencies": { + "@cloudbeaver/core-administration": "~0.1.0", + "@cloudbeaver/core-app": "~0.1.0", + "@cloudbeaver/core-authentication": "~0.1.0", + "@cloudbeaver/core-blocks": "~0.1.0", + "@cloudbeaver/core-connections": "~0.1.0", + "@cloudbeaver/core-di": "~0.1.0", + "@cloudbeaver/core-dialogs": "~0.1.0", + "@cloudbeaver/core-events": "~0.1.0", + "@cloudbeaver/core-executor": "~0.1.0", + "@cloudbeaver/core-extensions": "~0.1.0", + "@cloudbeaver/core-localization": "~0.1.0", + "@cloudbeaver/core-notifications": "~0.1.0", + "@cloudbeaver/core-plugin": "~0.1.0", + "@cloudbeaver/core-product": "~0.1.0", + "@cloudbeaver/core-root": "~0.1.0", + "@cloudbeaver/core-routing": "~0.1.0", + "@cloudbeaver/core-sdk": "~0.1.0", + "@cloudbeaver/core-settings": "~0.1.0", + "@cloudbeaver/core-theming": "~0.1.0", + "@cloudbeaver/core-ui": "~0.1.0", + "@cloudbeaver/core-utils": "~0.1.0", + "@cloudbeaver/core-view": "~0.1.0", + "react": "~17.x.x", + "mobx": "~6.x.x", + "mobx-react-lite": "~3.x.x", + "reshadow": "~0.x.x" + } +} \ No newline at end of file diff --git a/webapp/packages/plugin-resource-manager-administration/src/LocaleService.ts b/webapp/packages/plugin-resource-manager-administration/src/LocaleService.ts new file mode 100644 index 0000000000..90c761184a --- /dev/null +++ b/webapp/packages/plugin-resource-manager-administration/src/LocaleService.ts @@ -0,0 +1,36 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2022 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +import { Bootstrap, injectable } from '@cloudbeaver/core-di'; +import { LocalizationService } from '@cloudbeaver/core-localization'; + +@injectable() +export class LocaleService extends Bootstrap { + constructor(private readonly localizationService: LocalizationService) { + super(); + } + + register(): void | Promise { + this.localizationService.addProvider(this.provider.bind(this)); + } + + load(): void | Promise { } + + private async provider(locale: string) { + switch (locale) { + case 'ru': + return (await import('./locales/ru')).default; + case 'it': + return (await import('./locales/it')).default; + case 'zh': + return (await import('./locales/zh')).default; + default: + return (await import('./locales/en')).default; + } + } +} \ No newline at end of file diff --git a/webapp/packages/plugin-resource-manager-administration/src/PluginBootstrap.ts b/webapp/packages/plugin-resource-manager-administration/src/PluginBootstrap.ts new file mode 100644 index 0000000000..c759eea3e2 --- /dev/null +++ b/webapp/packages/plugin-resource-manager-administration/src/PluginBootstrap.ts @@ -0,0 +1,54 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2022 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +import { Bootstrap, injectable } from '@cloudbeaver/core-di'; +import { NotificationService } from '@cloudbeaver/core-events'; +import { ExecutorInterrupter, IExecutionContextProvider } from '@cloudbeaver/core-executor'; +import { ServerConfigResource } from '@cloudbeaver/core-root'; +import { ILoadConfigData, ServerConfigurationService } from '@cloudbeaver/plugin-administration'; + +import { ResourceManagerSettings } from './ResourceManagerSettings'; + +@injectable() +export class PluginBootstrap extends Bootstrap { + constructor( + private readonly serverConfigurationService: ServerConfigurationService, + private readonly serverConfigResource: ServerConfigResource, + private readonly notificationService: NotificationService + ) { + super(); + + this.loadConfigHandler = this.loadConfigHandler.bind(this); + } + + register(): void | Promise { + this.serverConfigurationService.configurationContainer.add(ResourceManagerSettings, 1); + this.serverConfigurationService.loadConfigTask.addHandler(this.loadConfigHandler); + } + + async load(): Promise { } + + private async loadConfigHandler(data: ILoadConfigData, contexts: IExecutionContextProvider) { + if (!data.reset) { + return; + } + + try { + const config = await this.serverConfigResource.load(); + + if (!config) { + return; + } + + data.state.serverConfig.resourceManagerEnabled = config.resourceManagerEnabled; + } catch (exception) { + ExecutorInterrupter.interrupt(contexts); + this.notificationService.logException(exception as any, 'Can\'t load server configuration'); + } + } +} \ No newline at end of file diff --git a/webapp/packages/plugin-resource-manager-administration/src/ResourceManagerSettings.tsx b/webapp/packages/plugin-resource-manager-administration/src/ResourceManagerSettings.tsx new file mode 100644 index 0000000000..749f4fdf2f --- /dev/null +++ b/webapp/packages/plugin-resource-manager-administration/src/ResourceManagerSettings.tsx @@ -0,0 +1,35 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2022 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +import { observer } from 'mobx-react-lite'; +import styled from 'reshadow'; + +import { BASE_CONTAINERS_STYLES, Group, GroupTitle, PlaceholderComponent, Switch } from '@cloudbeaver/core-blocks'; +import { useTranslate } from '@cloudbeaver/core-localization'; +import type { IConfigurationPlaceholderProps } from '@cloudbeaver/plugin-administration'; + +export const ResourceManagerSettings: PlaceholderComponent = observer( + function ResourceManagerSettings({ state }) { + const translate = useTranslate(); + + return styled(BASE_CONTAINERS_STYLES)( + + {translate('plugin_resource_manager_title')} + + {translate('plugin_resource_manager_administration_settings_enable')} + + + ); + }); \ No newline at end of file diff --git a/webapp/packages/plugin-resource-manager-administration/src/index.ts b/webapp/packages/plugin-resource-manager-administration/src/index.ts new file mode 100644 index 0000000000..7a00070e27 --- /dev/null +++ b/webapp/packages/plugin-resource-manager-administration/src/index.ts @@ -0,0 +1,3 @@ +import { resourceManagerAdministrationPlugin } from './manifest'; + +export default resourceManagerAdministrationPlugin; \ No newline at end of file diff --git a/webapp/packages/plugin-resource-manager-administration/src/locales/en.ts b/webapp/packages/plugin-resource-manager-administration/src/locales/en.ts new file mode 100644 index 0000000000..800db43248 --- /dev/null +++ b/webapp/packages/plugin-resource-manager-administration/src/locales/en.ts @@ -0,0 +1,4 @@ +export default [ + ['plugin_resource_manager_administration_settings_enable', 'Enable Resource manager'], + ['plugin_resource_manager_administration_settings_enable_description', 'Enable Resource manager functionality'], +]; \ No newline at end of file diff --git a/webapp/packages/plugin-resource-manager-administration/src/locales/it.ts b/webapp/packages/plugin-resource-manager-administration/src/locales/it.ts new file mode 100644 index 0000000000..800db43248 --- /dev/null +++ b/webapp/packages/plugin-resource-manager-administration/src/locales/it.ts @@ -0,0 +1,4 @@ +export default [ + ['plugin_resource_manager_administration_settings_enable', 'Enable Resource manager'], + ['plugin_resource_manager_administration_settings_enable_description', 'Enable Resource manager functionality'], +]; \ No newline at end of file diff --git a/webapp/packages/plugin-resource-manager-administration/src/locales/ru.ts b/webapp/packages/plugin-resource-manager-administration/src/locales/ru.ts new file mode 100644 index 0000000000..2a93554670 --- /dev/null +++ b/webapp/packages/plugin-resource-manager-administration/src/locales/ru.ts @@ -0,0 +1,4 @@ +export default [ + ['plugin_resource_manager_administration_settings_enable', 'Включить Менеджер ресурсов'], + ['plugin_resource_manager_administration_settings_enable_description', 'Включает функционал Менеджера ресурсов'], +]; \ No newline at end of file diff --git a/webapp/packages/plugin-resource-manager-administration/src/locales/zh.ts b/webapp/packages/plugin-resource-manager-administration/src/locales/zh.ts new file mode 100644 index 0000000000..800db43248 --- /dev/null +++ b/webapp/packages/plugin-resource-manager-administration/src/locales/zh.ts @@ -0,0 +1,4 @@ +export default [ + ['plugin_resource_manager_administration_settings_enable', 'Enable Resource manager'], + ['plugin_resource_manager_administration_settings_enable_description', 'Enable Resource manager functionality'], +]; \ No newline at end of file diff --git a/webapp/packages/plugin-resource-manager-administration/src/manifest.ts b/webapp/packages/plugin-resource-manager-administration/src/manifest.ts new file mode 100644 index 0000000000..9729a95623 --- /dev/null +++ b/webapp/packages/plugin-resource-manager-administration/src/manifest.ts @@ -0,0 +1,20 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2022 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +import type { PluginManifest } from '@cloudbeaver/core-di'; + +import { LocaleService } from './LocaleService'; +import { PluginBootstrap } from './PluginBootstrap'; + +export const resourceManagerAdministrationPlugin: PluginManifest = { + info: { name: 'Resource manager administration plugin' }, + providers: [ + PluginBootstrap, + LocaleService, + ], +}; \ No newline at end of file diff --git a/webapp/packages/plugin-resource-manager-administration/tsconfig.json b/webapp/packages/plugin-resource-manager-administration/tsconfig.json new file mode 100644 index 0000000000..bca25a8e0a --- /dev/null +++ b/webapp/packages/plugin-resource-manager-administration/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "lib", + "composite": true + }, + "include": [ + "src" + ], + "exclude": [ + "**/node_modules", + "**/.*/" + ], + "references": [ + { + "path": "../*" + } + ] +} \ No newline at end of file From 8e2ec49f88bf24699e0242eb14fc5695ff7bcabb Mon Sep 17 00:00:00 2001 From: Naumov Alexey Date: Fri, 27 May 2022 12:49:00 +0200 Subject: [PATCH 02/13] fix(plugin-resource-manager-administration): CB-2066 add rm enable option to the existing group --- .../ServerConfiguration/ServerConfigurationPage.tsx | 6 +++++- .../ServerConfiguration/ServerConfigurationService.ts | 2 +- .../src/PluginBootstrap.ts | 2 +- .../src/ResourceManagerSettings.tsx | 6 +++--- .../plugin-resource-manager/src/ResourceManagerService.ts | 7 +++---- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/webapp/packages/plugin-administration/src/ConfigurationWizard/ServerConfiguration/ServerConfigurationPage.tsx b/webapp/packages/plugin-administration/src/ConfigurationWizard/ServerConfiguration/ServerConfigurationPage.tsx index 33914c9127..5fce6cef5a 100644 --- a/webapp/packages/plugin-administration/src/ConfigurationWizard/ServerConfiguration/ServerConfigurationPage.tsx +++ b/webapp/packages/plugin-administration/src/ConfigurationWizard/ServerConfiguration/ServerConfigurationPage.tsx @@ -126,7 +126,11 @@ export const ServerConfigurationPage: AdministrationItemContentComponent = obser - + ; readonly validationTask: IExecutor; readonly configurationContainer: PlaceholderContainer; - readonly pluginsContainer: PlaceholderContainer; + readonly pluginsContainer: PlaceholderContainer; private done: boolean; private stateLinked: boolean; diff --git a/webapp/packages/plugin-resource-manager-administration/src/PluginBootstrap.ts b/webapp/packages/plugin-resource-manager-administration/src/PluginBootstrap.ts index c759eea3e2..52449aeaf2 100644 --- a/webapp/packages/plugin-resource-manager-administration/src/PluginBootstrap.ts +++ b/webapp/packages/plugin-resource-manager-administration/src/PluginBootstrap.ts @@ -27,7 +27,7 @@ export class PluginBootstrap extends Bootstrap { } register(): void | Promise { - this.serverConfigurationService.configurationContainer.add(ResourceManagerSettings, 1); + this.serverConfigurationService.pluginsContainer.add(ResourceManagerSettings, 0); this.serverConfigurationService.loadConfigTask.addHandler(this.loadConfigHandler); } diff --git a/webapp/packages/plugin-resource-manager-administration/src/ResourceManagerSettings.tsx b/webapp/packages/plugin-resource-manager-administration/src/ResourceManagerSettings.tsx index 749f4fdf2f..8efa05619b 100644 --- a/webapp/packages/plugin-resource-manager-administration/src/ResourceManagerSettings.tsx +++ b/webapp/packages/plugin-resource-manager-administration/src/ResourceManagerSettings.tsx @@ -9,7 +9,7 @@ import { observer } from 'mobx-react-lite'; import styled from 'reshadow'; -import { BASE_CONTAINERS_STYLES, Group, GroupTitle, PlaceholderComponent, Switch } from '@cloudbeaver/core-blocks'; +import { BASE_CONTAINERS_STYLES, GroupTitle, PlaceholderComponent, Switch } from '@cloudbeaver/core-blocks'; import { useTranslate } from '@cloudbeaver/core-localization'; import type { IConfigurationPlaceholderProps } from '@cloudbeaver/plugin-administration'; @@ -18,7 +18,7 @@ export const ResourceManagerSettings: PlaceholderComponent + <> {translate('plugin_resource_manager_title')} {translate('plugin_resource_manager_administration_settings_enable')} - + ); }); \ No newline at end of file diff --git a/webapp/packages/plugin-resource-manager/src/ResourceManagerService.ts b/webapp/packages/plugin-resource-manager/src/ResourceManagerService.ts index 7870cd264a..69bdf2a5f2 100644 --- a/webapp/packages/plugin-resource-manager/src/ResourceManagerService.ts +++ b/webapp/packages/plugin-resource-manager/src/ResourceManagerService.ts @@ -10,20 +10,19 @@ import { computed, makeObservable, observable } from 'mobx'; import { AuthInfoService } from '@cloudbeaver/core-authentication'; import { injectable } from '@cloudbeaver/core-di'; - -import { ResourceManagerSettingsService } from './ResourceManagerSettingsService'; +import { ServerConfigResource } from '@cloudbeaver/core-root'; @injectable() export class ResourceManagerService { get enabled() { - return !this.resourceManagerSettingsService.settings.getValue('disabled') && !!this.authInfoService.userInfo; + return this.serverConfigResource.resourceManagerEnabled && !!this.authInfoService.userInfo; } panelEnabled: boolean; constructor( - private readonly resourceManagerSettingsService: ResourceManagerSettingsService, private readonly authInfoService: AuthInfoService, + private readonly serverConfigResource: ServerConfigResource ) { this.togglePanel = this.togglePanel.bind(this); From 722c5539067246a5576400bb0c95fb3831a02715 Mon Sep 17 00:00:00 2001 From: Naumov Alexey Date: Fri, 27 May 2022 13:08:47 +0200 Subject: [PATCH 03/13] fix(plugin-resource-manager-administration): CB-2066 add rm-administration plugin --- webapp/packages/product-default/src/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/webapp/packages/product-default/src/index.ts b/webapp/packages/product-default/src/index.ts index b365bc4749..bee503523c 100644 --- a/webapp/packages/product-default/src/index.ts +++ b/webapp/packages/product-default/src/index.ts @@ -19,6 +19,7 @@ import localization from '@cloudbeaver/plugin-localization'; import objectViewer from '@cloudbeaver/plugin-object-viewer'; import productPlugin from '@cloudbeaver/plugin-product'; import resourceManager from '@cloudbeaver/plugin-resource-manager'; +import resourceManagerAdministration from '@cloudbeaver/plugin-resource-manager-administration'; import settingsMenu from '@cloudbeaver/plugin-settings-menu'; import settingsMenuAdministration from '@cloudbeaver/plugin-settings-menu-administration'; import sqlEditor from '@cloudbeaver/plugin-sql-editor'; @@ -60,6 +61,7 @@ const PLUGINS: PluginManifest[] = [ settingsMenuAdministration, help, resourceManager, + resourceManagerAdministration, sqlEditorResource, ]; From ee24bf33af66cb76cf07ea751628b828bb13c22b Mon Sep 17 00:00:00 2001 From: Naumov Alexey Date: Fri, 27 May 2022 15:16:12 +0200 Subject: [PATCH 04/13] fix(core-app): CB-2082 support shorcut icon --- .../core-app/public/apple-touch-icon.png | Bin 0 -> 11069 bytes .../packages/core-app/public/favicon-32x32.png | Bin 0 -> 1532 bytes webapp/packages/core-app/public/favicon.ico | Bin 0 -> 15086 bytes .../core-blocks/src/HTMLTemplates/head.html.ejs | 4 ++++ 4 files changed, 4 insertions(+) create mode 100644 webapp/packages/core-app/public/apple-touch-icon.png create mode 100644 webapp/packages/core-app/public/favicon-32x32.png create mode 100644 webapp/packages/core-app/public/favicon.ico diff --git a/webapp/packages/core-app/public/apple-touch-icon.png b/webapp/packages/core-app/public/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..58b305de65e1512187bede5245a8f362f08d24af GIT binary patch literal 11069 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 literal 0 HcmV?d00001 diff --git a/webapp/packages/core-app/public/favicon.ico b/webapp/packages/core-app/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..21c92734c83ae32551ddf440a0673650e1ffd9dc GIT binary patch literal 15086 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 literal 0 HcmV?d00001 diff --git a/webapp/packages/core-blocks/src/HTMLTemplates/head.html.ejs b/webapp/packages/core-blocks/src/HTMLTemplates/head.html.ejs index bf06afaa32..f07983153c 100644 --- a/webapp/packages/core-blocks/src/HTMLTemplates/head.html.ejs +++ b/webapp/packages/core-blocks/src/HTMLTemplates/head.html.ejs @@ -1,8 +1,12 @@ + + + + From 332b3bce25e542b3fe576e20ebb10ab2650d091d Mon Sep 17 00:00:00 2001 From: Naumov Alexey Date: Fri, 27 May 2022 16:58:13 +0200 Subject: [PATCH 05/13] fix(plugin-resource-manager): CB-2087 allow parentheses --- .../plugin-resource-manager/src/SaveScriptDialog.tsx | 2 +- .../packages/plugin-resource-manager/src/locales/en.ts | 2 +- .../packages/plugin-resource-manager/src/locales/it.ts | 2 +- .../packages/plugin-resource-manager/src/locales/ru.ts | 2 +- .../packages/plugin-resource-manager/src/locales/zh.ts | 2 +- .../src/PluginBootstrap.ts | 9 ++++----- 6 files changed, 9 insertions(+), 10 deletions(-) diff --git a/webapp/packages/plugin-resource-manager/src/SaveScriptDialog.tsx b/webapp/packages/plugin-resource-manager/src/SaveScriptDialog.tsx index a8ce5b4f42..ad3ae4b5d5 100644 --- a/webapp/packages/plugin-resource-manager/src/SaveScriptDialog.tsx +++ b/webapp/packages/plugin-resource-manager/src/SaveScriptDialog.tsx @@ -32,7 +32,7 @@ interface State { submit: () => Promise; } -const regex = /^(?!\.)[\p{L}\w\-$.\s]+$/u; +const regex = /^(?!\.)[\p{L}\w\-$.\s()]+$/u; export const SaveScriptDialog: DialogComponent = observer(function SaveScriptDialog({ payload, diff --git a/webapp/packages/plugin-resource-manager/src/locales/en.ts b/webapp/packages/plugin-resource-manager/src/locales/en.ts index 2de54ee0fd..129d4cb651 100644 --- a/webapp/packages/plugin-resource-manager/src/locales/en.ts +++ b/webapp/packages/plugin-resource-manager/src/locales/en.ts @@ -14,5 +14,5 @@ export default [ ['plugin_resource_manager_sync_script_error', "Failed to sync editor's query"], ['plugin_resource_manager_script_not_found_title', 'Failed to find the associated script'], ['plugin_resource_manager_script_not_found_message', 'The script was probably removed or renamed. The last known value will be used'], - ['plugin_resource_manager_script_name_invalid_characters_message', 'Script\'s name may contain the following symbols "_-$." and can\'t start with a dot'], + ['plugin_resource_manager_script_name_invalid_characters_message', 'Script\'s name may contain the following symbols "_-$.()" and can\'t start with a dot'], ]; \ No newline at end of file diff --git a/webapp/packages/plugin-resource-manager/src/locales/it.ts b/webapp/packages/plugin-resource-manager/src/locales/it.ts index 4cc87825d4..3ba86c11c0 100644 --- a/webapp/packages/plugin-resource-manager/src/locales/it.ts +++ b/webapp/packages/plugin-resource-manager/src/locales/it.ts @@ -14,5 +14,5 @@ export default [ ['plugin_resource_manager_sync_script_error', "Failed to sync editor's query"], ['plugin_resource_manager_script_not_found_title', 'Failed to find the associated script'], ['plugin_resource_manager_script_not_found_message', 'The script was probably removed or renamed. The last known value will be used'], - ['plugin_resource_manager_script_name_invalid_characters_message', 'Script\'s name may contain the following symbols "_-$." and can\'t start with a dot'], + ['plugin_resource_manager_script_name_invalid_characters_message', 'Script\'s name may contain the following symbols "_-$.()" and can\'t start with a dot'], ]; \ No newline at end of file diff --git a/webapp/packages/plugin-resource-manager/src/locales/ru.ts b/webapp/packages/plugin-resource-manager/src/locales/ru.ts index bf320f8591..84e9d2a8a7 100644 --- a/webapp/packages/plugin-resource-manager/src/locales/ru.ts +++ b/webapp/packages/plugin-resource-manager/src/locales/ru.ts @@ -14,5 +14,5 @@ export default [ ['plugin_resource_manager_sync_script_error', 'Не удалось синхронизировать данные редактора'], ['plugin_resource_manager_script_not_found_title', 'Не удалось найти привязанный скрипт'], ['plugin_resource_manager_script_not_found_message', 'Возможно скрипт был удален или переименован. Будет использовано последнее известное значение'], - ['plugin_resource_manager_script_name_invalid_characters_message', 'Имя скрипта может содержать следующие символы "_-$." и не может начинаться с точки'], + ['plugin_resource_manager_script_name_invalid_characters_message', 'Имя скрипта может содержать следующие символы "_-$.()" и не может начинаться с точки'], ]; \ No newline at end of file diff --git a/webapp/packages/plugin-resource-manager/src/locales/zh.ts b/webapp/packages/plugin-resource-manager/src/locales/zh.ts index 3697c691e4..640d9cab22 100644 --- a/webapp/packages/plugin-resource-manager/src/locales/zh.ts +++ b/webapp/packages/plugin-resource-manager/src/locales/zh.ts @@ -14,5 +14,5 @@ export default [ ['plugin_resource_manager_sync_script_error', '同步查询失败'], ['plugin_resource_manager_script_not_found_title', '找不到关联的脚本'], ['plugin_resource_manager_script_not_found_message', '脚本可能被删除或重命名,将使用最后的有效值'], - ['plugin_resource_manager_script_name_invalid_characters_message', 'Script\'s name may contain the following symbols "_-$." and can\'t start with a dot'], + ['plugin_resource_manager_script_name_invalid_characters_message', 'Script\'s name may contain the following symbols "_-$.()" and can\'t start with a dot'], ]; diff --git a/webapp/packages/plugin-sql-editor-navigation-tab-resource/src/PluginBootstrap.ts b/webapp/packages/plugin-sql-editor-navigation-tab-resource/src/PluginBootstrap.ts index 3b7135d9d2..4d08df8004 100644 --- a/webapp/packages/plugin-sql-editor-navigation-tab-resource/src/PluginBootstrap.ts +++ b/webapp/packages/plugin-sql-editor-navigation-tab-resource/src/PluginBootstrap.ts @@ -14,8 +14,8 @@ import { SessionExpireService } from '@cloudbeaver/core-root'; import { createPath } from '@cloudbeaver/core-utils'; import { ActionService, ACTION_SAVE, DATA_CONTEXT_MENU, MenuService } from '@cloudbeaver/core-view'; import { NavResourceNodeService, RESOURCE_NODE_TYPE, SaveScriptDialog, ResourceManagerService, ProjectsResource, RESOURCES_NODE_PATH } from '@cloudbeaver/plugin-resource-manager'; -import { DATA_CONTEXT_SQL_EDITOR_STATE, SqlEditorService, SQL_EDITOR_ACTIONS_MENU } from '@cloudbeaver/plugin-sql-editor'; -import { SqlEditorNavigatorService, SqlEditorTabService } from '@cloudbeaver/plugin-sql-editor-navigation-tab'; +import { DATA_CONTEXT_SQL_EDITOR_STATE, getSqlEditorName, SqlEditorService, SQL_EDITOR_ACTIONS_MENU } from '@cloudbeaver/plugin-sql-editor'; +import { SqlEditorNavigatorService } from '@cloudbeaver/plugin-sql-editor-navigation-tab'; import { isScript } from './isScript'; import { SCRIPT_EXTENSION } from './SCRIPT_EXTENSION'; @@ -27,7 +27,6 @@ export class PluginBootstrap extends Bootstrap { private readonly navNodeManagerService: NavNodeManagerService, private readonly navTreeResource: NavTreeResource, private readonly navResourceNodeService: NavResourceNodeService, - private readonly sqlEditorTabService: SqlEditorTabService, private readonly sqlEditorService: SqlEditorService, private readonly navNodeInfoResource: NavNodeInfoResource, private readonly navigationTabsService: NavigationTabsService, @@ -64,9 +63,9 @@ export class PluginBootstrap extends Bootstrap { const tab = this.navigationTabsService.currentTab; if (action === ACTION_SAVE) { - const tabName = this.sqlEditorTabService.getName(state); + const name = getSqlEditorName(state); const result = await this.commonDialogService.open(SaveScriptDialog, { - defaultScriptName: tabName, + defaultScriptName: name, }); if (result !== DialogueStateResult.Rejected && result !== DialogueStateResult.Resolved) { From 69b299f15b27b1bf9c4bb3d19b8156525b18a058 Mon Sep 17 00:00:00 2001 From: Alexander Skoblikov Date: Mon, 30 May 2022 14:18:16 +0300 Subject: [PATCH 06/13] CB-1985 Azure AD auth provider (#870) * CB-1985 Azure AD auth provider * CB-1985 review fix --- .../bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF | 1 + .../auth/provider/fa/AbstractSessionFederated.java | 0 .../auth/provider/fa/FederatedUserDetails.java | 0 .../src/io/cloudbeaver/model/session/WebSession.java | 10 +++++++--- .../bundles/io.cloudbeaver.server/META-INF/MANIFEST.MF | 1 - 5 files changed, 8 insertions(+), 4 deletions(-) rename server/bundles/{io.cloudbeaver.server => io.cloudbeaver.model}/src/io/cloudbeaver/auth/provider/fa/AbstractSessionFederated.java (100%) rename server/bundles/{io.cloudbeaver.server => io.cloudbeaver.model}/src/io/cloudbeaver/auth/provider/fa/FederatedUserDetails.java (100%) diff --git a/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF index 935702f4d0..4cffad04d1 100644 --- a/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF +++ b/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF @@ -19,6 +19,7 @@ Export-Package: io.cloudbeaver, io.cloudbeaver.auth, io.cloudbeaver.auth.provider, io.cloudbeaver.auth.provider.local, + io.cloudbeaver.auth.provider.fa, io.cloudbeaver.model, io.cloudbeaver.model.app, io.cloudbeaver.model.rm.local, diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/auth/provider/fa/AbstractSessionFederated.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/auth/provider/fa/AbstractSessionFederated.java similarity index 100% rename from server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/auth/provider/fa/AbstractSessionFederated.java rename to server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/auth/provider/fa/AbstractSessionFederated.java diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/auth/provider/fa/FederatedUserDetails.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/auth/provider/fa/FederatedUserDetails.java similarity index 100% rename from server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/auth/provider/fa/FederatedUserDetails.java rename to server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/auth/provider/fa/FederatedUserDetails.java diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebSession.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebSession.java index 90709243ba..0ae1d6e0d6 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebSession.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebSession.java @@ -546,7 +546,7 @@ public class WebSession extends AbstractSessionPersistent implements SMSession, } clearAuthTokens(); this.sessionAuthContext.close(); - this.user = null; + setUser(null); if (this.sessionProject != null) { this.sessionProject.dispose(); @@ -760,7 +760,7 @@ public class WebSession extends AbstractSessionPersistent implements SMSession, } if (application.isConfigurationMode() && this.user == null && newUser != null) { //FIXME hotfix to avoid exception after external auth provider login in easy config - this.user = newUser; + setUser(newUser); refreshUserData(); } else if (!CommonUtils.equalObjects(this.user, newUser)) { throw new DBException("Can't authorize different users in the single session"); @@ -912,10 +912,14 @@ public class WebSession extends AbstractSessionPersistent implements SMSession, this.adminSecurityController = application.getAdminSecurityController(this); this.rmController = application.getResourceController(this); - this.user = tokenInfo.getUserId() == null ? null : new WebUser(securityController.getUserById(tokenInfo.getUserId())); + setUser(tokenInfo.getUserId() == null ? null : new WebUser(securityController.getUserById(tokenInfo.getUserId()))); refreshUserData(); } + private synchronized void setUser(@Nullable WebUser user) { + this.user = user; + } + @Override public SMCredentials getActiveUserCredentials() { return smCredentials; diff --git a/server/bundles/io.cloudbeaver.server/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.server/META-INF/MANIFEST.MF index 0df6e252a4..11458ae9a0 100644 --- a/server/bundles/io.cloudbeaver.server/META-INF/MANIFEST.MF +++ b/server/bundles/io.cloudbeaver.server/META-INF/MANIFEST.MF @@ -26,7 +26,6 @@ Require-Bundle: org.eclipse.core.runtime;visibility:=reexport, io.cloudbeaver.model;visibility:=reexport, io.cloudbeaver.service.security;visibility:=reexport Export-Package: io.cloudbeaver, - io.cloudbeaver.auth.provider.fa, io.cloudbeaver.model, io.cloudbeaver.model.resources, io.cloudbeaver.model.user, From 1afaf33a00651fbf101db20f426f5edc162e4d88 Mon Sep 17 00:00:00 2001 From: Ainur <59531286+yagudin10@users.noreply.github.com> Date: Mon, 30 May 2022 15:14:34 +0300 Subject: [PATCH 07/13] CB-1491 simple node without renaming (#869) --- .../cloudbeaver/service/navigator/WebNavigatorNodeInfo.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/WebNavigatorNodeInfo.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/WebNavigatorNodeInfo.java index 2b3d2477e6..3ad8be1f74 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/WebNavigatorNodeInfo.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/WebNavigatorNodeInfo.java @@ -154,7 +154,9 @@ public class WebNavigatorNodeInfo { features.add("canDelete"); } if (objectManager instanceof DBEObjectRenamer && ((DBEObjectRenamer) objectManager).canRenameObject(object)) { - features.add("canRename"); + if (!object.getDataSource().getContainer().getNavigatorSettings().isShowOnlyEntities()) { + features.add("canRename"); + } } } } From 2d689036f6941fa93b0381e94c662c97e61e7612 Mon Sep 17 00:00:00 2001 From: Ainur <59531286+yagudin10@users.noreply.github.com> Date: Mon, 30 May 2022 15:15:00 +0300 Subject: [PATCH 08/13] CB-2065 rm resource relative path and validation (#850) * CB-2065 rm resource relative path and validation * CB-2065 rm resource validation on reading and writing * CB-2065 rm resource validation on reading and writing * CB-2065 show illegal characters on exception * CB-2065 rm resource invalidate dot at the beginning of name * CB-2065 rm resource regex add space * CB-2065 rm regex add brackets --- .../rm/local/LocalResourceController.java | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java index ab0df10d21..f0e52880c3 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java @@ -49,6 +49,8 @@ public class LocalResourceController implements RMController { private static final Log log = Log.getLog(LocalResourceController.class); + private static final String FILE_REGEX = "(?U)[\\w.$() -]+"; + private static final String PROJECT_PREFIX_GLOBAL = "g_"; private static final String PROJECT_PREFIX_SHARED = "s_"; private static final String PROJECT_PREFIX_USER = "u_"; @@ -182,6 +184,7 @@ public class LocalResourceController implements RMController { @NotNull String resourcePath, boolean isFolder) throws DBException { + validateResourcePath(resourcePath); Path targetPath = getTargetPath(projectId, resourcePath); if (Files.exists(targetPath)) { throw new DBException("Resource '" + resourcePath + "' already exists"); @@ -205,6 +208,7 @@ public class LocalResourceController implements RMController { @Override public void deleteResource(@NotNull String projectId, @NotNull String resourcePath, boolean recursive) throws DBException { + validateResourcePath(resourcePath); Path targetPath = getTargetPath(projectId, resourcePath); if (!Files.exists(targetPath)) { throw new DBException("Resource '" + resourcePath + "' doesn't exists"); @@ -227,10 +231,11 @@ public class LocalResourceController implements RMController { public RMResource[] getResourcePath(@NotNull String projectId, @NotNull String resourcePath) throws DBException { return makeResourcePath(projectId, getTargetPath(projectId, resourcePath)).toArray(RMResource[]::new); } - + @NotNull @Override public byte[] getResourceContents(@NotNull String projectId, @NotNull String resourcePath) throws DBException { + validateResourcePath(resourcePath); Path targetPath = getTargetPath(projectId, resourcePath); if (!Files.exists(targetPath)) { throw new DBException("Resource '" + resourcePath + "' doesn't exists"); @@ -249,6 +254,7 @@ public class LocalResourceController implements RMController { @NotNull String resourcePath, @NotNull byte[] data) throws DBException { + validateResourcePath(resourcePath); Number fileSizeLimit = WebAppUtils.getWebApplication() .getAppConfiguration() .getResourceQuota(WebSQLConstants.QUOTA_PROP_RM_FILE_SIZE_LIMIT); @@ -272,6 +278,16 @@ public class LocalResourceController implements RMController { return DEFAULT_CHANGE_ID; } + private void validateResourcePath(String resourcePath) throws DBException { + if (resourcePath.startsWith(".")) { + throw new DBException("Resource path '" + resourcePath + "' can't start with dot"); + } + if (!resourcePath.matches(FILE_REGEX)) { + String illegalCharacters = resourcePath.replaceAll(FILE_REGEX, " ").strip(); + throw new DBException("Resource path '" + resourcePath + "' contains illegal characters: " + illegalCharacters); + } + } + @Override public void addRMEventListener(RMEventListener listener) { this.listeners.add(listener); @@ -307,7 +323,7 @@ public class LocalResourceController implements RMController { if (!targetPath.startsWith(projectPath)) { throw new DBException("Invalid resource path"); } - return targetPath; + return WebAppUtils.getWebApplication().getHomeDirectory().relativize(targetPath); } catch (InvalidPathException e) { throw new DBException("Resource path contains invalid characters"); } From fa3a01f335e05fceca42f2f08d8547120f0f3f3d Mon Sep 17 00:00:00 2001 From: Ainur <59531286+yagudin10@users.noreply.github.com> Date: Mon, 30 May 2022 15:15:34 +0300 Subject: [PATCH 09/13] CB-2073 db connection saved credentials fix (#855) --- .../src/io/cloudbeaver/WebServiceUtils.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java index 821146bfe3..ada59adda2 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java @@ -33,6 +33,7 @@ import org.jkiss.dbeaver.model.access.DBAAuthCredentials; import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry; import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration; import org.jkiss.dbeaver.model.connection.DBPDriver; +import org.jkiss.dbeaver.model.impl.auth.AuthModelDatabaseNativeCredentials; import org.jkiss.dbeaver.model.navigator.DBNBrowseSettings; import org.jkiss.dbeaver.model.navigator.DBNModel; import org.jkiss.dbeaver.model.net.DBWHandlerConfiguration; @@ -245,6 +246,7 @@ public class WebServiceUtils extends WebCommonUtils { if (authProperties == null) { authProperties = new LinkedHashMap<>(); } + authProperties.replace(AuthModelDatabaseNativeCredentials.PROP_USER_PASSWORD, null); } else { if (authProperties == null) { // No changes From 5ff6132c733d694521ef86ab70e885f69417d2be Mon Sep 17 00:00:00 2001 From: Ainur <59531286+yagudin10@users.noreply.github.com> Date: Mon, 30 May 2022 16:17:36 +0300 Subject: [PATCH 10/13] CB-1327 remove Diagram tab for Redis (#872) --- .../service/navigator/WebDatabaseObjectInfo.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/WebDatabaseObjectInfo.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/WebDatabaseObjectInfo.java index b93c9e8ba7..b8f0aefec4 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/WebDatabaseObjectInfo.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/WebDatabaseObjectInfo.java @@ -168,6 +168,7 @@ public class WebDatabaseObjectInfo { } private static void getObjectFeatures(DBSObject object, List features) { + boolean isDiagramSupported = true; if (object instanceof DBPScriptObject) features.add(OBJECT_FEATURE_SCRIPT); if (object instanceof DBPScriptObjectExt) features.add(OBJECT_FEATURE_SCRIPT_EXTENDED); if (object instanceof DBSDataContainer) { @@ -175,9 +176,14 @@ public class WebDatabaseObjectInfo { if (((DBSDataContainer) object).isFeatureSupported(DBSDataContainer.FEATURE_DATA_FILTER)) { features.add(OBJECT_FEATURE_DATA_CONTAINER_SUPPORTS_FILTERS); } + if (((DBSDataContainer) object).isFeatureSupported(DBSDataContainer.FEATURE_KEY_VALUE)) { + isDiagramSupported = false; + } } if (object instanceof DBSDataManipulator) features.add(OBJECT_FEATURE_DATA_MANIPULATOR); - if (object instanceof DBSEntity && !(object instanceof DBSDataType)) features.add(OBJECT_FEATURE_ENTITY); + if (object instanceof DBSEntity && !(object instanceof DBSDataType) && isDiagramSupported) { + features.add(OBJECT_FEATURE_ENTITY); + } if (object instanceof DBSSchema) features.add(OBJECT_FEATURE_SCHEMA); if (object instanceof DBSCatalog) features.add(OBJECT_FEATURE_CATALOG); if (object instanceof DBSObjectContainer) { From 5078102b392d96fd100a805063beca0fd05b9c3e Mon Sep 17 00:00:00 2001 From: Ainur <59531286+yagudin10@users.noreply.github.com> Date: Mon, 30 May 2022 16:18:05 +0300 Subject: [PATCH 11/13] CB-2089 add forwardProxy property to app configuration (#871) --- .../DefaultConfiguration/cloudbeaver.conf | 2 ++ .../SQLiteConfiguration/cloudbeaver.conf | 2 ++ .../src/io/cloudbeaver/server/CBAppConfig.java | 10 ++++++++++ .../src/io/cloudbeaver/server/CBApplication.java | 1 + .../src/io/cloudbeaver/server/jetty/CBJettyServer.java | 7 ++++++- 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/config/sample-databases/DefaultConfiguration/cloudbeaver.conf b/config/sample-databases/DefaultConfiguration/cloudbeaver.conf index 57d7546bfe..168e296f93 100644 --- a/config/sample-databases/DefaultConfiguration/cloudbeaver.conf +++ b/config/sample-databases/DefaultConfiguration/cloudbeaver.conf @@ -39,6 +39,8 @@ anonymousUserRole: "user", supportsCustomConnections: false, + forwardProxy: false, + publicCredentialsSaveEnabled: true, adminCredentialsSaveEnabled: true, diff --git a/config/sample-databases/SQLiteConfiguration/cloudbeaver.conf b/config/sample-databases/SQLiteConfiguration/cloudbeaver.conf index 30fbf76216..a1f14be291 100644 --- a/config/sample-databases/SQLiteConfiguration/cloudbeaver.conf +++ b/config/sample-databases/SQLiteConfiguration/cloudbeaver.conf @@ -39,6 +39,8 @@ anonymousUserRole: "user", supportsCustomConnections: false, + forwardProxy: false, + publicCredentialsSaveEnabled: true, adminCredentialsSaveEnabled: true, diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBAppConfig.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBAppConfig.java index b873464f2f..10f9e129d4 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBAppConfig.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBAppConfig.java @@ -46,6 +46,7 @@ public class CBAppConfig extends BaseWebAppConfiguration { private boolean supportsConnectionBrowser; private boolean supportsUserWorkspaces; private boolean enableReverseProxyAuth; + private boolean forwardProxy; private boolean publicCredentialsSaveEnabled; private boolean adminCredentialsSaveEnabled; @@ -79,6 +80,7 @@ public class CBAppConfig extends BaseWebAppConfiguration { this.authConfiguration = new LinkedHashMap<>(); this.resourceQuotas = new LinkedHashMap<>(); this.enableReverseProxyAuth = false; + this.forwardProxy = false; } public CBAppConfig(CBAppConfig src) { @@ -98,6 +100,7 @@ public class CBAppConfig extends BaseWebAppConfiguration { this.authConfiguration = new LinkedHashMap<>(src.authConfiguration); this.resourceQuotas = new LinkedHashMap<>(src.resourceQuotas); this.enableReverseProxyAuth = src.enableReverseProxyAuth; + this.forwardProxy = src.forwardProxy; } @@ -310,4 +313,11 @@ public class CBAppConfig extends BaseWebAppConfiguration { return enableReverseProxyAuth; } + //////////////////////////////////////////// + // Forward proxy + + public boolean isEnabledForwardProxy() { + return forwardProxy; + } + } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBApplication.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBApplication.java index 258c0d7f5d..e84c417658 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBApplication.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBApplication.java @@ -778,6 +778,7 @@ public class CBApplication extends BaseWebApplication { JSONUtils.field(json, "publicCredentialsSaveEnabled", appConfig.isPublicCredentialsSaveEnabled()); JSONUtils.field(json, "adminCredentialsSaveEnabled", appConfig.isAdminCredentialsSaveEnabled()); JSONUtils.field(json, "enableReverseProxyAuth", appConfig.isEnabledReverseProxyAuth()); + JSONUtils.field(json, "forwardProxy", appConfig.isEnabledForwardProxy()); JSONUtils.field(json, CBConstants.PARAM_RESOURCE_MANAGER_ENABLED, appConfig.isResourceManagerEnabled()); Map resourceQuotas = appConfig.getResourceQuotas(); diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBJettyServer.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBJettyServer.java index 803cf03a5b..306c645c6a 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBJettyServer.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBJettyServer.java @@ -93,12 +93,17 @@ public class CBJettyServer { } + boolean forwardProxy = application.getAppConfiguration().isEnabledForwardProxy(); { // HTTP config for(Connector y : server.getConnectors()) { for(ConnectionFactory x : y.getConnectionFactories()) { if(x instanceof HttpConnectionFactory) { - ((HttpConnectionFactory)x).getHttpConfiguration().setSendServerVersion(false); + HttpConfiguration httpConfiguration = ((HttpConnectionFactory)x).getHttpConfiguration(); + httpConfiguration.setSendServerVersion(false); + if (forwardProxy) { + httpConfiguration.addCustomizer(new ForwardedRequestCustomizer()); + } } } } From f4db7297bf6df91d40a7060888a1cf11a0ce0dd6 Mon Sep 17 00:00:00 2001 From: Wroud Date: Mon, 30 May 2022 20:06:39 +0300 Subject: [PATCH 12/13] fix(core-connections): CB-1947 extra error notification --- .../shared/NodesManager/NavNodeManagerService.ts | 8 +------- .../src/ConnectionsManagerService.ts | 14 +++++++++----- .../src/ObjectPropertiesPage/ObjectFolders.tsx | 14 +++++++++----- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/webapp/packages/core-app/src/shared/NodesManager/NavNodeManagerService.ts b/webapp/packages/core-app/src/shared/NodesManager/NavNodeManagerService.ts index 17006258c2..feaab27e9d 100644 --- a/webapp/packages/core-app/src/shared/NodesManager/NavNodeManagerService.ts +++ b/webapp/packages/core-app/src/shared/NodesManager/NavNodeManagerService.ts @@ -327,13 +327,7 @@ export class NavNodeManagerService extends Bootstrap { const nodeInfo = await contexts.getContext(this.navigationNavNodeContext); if (NodeManagerUtils.isDatabaseObject(nodeInfo.nodeId) && nodeInfo.connection) { - let connection: Connection | null; - try { - connection = await this.connectionsManagerService.requireConnection(nodeInfo.connection.id); - } catch (exception: any) { - this.notificationService.logException(exception); - throw exception; - } + const connection = await this.connectionsManagerService.requireConnection(nodeInfo.connection.id); if (!connection?.connected) { throw new Error('Connection not established'); diff --git a/webapp/packages/core-connections/src/ConnectionsManagerService.ts b/webapp/packages/core-connections/src/ConnectionsManagerService.ts index bb5a30192b..578f42dbf1 100644 --- a/webapp/packages/core-connections/src/ConnectionsManagerService.ts +++ b/webapp/packages/core-connections/src/ConnectionsManagerService.ts @@ -35,10 +35,14 @@ export class ConnectionsManagerService { } async requireConnection(connectionId: string | null = null): Promise { - const context = await this.connectionExecutor.execute(connectionId); - const connection = context.getContext(this.connectionContext); + try { + const context = await this.connectionExecutor.execute(connectionId); + const connection = context.getContext(this.connectionContext); - return connection.connection; + return connection.connection; + } catch { + return null; + } } async addOpenedConnection(connection: Connection): Promise { @@ -50,7 +54,7 @@ export class ConnectionsManagerService { objectCatalogId?: string, objectSchemaId?: string ): ObjectContainer | undefined { - if (objectCatalogId){ + if (objectCatalogId) { const objectContainers = this.containerContainers.getCatalogData(connectionId, objectCatalogId); if (!objectContainers) { @@ -60,7 +64,7 @@ export class ConnectionsManagerService { if (!objectSchemaId) { return objectContainers.catalog; } - + return objectContainers.schemaList.find( objectContainer => objectContainer.name === objectSchemaId ); diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFolders.tsx b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFolders.tsx index 53705736d6..fedd57a88e 100644 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFolders.tsx +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFolders.tsx @@ -77,11 +77,6 @@ export const ObjectFolders = observer(function ObjectFolders({ tab }) { }); const folders = navNodeViewService.getFolders(nodeId) || []; - - function openFolder(tabData: ITabData) { - navNodeManagerService.navToNode(nodeId, parentId, tabData.tabId); - } - const wrongFolder = ( !folders.includes(folderId) && folders.length > 0 @@ -94,6 +89,15 @@ export const ObjectFolders = observer(function ObjectFolders({ tab }) { folderId = folders[0]; } + function openFolder(tabData: ITabData) { + if (tabData.tabId === folderId) { + return; + } + + navNodeManagerService.navToNode(nodeId, parentId, tabData.tabId); + } + + useEffect(() => { if (wrongFolder) { navNodeManagerService.navToNode(nodeId, parentId, folderId); From ceb1f12ac8b1e7e9fd41428e4aa44069240cf15d Mon Sep 17 00:00:00 2001 From: Naumov Alexey Date: Tue, 31 May 2022 12:12:32 +0200 Subject: [PATCH 13/13] fix(core-app): CB-2012 revert preview --- .../ElementsTree/NavigationTreeNode/NavigationNode.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/packages/core-app/src/NavigationTree/ElementsTree/NavigationTreeNode/NavigationNode.tsx b/webapp/packages/core-app/src/NavigationTree/ElementsTree/NavigationTreeNode/NavigationNode.tsx index 78bd71ba35..b714d44dbc 100644 --- a/webapp/packages/core-app/src/NavigationTree/ElementsTree/NavigationTreeNode/NavigationNode.tsx +++ b/webapp/packages/core-app/src/NavigationTree/ElementsTree/NavigationTreeNode/NavigationNode.tsx @@ -84,7 +84,7 @@ export const NavigationNode: NavigationNodeComponent = observer(function Navigat onOpen={handleOpen} onSelect={handleSelect} > - + {/* */} {(expanded || expandedExternal) && }