From 3b6bfe2a4ebd7aad78ee8970d71809b4ae5e68e8 Mon Sep 17 00:00:00 2001 From: yagudin10 Date: Mon, 22 Aug 2022 13:23:18 +0300 Subject: [PATCH 1/8] CB-2365 reverse proxy anonymous access enabled fix --- .../service/auth/RPSessionHandler.java | 35 +++---------------- 1 file changed, 4 insertions(+), 31 deletions(-) diff --git a/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/RPSessionHandler.java b/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/RPSessionHandler.java index fcb178b64b..a4a87437b4 100644 --- a/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/RPSessionHandler.java +++ b/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/RPSessionHandler.java @@ -16,31 +16,26 @@ */ package io.cloudbeaver.service.auth; -import io.cloudbeaver.DBWUserIdentity; import io.cloudbeaver.DBWebException; import io.cloudbeaver.auth.SMAuthProviderExternal; import io.cloudbeaver.auth.provider.rp.RPAuthProvider; -import io.cloudbeaver.model.session.WebAuthInfo; import io.cloudbeaver.model.session.WebSession; -import io.cloudbeaver.model.user.WebUser; +import io.cloudbeaver.model.session.WebSessionAuthProcessor; import io.cloudbeaver.server.CBApplication; import io.cloudbeaver.service.DBWSessionHandler; import org.jkiss.code.NotNull; import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.model.auth.SMAuthInfo; -import org.jkiss.dbeaver.model.auth.SMSession; import org.jkiss.dbeaver.model.security.SMConstants; import org.jkiss.dbeaver.model.security.SMController; import org.jkiss.dbeaver.model.security.exception.SMException; import org.jkiss.dbeaver.registry.auth.AuthProviderDescriptor; import org.jkiss.dbeaver.registry.auth.AuthProviderRegistry; -import org.jkiss.utils.CommonUtils; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; -import java.time.OffsetDateTime; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -70,7 +65,6 @@ public class RPSessionHandler implements DBWSessionHandler { String userName = request.getHeader(RPAuthProvider.X_USER); String roles = request.getHeader(RPAuthProvider.X_ROLE); List userRoles = roles == null ? Collections.emptyList() : List.of(roles.split("\\|")); - SMSession authSession; if (userName != null) { try { Map credentials = new HashMap<>(); @@ -79,39 +73,18 @@ public class RPSessionHandler implements DBWSessionHandler { sessionParameters.put(SMConstants.SESSION_PARAM_TRUSTED_USER_ROLES, userRoles); Map userCredentials = authProviderExternal.authExternalUser( webSession.getProgressMonitor(), sessionParameters, credentials); + String currentSmSessionId = webSession.getUser() == null ? null : webSession.getUserContext().getSmSessionId(); try { SMAuthInfo smAuthInfo = securityController.authenticate( webSession.getSessionId(), - webSession.getUserContext().getSmSessionId(), + currentSmSessionId, sessionParameters, WebSession.CB_SESSION_TYPE, authProvider.getId(), null, userCredentials); - webSession.updateSMAuthInfo(smAuthInfo); + new WebSessionAuthProcessor(webSession, smAuthInfo, false).authenticateSession(); } catch (SMException e) { log.debug("Error during user authentication", e); throw e; } - WebUser user = webSession.getUser(); - DBWUserIdentity userIdentity = authProviderExternal.getUserIdentity( - webSession.getProgressMonitor(), sessionParameters, credentials); - - if (CommonUtils.isEmpty(user.getDisplayName())) { - user.setDisplayName(userIdentity.getDisplayName()); - } - authSession = authProviderExternal.openSession( - webSession.getProgressMonitor(), - webSession, - sessionParameters, - userCredentials); - - WebAuthInfo authInfo = new WebAuthInfo( - webSession, - user, - authProvider, - userIdentity, - authSession, - OffsetDateTime.now()); - authInfo.setMessage("Authenticated with " + authProvider.getLabel() + " provider"); - webSession.addAuthInfo(authInfo); } catch (Exception e) { throw new DBWebException("Error", e); } From 819b84cc9be992d902c5b35491b13d6c4c18c9b5 Mon Sep 17 00:00:00 2001 From: yagudin10 Date: Mon, 22 Aug 2022 18:29:37 +0300 Subject: [PATCH 2/8] CB-2365 rp tests --- .../io/cloudbeaver/utils/WebTestUtils.java | 19 +++++++-- .../test/platform/AuthenticationTest.java | 42 +++++++++++++++++++ .../workspace/conf/cloudbeaver.conf | 5 ++- .../workspace/gql_scripts/activeUser.json | 4 ++ .../workspace/gql_scripts/openSession.json | 7 ++++ 5 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/activeUser.json create mode 100644 server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/openSession.json diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebTestUtils.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebTestUtils.java index 24b59dbc0a..17456db347 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebTestUtils.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebTestUtils.java @@ -29,6 +29,7 @@ import java.net.http.HttpResponse; import java.nio.file.Files; import java.nio.file.Path; import java.util.Collections; +import java.util.List; import java.util.Map; public class WebTestUtils { @@ -42,12 +43,24 @@ public class WebTestUtils { public static Map doPost(String apiUrl, String input, HttpClient client) throws Exception { - HttpRequest request = HttpRequest.newBuilder() + return doPostWithHeaders(apiUrl, input, client, List.of()); + } + + public static Map doPostWithHeaders( + String apiUrl, + String input, + HttpClient client, + List headers + ) throws Exception { + HttpRequest.Builder requestBuilder = HttpRequest.newBuilder() .uri(URI.create(apiUrl)) .POST(HttpRequest.BodyPublishers.ofString(input)) - .header("Content-Type", "application/json") - .build(); + .header("Content-Type", "application/json"); + if (!headers.isEmpty()) { + requestBuilder.headers(headers.toArray(String[]::new)); + } + HttpRequest request = requestBuilder.build(); HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); diff --git a/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/AuthenticationTest.java b/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/AuthenticationTest.java index 22adf77024..9a58c32163 100644 --- a/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/AuthenticationTest.java +++ b/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/AuthenticationTest.java @@ -1,15 +1,23 @@ package io.cloudbeaver.test.platform; +import io.cloudbeaver.auth.provider.rp.RPAuthProvider; import io.cloudbeaver.utils.WebTestUtils; import org.jkiss.dbeaver.model.auth.SMAuthStatus; import org.jkiss.dbeaver.model.data.json.JSONUtils; import org.junit.Assert; import org.junit.Test; +import org.mockito.Mockito; import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.util.Collections; +import java.util.List; import java.util.Map; public class AuthenticationTest { + public static final String GQL_TEMPLATE_OPEN_SESSION = "openSession.json"; + public static final String GQL_TEMPLATE_ACTIVE_USER = "activeUser.json"; + public static final String REVERSE_PROXY_TEST_USER = "reverseProxyTestUser"; @Test public void testLoginUser() throws Exception { @@ -18,4 +26,38 @@ public class AuthenticationTest { client, CEServerTestSuite.getScriptsPath(), CEServerTestSuite.GQL_API_URL); Assert.assertEquals(SMAuthStatus.SUCCESS.name(), JSONUtils.getString(authInfo, "authStatus")); } + + @Test + public void testReverseProxyAnonymousModeLogin() throws Exception { + HttpClient client = CEServerTestSuite.getClient(); + Map sessionInfo = openSession(client); + Assert.assertTrue(JSONUtils.getBoolean(sessionInfo, "valid")); + Map activeUser = getActiveUser(client); + Assert.assertEquals(REVERSE_PROXY_TEST_USER, JSONUtils.getString(activeUser, "userId")); + } + + private Map openSession(HttpClient client) throws Exception { + Map data = doPostQuery(client, GQL_TEMPLATE_OPEN_SESSION); + if (data != null) { + return JSONUtils.getObject(data, "session"); + } + return Collections.emptyMap(); + } + + private Map getActiveUser(HttpClient client) throws Exception { + Map data = doPostQuery(client, GQL_TEMPLATE_ACTIVE_USER); + if (data != null) { + return JSONUtils.getObject(data, "user"); + } + return Collections.emptyMap(); + } + + private Map doPostQuery(HttpClient client, String gqlScript) throws Exception { + String input = WebTestUtils.readScriptTemplate(gqlScript, CEServerTestSuite.getScriptsPath()); + List headers = List.of(RPAuthProvider.X_USER, REVERSE_PROXY_TEST_USER, RPAuthProvider.X_ROLE, "user"); + Map map = WebTestUtils.doPostWithHeaders(CEServerTestSuite.GQL_API_URL, input, client, headers); + return JSONUtils.getObjectOrNull(map, "data"); + } + + } diff --git a/server/test/io.cloudbeaver.test.platform/workspace/conf/cloudbeaver.conf b/server/test/io.cloudbeaver.test.platform/workspace/conf/cloudbeaver.conf index e6d24f8063..f56cacd670 100644 --- a/server/test/io.cloudbeaver.test.platform/workspace/conf/cloudbeaver.conf +++ b/server/test/io.cloudbeaver.test.platform/workspace/conf/cloudbeaver.conf @@ -1,6 +1,7 @@ { server: { serverPort: "${CLOUDBEAVER_TEST_PORT:18978}", + serverName: "CloudBeaver CE Test Server", workspaceLocation: "workspace", contentRoot: "workspace/web", @@ -36,8 +37,10 @@ anonymousAccessEnabled: true, anonymousUserRole: "user", supportsCustomConnections: true, + enableReverseProxyAuth: true, enabledAuthProviders: [ - "local" + "local", + "reverseProxy" ], enabledFeatures: [ diff --git a/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/activeUser.json b/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/activeUser.json new file mode 100644 index 0000000000..97b079675a --- /dev/null +++ b/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/activeUser.json @@ -0,0 +1,4 @@ +{ + "query": "\n query activeUser {\n user: activeUser {\n userId\n }\n}\n ", + "operationName": "activeUser" +} \ No newline at end of file diff --git a/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/openSession.json b/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/openSession.json new file mode 100644 index 0000000000..eff24dcf81 --- /dev/null +++ b/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/openSession.json @@ -0,0 +1,7 @@ +{ + "query": "\n mutation openSession($defaultLocale: String) {\n session: openSession(defaultLocale: $defaultLocale) {\n valid\n }\n}\n ", + "variables": { + "defaultLocale": "en" + }, + "operationName": "openSession" +} \ No newline at end of file From 4dc8f1970c33bddd9366ff1667470508e7b7549b Mon Sep 17 00:00:00 2001 From: Konstantin Vasilev Date: Mon, 29 Aug 2022 17:53:06 +0300 Subject: [PATCH 3/8] CB-1857 feat(plugin-gis-viewer): Add combobox for crs selecting --- .../core-blocks/src/FormControls/Combobox.tsx | 10 ++-- .../plugin-gis-viewer/src/CrsInput.tsx | 50 ++++++++++++++++ .../src/GISValuePresentation.tsx | 57 +++++++++++++++++-- .../plugin-gis-viewer/src/LeafletMap.tsx | 21 ++++--- 4 files changed, 119 insertions(+), 19 deletions(-) create mode 100644 webapp/packages/plugin-gis-viewer/src/CrsInput.tsx diff --git a/webapp/packages/core-blocks/src/FormControls/Combobox.tsx b/webapp/packages/core-blocks/src/FormControls/Combobox.tsx index 9c7fdc5ba4..b82dbb201f 100644 --- a/webapp/packages/core-blocks/src/FormControls/Combobox.tsx +++ b/webapp/packages/core-blocks/src/FormControls/Combobox.tsx @@ -90,7 +90,7 @@ const styles = css` width: 100%; height: 100%; } - } + } } } Icon { @@ -112,12 +112,12 @@ const styles = css` width: 16px; height: 16px; margin-left: 12px; - + & IconOrImage { width: 100%; height: 100%; } - + &:not(:empty) + input { padding-left: 34px !important; } @@ -131,8 +131,8 @@ type BaseProps = Omit, searchable?: boolean; defaultValue?: TKey; loading?: boolean; - keySelector: (item: TValue, index: number) => TKey; - valueSelector: (item: TValue) => string; + keySelector?: (item: TValue, index: number) => TKey; + valueSelector?: (item: TValue) => string; titleSelector?: (item: TValue) => string | undefined; iconSelector?: (item: TValue) => string | React.ReactElement | undefined; isDisabled?: (item: TValue) => boolean; diff --git a/webapp/packages/plugin-gis-viewer/src/CrsInput.tsx b/webapp/packages/plugin-gis-viewer/src/CrsInput.tsx new file mode 100644 index 0000000000..d3e4836764 --- /dev/null +++ b/webapp/packages/plugin-gis-viewer/src/CrsInput.tsx @@ -0,0 +1,50 @@ +import styled, { css } from 'reshadow'; + +import { Combobox } from '@cloudbeaver/core-blocks'; + +import type { CrsKey } from './LeafletMap'; + +const styles = css` + root { + display: inline-flex; + align-items: center; + font-size: 12px; + } + + label { + margin-right: 4px; + flex-grow: 0; + flex-shrink: 1; + } + + Combobox { + width: 120px; + flex: 0 0 auto; + } +`; + +interface Props { + value: CrsKey; + onChange: (value: CrsKey) => void; +} + +const items: CrsKey[] = [ + 'Simple', + 'EPSG3395', + 'EPSG3857', + 'EPSG4326', + 'EPSG900913', +]; + +export function CrsInput(props: Props) { + return styled(styles)( + + + + + ); +} \ No newline at end of file diff --git a/webapp/packages/plugin-gis-viewer/src/GISValuePresentation.tsx b/webapp/packages/plugin-gis-viewer/src/GISValuePresentation.tsx index 43e5322b1b..1c97f0ff2d 100644 --- a/webapp/packages/plugin-gis-viewer/src/GISValuePresentation.tsx +++ b/webapp/packages/plugin-gis-viewer/src/GISValuePresentation.tsx @@ -5,18 +5,51 @@ * 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 { useCallback, useMemo } from 'react'; +import { useCallback, useMemo, useState } from 'react'; +import styled, { css } from 'reshadow'; import wellknown from 'wellknown'; import { TextPlaceholder } from '@cloudbeaver/core-blocks'; import { useTranslate } from '@cloudbeaver/core-localization'; import { IDatabaseResultSet, ResultSetSelectAction, IResultSetElementKey, IDatabaseDataModel, ResultSetViewAction, ResultSetDataKeysUtils } from '@cloudbeaver/plugin-data-viewer'; -import { IGeoJSONFeature, IAssociatedValue, LeafletMap } from './LeafletMap'; +import { CrsInput } from './CrsInput'; +import { IGeoJSONFeature, IAssociatedValue, LeafletMap, CrsKey } from './LeafletMap'; import { ResultSetGISAction } from './ResultSetGISAction'; +function getCrsKey(feature?: IGeoJSONFeature): CrsKey { + switch (feature?.properties.srid) { + case 3857: + return 'EPSG3857'; + case 4326: + return 'EPSG4326'; + case 3395: + return 'EPSG3395'; + case 900913: + return 'EPSG900913'; + default: + return 'EPSG3857'; + } +} + +const styles = css` + root { + display: flex; + flex-direction: column; + width: 100%; + } + + map { + flex: 1 1 auto; + } + + toolbar { + margin-top: 8px; + flex: 0 0 auto; + } +`; + interface Props { model: IDatabaseDataModel; resultIndex: number; @@ -87,11 +120,25 @@ export const GISValuePresentation = observer(function GISValuePresentatio return values; }, [view]); + + const defaultCrsKey = getCrsKey(parsedGISData[0]); + const [crsKey, setCrsKey] = useState(defaultCrsKey); + if (!parsedGISData.length) { return {translate('gis_presentation_placeholder')}; } - return ( - + return styled(styles)( + + + + + + + + ); }); diff --git a/webapp/packages/plugin-gis-viewer/src/LeafletMap.tsx b/webapp/packages/plugin-gis-viewer/src/LeafletMap.tsx index bff6d0153f..0a7673ae2b 100644 --- a/webapp/packages/plugin-gis-viewer/src/LeafletMap.tsx +++ b/webapp/packages/plugin-gis-viewer/src/LeafletMap.tsx @@ -42,8 +42,11 @@ interface IBaseTile extends TileLayerProps { checked?: boolean; } +export type CrsKey = 'Simple' | 'EPSG3857' | 'EPSG4326' | 'EPSG3395' | 'EPSG900913'; + interface Props { geoJSON: IGeoJSONFeature[]; + crsKey: CrsKey; getAssociatedValues: (cell: IResultSetElementKey) => IAssociatedValue[]; } @@ -87,17 +90,17 @@ function polyStyle() { }; } -function getCRS(feature?: IGeoJSONFeature): leaflet.CRS { - switch (feature?.properties.srid) { - case 0: +function getCRS(crsKey: CrsKey): leaflet.CRS { + switch (crsKey) { + case 'Simple': return leaflet.CRS.Simple; - case 3857: + case 'EPSG3857': return leaflet.CRS.EPSG3857; - case 4326: + case 'EPSG4326': return leaflet.CRS.EPSG4326; - case 3395: + case 'EPSG3395': return leaflet.CRS.EPSG3395; - case 900913: + case 'EPSG900913': return leaflet.CRS.EPSG900913; default: return leaflet.CRS.EPSG3857; @@ -111,14 +114,14 @@ const styles = css` } `; -export const LeafletMap: React.FC = function LeafletMap({ geoJSON, getAssociatedValues }) { +export const LeafletMap: React.FC = function LeafletMap({ geoJSON, crsKey, getAssociatedValues }) { const splitContext = useSplit(); const translate = useTranslate(); const [mapRef, setMapRef] = useState(null); const [geoJSONLayerRef, setGeoJSONLayerRef] = useState(null); - const crs = getCRS(geoJSON[0]); + const crs = getCRS(crsKey); const onEachFeature = useCallback((feature: IGeoJSONFeature, layer: leaflet.Layer) => { const associatedValues = getAssociatedValues(feature.properties.associatedCell); From 83f64269817d4a1386b60ce41033db1ac0fed765 Mon Sep 17 00:00:00 2001 From: Serge Rider Date: Tue, 30 Aug 2022 12:26:03 +0200 Subject: [PATCH 4/8] CB-2415 Do not save admin connection on connect in public interface (#1083) --- .../src/io/cloudbeaver/WebServiceUtils.java | 5 ++++- .../service/core/impl/WebServiceCore.java | 17 +++++++++++------ .../service/admin/impl/WebServiceAdmin.java | 4 ++-- 3 files changed, 17 insertions(+), 9 deletions(-) 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 b3b5ef96e3..08010f6d82 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java @@ -34,6 +34,7 @@ import org.jkiss.dbeaver.model.DBPDataSourceContainer; import org.jkiss.dbeaver.model.DBPDataSourceFolder; import org.jkiss.dbeaver.model.access.DBAAuthCredentials; import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry; +import org.jkiss.dbeaver.model.app.DBPProject; import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration; import org.jkiss.dbeaver.model.connection.DBPDriver; import org.jkiss.dbeaver.model.impl.auth.AuthModelDatabaseNativeCredentials; @@ -42,7 +43,6 @@ import org.jkiss.dbeaver.model.navigator.DBNModel; import org.jkiss.dbeaver.model.navigator.DBNProject; import org.jkiss.dbeaver.model.net.DBWHandlerConfiguration; import org.jkiss.dbeaver.model.net.ssh.SSHConstants; -import org.jkiss.dbeaver.model.rm.RMProject; import org.jkiss.dbeaver.registry.DataSourceDescriptor; import org.jkiss.dbeaver.registry.DataSourceNavigatorSettings; import org.jkiss.dbeaver.registry.DataSourceProviderDescriptor; @@ -340,6 +340,9 @@ public class WebServiceUtils extends WebCommonUtils { DBNModel.updateConfigAndRefreshDatabases(projectNode.getDatabases()); } + public static boolean isGlobalProject(DBPProject project) { + return CommonUtils.equalObjects(CBApplication.getInstance().getDefaultProjectName(), project.getName()); + } } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java index 445dcb24db..ab6e649038 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java @@ -21,17 +21,14 @@ import io.cloudbeaver.DBWConstants; import io.cloudbeaver.DBWebException; import io.cloudbeaver.WebServiceUtils; import io.cloudbeaver.model.*; -import io.cloudbeaver.model.app.BaseWebApplication; -import io.cloudbeaver.model.app.WebAppConfiguration; import io.cloudbeaver.model.session.WebSession; import io.cloudbeaver.registry.WebHandlerRegistry; import io.cloudbeaver.registry.WebSessionHandlerDescriptor; -import io.cloudbeaver.server.CBAppConfig; import io.cloudbeaver.server.CBApplication; import io.cloudbeaver.server.CBPlatform; import io.cloudbeaver.service.core.DBWServiceCore; -import io.cloudbeaver.utils.WebDataSourceUtils; import io.cloudbeaver.utils.WebConnectionFolderUtils; +import io.cloudbeaver.utils.WebDataSourceUtils; import org.jkiss.code.NotNull; import org.jkiss.code.Nullable; import org.jkiss.dbeaver.DBException; @@ -55,7 +52,6 @@ import org.jkiss.dbeaver.registry.DataSourceDescriptor; import org.jkiss.dbeaver.registry.DataSourceProviderRegistry; import org.jkiss.dbeaver.registry.network.NetworkHandlerDescriptor; import org.jkiss.dbeaver.registry.network.NetworkHandlerRegistry; -import org.jkiss.dbeaver.runtime.DBWorkbench; import org.jkiss.dbeaver.runtime.jobs.ConnectionTestJob; import org.jkiss.dbeaver.utils.RuntimeUtils; import org.jkiss.utils.CommonUtils; @@ -294,6 +290,8 @@ public class WebServiceCore implements DBWServiceCore { connectionInfo.clearSavedCredentials(); } // Mark all specified network configs as saved + boolean[] saveConfig = new boolean[1]; + if (networkCredentials != null) { networkCredentials.forEach(c -> { if (CommonUtils.toBoolean(c.isSavePassword()) && !CommonUtils.isEmpty(c.getUserName())) { @@ -302,7 +300,7 @@ public class WebServiceCore implements DBWServiceCore { handlerCfg.setUserName(c.getUserName()); handlerCfg.setPassword(c.getPassword()); handlerCfg.setSavePassword(true); - dataSourceContainer.persistConfiguration(); + saveConfig[0] = true; } } }); @@ -316,6 +314,13 @@ public class WebServiceCore implements DBWServiceCore { true); WebDataSourceUtils.saveCredentialsInDataSource(connectionInfo, dataSourceContainer, dataSourceContainer.getConnectionConfiguration()); + saveConfig[0] = true; + } + if (WebServiceUtils.isGlobalProject(dataSourceContainer.getProject())) { + // Do not flush config for global project (only admin can do it - CB-2415) + saveConfig[0] = false; + } + if (saveConfig[0]) { dataSourceContainer.persistConfiguration(); } diff --git a/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/WebServiceAdmin.java b/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/WebServiceAdmin.java index d781168a26..2fd74b31bd 100644 --- a/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/WebServiceAdmin.java +++ b/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/WebServiceAdmin.java @@ -660,7 +660,7 @@ public class WebServiceAdmin implements DBWServiceAdmin { String connectionId ) throws DBWebException { DBPProject globalProject = webSession.getProjectById(projectId); - if (!CommonUtils.equalObjects(globalProject.getName(), CBApplication.getInstance().getDefaultProjectName())) { + if (!WebServiceUtils.isGlobalProject(globalProject)) { throw new DBWebException("Project '" + projectId + "'is not global"); } try { @@ -685,7 +685,7 @@ public class WebServiceAdmin implements DBWServiceAdmin { @NotNull List subjects ) throws DBWebException { DBPProject globalProject = webSession.getProjectById(projectId); - if (!CommonUtils.equalObjects(globalProject.getName(), CBApplication.getInstance().getDefaultProjectName())) { + if (!WebServiceUtils.isGlobalProject(globalProject)) { throw new DBWebException("Project '" + projectId + "'is not global"); } DBPDataSourceContainer dataSource = getGlobalRegistry(webSession).getDataSource(connectionId); From 136fa13e4152a81a3f5200c77b09d4da7ebeeba5 Mon Sep 17 00:00:00 2001 From: Serge Rider Date: Tue, 30 Aug 2022 12:26:24 +0200 Subject: [PATCH 5/8] CB-2480 Disable "show system objects" by default (#1084) --- .../src/io/cloudbeaver/server/CBAppConfig.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 87f562c63f..8fd830c197 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 @@ -35,7 +35,9 @@ import java.util.Map; * Application configuration */ public class CBAppConfig extends BaseAuthWebAppConfiguration implements WebAuthConfiguration { - public static final DataSourceNavigatorSettings DEFAULT_VIEW_SETTINGS = DataSourceNavigatorSettings.PRESET_FULL.getSettings(); + public static final DataSourceNavigatorSettings.Preset PRESET_WEB = new DataSourceNavigatorSettings.Preset("web", "Web", "Default view"); + + public static final DataSourceNavigatorSettings DEFAULT_VIEW_SETTINGS = PRESET_WEB.getSettings(); private boolean supportsCustomConnections; private boolean supportsConnectionBrowser; From 57b95a0c5bece3775b61f2d627f20b89af5ce2d2 Mon Sep 17 00:00:00 2001 From: ShadelessFox <35821147+ShadelessFox@users.noreply.github.com> Date: Tue, 30 Aug 2022 18:50:29 +0300 Subject: [PATCH 6/8] dbeaver/dbeaver-ee#1788 Remember session start datetime (#1082) --- .../auth/provider/fa/AbstractSessionFederated.java | 7 +++++++ .../src/io/cloudbeaver/model/session/WebSession.java | 9 +++++++++ .../auth/provider/local/LocalAuthSession.java | 8 ++++++++ 3 files changed, 24 insertions(+) diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/auth/provider/fa/AbstractSessionFederated.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/auth/provider/fa/AbstractSessionFederated.java index 4b9edeca46..daffd15ed4 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/auth/provider/fa/AbstractSessionFederated.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/auth/provider/fa/AbstractSessionFederated.java @@ -22,6 +22,7 @@ import org.jkiss.code.Nullable; import org.jkiss.dbeaver.model.app.DBPProject; import org.jkiss.dbeaver.model.auth.*; +import java.time.LocalDateTime; import java.util.Map; public abstract class AbstractSessionFederated implements SMSessionFederated { @@ -56,6 +57,12 @@ public abstract class AbstractSessionFederated implements SMSessionFederated { return parentSession.getSessionPrincipal(); } + @NotNull + @Override + public LocalDateTime getSessionStart() { + return parentSession.getSessionStart(); + } + @Override public boolean isApplicationSession() { return false; 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 c0f0872e8f..adad2d4f5c 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 @@ -70,6 +70,9 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.lang.reflect.InvocationTargetException; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; @@ -160,6 +163,12 @@ public class WebSession extends AbstractSessionPersistent implements SMSession, return id; } + @NotNull + @Override + public LocalDateTime getSessionStart() { + return LocalDateTime.ofInstant(Instant.ofEpochMilli(createTime), ZoneId.systemDefault()); + } + public WebApplication getApplication() { return application; } diff --git a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/auth/provider/local/LocalAuthSession.java b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/auth/provider/local/LocalAuthSession.java index 9c6b98478b..bc876fcbdf 100644 --- a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/auth/provider/local/LocalAuthSession.java +++ b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/auth/provider/local/LocalAuthSession.java @@ -24,6 +24,8 @@ import org.jkiss.dbeaver.model.auth.SMSession; import org.jkiss.dbeaver.model.auth.SMSessionContext; import org.jkiss.dbeaver.model.auth.SMSessionPrincipal; +import java.time.LocalDateTime; + /** * Local auth provider */ @@ -65,6 +67,12 @@ public class LocalAuthSession implements SMSession { return webSession.getSessionId(); } + @NotNull + @Override + public LocalDateTime getSessionStart() { + return webSession.getSessionStart(); + } + @Override public boolean isApplicationSession() { return false; From 94c8fa0cd628542631bf30062f0791b98be23d11 Mon Sep 17 00:00:00 2001 From: Ainur <59531286+yagudin10@users.noreply.github.com> Date: Wed, 31 Aug 2022 10:57:26 +0300 Subject: [PATCH 7/8] CB-779 athena db use provider property for s3 location (#1077) --- .../io.cloudbeaver.server/schema/service.core.graphqls | 1 + .../src/io/cloudbeaver/WebServiceUtils.java | 4 +++- .../io/cloudbeaver/model/WebDatabaseDriverConfig.java | 10 ++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls b/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls index 54d2bb2dd2..c097dd45e4 100644 --- a/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls +++ b/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls @@ -198,6 +198,7 @@ type DriverInfo { embedded: Boolean enabled: Boolean! requiresServerName: Boolean + requiresDatabaseName: Boolean licenseRequired: Boolean license: String 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 08010f6d82..8af429a492 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java @@ -169,7 +169,6 @@ public class WebServiceUtils extends WebCommonUtils { if (config.getServerName() != null) { dsConfig.setServerName(config.getServerName()); } - dsConfig.setUrl(driver.getConnectionURL(dsConfig)); } if (config.getProperties() != null) { Map newProps = new LinkedHashMap<>(); @@ -197,6 +196,9 @@ public class WebServiceUtils extends WebCommonUtils { if (config.getConfigurationType() != null) { dsConfig.setConfigurationType(config.getConfigurationType()); } + if (CommonUtils.isEmpty(config.getUrl())) { + dsConfig.setUrl(driver.getConnectionURL(dsConfig)); + } // Save network handlers if (config.getNetworkHandlersConfig() != null) { for (WebNetworkHandlerConfigInput nhc : config.getNetworkHandlersConfig()) { diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDatabaseDriverConfig.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDatabaseDriverConfig.java index fb0f5350ef..bc3795be16 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDatabaseDriverConfig.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDatabaseDriverConfig.java @@ -44,6 +44,7 @@ import java.util.Map; public class WebDatabaseDriverConfig { public static final String URL_SERVER_FIELD = "{server}"; + public static final String URL_DATABASE_FIELD = ".*(?:\\{(?:database|file|folder)}).*"; private final WebSession webSession; private final DBPDriver driver; private String id; @@ -249,4 +250,13 @@ public class WebDatabaseDriverConfig { public DBPDriverConfigurationType[] getConfigurationTypes() { return driver.getSupportedConfigurationTypes().toArray(DBPDriverConfigurationType[]::new); } + + + @Property + public boolean getRequiresDatabaseName() { + if (driver.getSampleURL() == null) { + return false; + } + return driver.getSampleURL().matches(URL_DATABASE_FIELD); + } } From 47bb280cf34fd9a33d7a498666bee10a6fa4a6cd Mon Sep 17 00:00:00 2001 From: Ainur <59531286+yagudin10@users.noreply.github.com> Date: Wed, 31 Aug 2022 11:00:07 +0300 Subject: [PATCH 8/8] CB-2464 de save data sources remotely fix (#1081) * CB-2464 de save data sources remotely fix * CB-2464 add data source persistence registry --- .../io/cloudbeaver/VirtualProjectImpl.java | 5 +- .../WebDataSourceRegistryProxy.java | 259 +++++++++++++++++- .../rm/local/LocalResourceController.java | 13 +- .../cloudbeaver/model/session/WebSession.java | 7 +- .../navigator/WebNavigatorNodeInfo.java | 2 +- 5 files changed, 259 insertions(+), 27 deletions(-) diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/VirtualProjectImpl.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/VirtualProjectImpl.java index 1143f8a800..389d994751 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/VirtualProjectImpl.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/VirtualProjectImpl.java @@ -20,6 +20,7 @@ import io.cloudbeaver.model.rm.RMUtils; import org.eclipse.core.resources.IProject; import org.jkiss.code.NotNull; import org.jkiss.code.Nullable; +import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry; import org.jkiss.dbeaver.model.auth.SMSessionContext; import org.jkiss.dbeaver.model.rm.RMProject; import org.jkiss.dbeaver.registry.BaseProjectImpl; @@ -93,7 +94,7 @@ public class VirtualProjectImpl extends BaseProjectImpl { @NotNull @Override - protected DataSourceRegistry createDataSourceRegistry() { - return new WebDataSourceRegistryProxy(super.createDataSourceRegistry(), dataSourceFilter); + protected DBPDataSourceRegistry createDataSourceRegistry() { + return new WebDataSourceRegistryProxy(new DataSourceRegistry(this), dataSourceFilter); } } diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/WebDataSourceRegistryProxy.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/WebDataSourceRegistryProxy.java index 89d9cc9905..eca241b2b3 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/WebDataSourceRegistryProxy.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/WebDataSourceRegistryProxy.java @@ -7,30 +7,40 @@ import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.model.*; import org.jkiss.dbeaver.model.access.DBAAuthProfile; import org.jkiss.dbeaver.model.access.DBACredentialsProvider; +import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry; import org.jkiss.dbeaver.model.app.DBPProject; import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration; import org.jkiss.dbeaver.model.connection.DBPDriver; import org.jkiss.dbeaver.model.net.DBWNetworkProfile; +import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; import org.jkiss.dbeaver.model.struct.DBSObjectFilter; -import org.jkiss.dbeaver.registry.DataSourceDescriptor; -import org.jkiss.dbeaver.registry.DataSourceFolder; +import org.jkiss.dbeaver.registry.DataSourceConfigurationManager; +import org.jkiss.dbeaver.registry.DataSourcePersistentRegistry; import org.jkiss.dbeaver.registry.DataSourceRegistry; import java.util.List; +import java.util.Set; +import java.util.function.Predicate; import java.util.stream.Collectors; -public class WebDataSourceRegistryProxy extends DataSourceRegistry { +public class WebDataSourceRegistryProxy implements DBPDataSourceRegistry, DataSourcePersistentRegistry { private final DataSourceFilter dataSourceFilter; + private final DataSourceRegistry dataSourceRegistry; public WebDataSourceRegistryProxy(DataSourceRegistry dataSourceRegistry, DataSourceFilter filter) { - super(dataSourceRegistry.getProject()); + this.dataSourceRegistry = dataSourceRegistry; this.dataSourceFilter = filter; } + @Override + public DBPProject getProject() { + return dataSourceRegistry.getProject(); + } + @Nullable @Override - public DataSourceDescriptor getDataSource(String id) { - DataSourceDescriptor dataSource = super.getDataSource(id); + public DBPDataSourceContainer getDataSource(String id) { + DBPDataSourceContainer dataSource = dataSourceRegistry.getDataSource(id); if (dataSourceFilter != null && !dataSourceFilter.filter(dataSource)) { return null; } @@ -39,17 +49,17 @@ public class WebDataSourceRegistryProxy extends DataSourceRegistry { @Nullable @Override - public DataSourceDescriptor getDataSource(DBPDataSource dataSource) { + public DBPDataSourceContainer getDataSource(DBPDataSource dataSource) { if (dataSourceFilter != null && !dataSourceFilter.filter(dataSource.getContainer())) { return null; } - return super.getDataSource(dataSource); + return dataSourceRegistry.getDataSource(dataSource); } @Nullable @Override - public DataSourceDescriptor findDataSourceByName(String name) { - var dataSource = super.findDataSourceByName(name); + public DBPDataSourceContainer findDataSourceByName(String name) { + var dataSource = dataSourceRegistry.findDataSourceByName(name); if (dataSource != null) { if (dataSourceFilter == null || dataSourceFilter.filter(dataSource)) { return dataSource; @@ -61,7 +71,7 @@ public class WebDataSourceRegistryProxy extends DataSourceRegistry { @NotNull @Override public List getDataSourcesByProfile(@NotNull DBWNetworkProfile profile) { - return super.getDataSourcesByProfile(profile) + return dataSourceRegistry.getDataSourcesByProfile(profile) .stream() .filter(dataSourceFilter::filter) .collect(Collectors.toList()); @@ -69,10 +79,233 @@ public class WebDataSourceRegistryProxy extends DataSourceRegistry { @NotNull @Override - public List getDataSources() { - return super.getDataSources() + public List getDataSources() { + return dataSourceRegistry.getDataSources() .stream() .filter(dataSourceFilter::filter) .collect(Collectors.toList()); } + + @NotNull + @Override + public DBPDataSourceContainer createDataSource(DBPDriver driver, DBPConnectionConfiguration connConfig) { + return dataSourceRegistry.createDataSource(driver, connConfig); + } + + @NotNull + @Override + public DBPDataSourceContainer createDataSource(DBPDataSourceContainer source) { + return dataSourceRegistry.createDataSource(source); + } + + @Override + public void addDataSourceListener(@NotNull DBPEventListener listener) { + dataSourceRegistry.addDataSourceListener(listener); + } + + @Override + public boolean removeDataSourceListener(@NotNull DBPEventListener listener) { + return dataSourceRegistry.removeDataSourceListener(listener); + } + + @Override + public void addDataSource(@NotNull DBPDataSourceContainer dataSource) { + dataSourceRegistry.addDataSource(dataSource); + } + + @Override + public void removeDataSource(@NotNull DBPDataSourceContainer dataSource) { + dataSourceRegistry.removeDataSource(dataSource); + } + + @Override + public void updateDataSource(@NotNull DBPDataSourceContainer dataSource) { + dataSourceRegistry.updateDataSource(dataSource); + } + + @NotNull + @Override + public List getAllFolders() { + return dataSourceRegistry.getAllFolders(); + } + + @NotNull + @Override + public List getRootFolders() { + return dataSourceRegistry.getRootFolders(); + } + + @Override + public DBPDataSourceFolder getFolder(String path) { + return dataSourceRegistry.getFolder(path); + } + + @Override + public DBPDataSourceFolder addFolder(DBPDataSourceFolder parent, String name) { + return dataSourceRegistry.addFolder(parent, name); + } + + @Override + public void removeFolder(DBPDataSourceFolder folder, boolean dropContents) { + dataSourceRegistry.removeFolder(folder, dropContents); + } + + @Nullable + @Override + public DBSObjectFilter getSavedFilter(String name) { + return dataSourceRegistry.getSavedFilter(name); + } + + @NotNull + @Override + public List getSavedFilters() { + return dataSourceRegistry.getSavedFilters(); + } + + @Override + public void updateSavedFilter(DBSObjectFilter filter) { + dataSourceRegistry.updateSavedFilter(filter); + } + + @Override + public void removeSavedFilter(String filterName) { + dataSourceRegistry.removeSavedFilter(filterName); + } + + @Nullable + @Override + public DBWNetworkProfile getNetworkProfile(String name) { + return dataSourceRegistry.getNetworkProfile(name); + } + + @NotNull + @Override + public List getNetworkProfiles() { + return dataSourceRegistry.getNetworkProfiles(); + } + + @Override + public void updateNetworkProfile(DBWNetworkProfile profile) { + dataSourceRegistry.updateNetworkProfile(profile); + } + + @Override + public void removeNetworkProfile(DBWNetworkProfile profile) { + dataSourceRegistry.removeNetworkProfile(profile); + } + + @Nullable + @Override + public DBAAuthProfile getAuthProfile(String id) { + return dataSourceRegistry.getAuthProfile(id); + } + + @NotNull + @Override + public List getAllAuthProfiles() { + return dataSourceRegistry.getAllAuthProfiles(); + } + + @NotNull + @Override + public List getApplicableAuthProfiles(@Nullable DBPDriver driver) { + return dataSourceRegistry.getApplicableAuthProfiles(driver); + } + + @Override + public void updateAuthProfile(DBAAuthProfile profile) { + dataSourceRegistry.updateAuthProfile(profile); + } + + @Override + public void removeAuthProfile(DBAAuthProfile profile) { + dataSourceRegistry.removeAuthProfile(profile); + } + + @Override + public void flushConfig() { + dataSourceRegistry.flushConfig(); + } + + @Override + public void refreshConfig() { + dataSourceRegistry.refreshConfig(); + } + + @Override + public Throwable getLastError() { + return dataSourceRegistry.getLastError(); + } + + @Override + public boolean hasError() { + return dataSourceRegistry.hasError(); + } + + @Override + public void checkForErrors() throws DBException { + dataSourceRegistry.checkForErrors(); + } + + @Override + public void notifyDataSourceListeners(DBPEvent event) { + dataSourceRegistry.notifyDataSourceListeners(event); + } + + @NotNull + @Override + public ISecurePreferences getSecurePreferences() { + return dataSourceRegistry.getSecurePreferences(); + } + + @Nullable + @Override + public DBACredentialsProvider getAuthCredentialsProvider() { + return dataSourceRegistry.getAuthCredentialsProvider(); + } + + @Override + public void dispose() { + dataSourceRegistry.dispose(); + } + + @Override + public void setAuthCredentialsProvider(DBACredentialsProvider authCredentialsProvider) { + dataSourceRegistry.setAuthCredentialsProvider(authCredentialsProvider); + } + + @Override + public Set getTemporaryFolders() { + return dataSourceRegistry.getTemporaryFolders(); + } + + @Override + public void loadDataSources( + @NotNull List storages, + @NotNull DataSourceConfigurationManager manager, + boolean refresh, + boolean purgeUntouched + ) { + dataSourceRegistry.loadDataSources(storages, manager, refresh, purgeUntouched); + } + + @Override + public void saveDataSources() { + dataSourceRegistry.saveDataSources(); + } + + @Override + public DataSourceConfigurationManager getConfigurationManager() { + return dataSourceRegistry.getConfigurationManager(); + } + + @Override + public void saveConfigurationToManager( + @NotNull DBRProgressMonitor monitor, + @NotNull DataSourceConfigurationManager configurationManager, + @Nullable Predicate filter + ) { + dataSourceRegistry.saveConfigurationToManager(monitor, configurationManager, filter); + } + } 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 9d45432cac..80d89ceeb2 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 @@ -27,6 +27,7 @@ import org.jkiss.code.Nullable; import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.model.DBPDataSourceConfigurationStorage; +import org.jkiss.dbeaver.model.DBPDataSourceContainer; import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry; import org.jkiss.dbeaver.model.app.DBPProject; import org.jkiss.dbeaver.model.auth.SMCredentials; @@ -259,7 +260,7 @@ public class LocalResourceController implements RMController { DBPDataSourceRegistry registry = projectMetadata.getDataSourceRegistry(); registry.checkForErrors(); DataSourceConfigurationManagerBuffer buffer = new DataSourceConfigurationManagerBuffer(); - ((DataSourceRegistry)registry).saveConfigurationToManager(new VoidProgressMonitor(), buffer, null); + ((DataSourcePersistentRegistry) registry).saveConfigurationToManager(new VoidProgressMonitor(), buffer, null); registry.checkForErrors(); return new String(buffer.getData(), StandardCharsets.UTF_8); } @@ -267,22 +268,22 @@ public class LocalResourceController implements RMController { @Override public void saveProjectDataSources(@NotNull String projectId, @NotNull String configuration) throws DBException { final DBPProject project = getProjectMetadata(projectId); - final DataSourceRegistry registry = (DataSourceRegistry) project.getDataSourceRegistry(); + final DBPDataSourceRegistry registry = project.getDataSourceRegistry(); final DBPDataSourceConfigurationStorage storage = new DataSourceMemoryStorage(configuration.getBytes(StandardCharsets.UTF_8)); final DataSourceConfigurationManager manager = new DataSourceConfigurationManagerBuffer(); - registry.loadDataSources(List.of(storage), manager, true, false); + ((DataSourcePersistentRegistry) registry).loadDataSources(List.of(storage), manager, true, false); registry.checkForErrors(); - registry.saveDataSources(); + ((DataSourcePersistentRegistry) registry).saveDataSources(); registry.checkForErrors(); } @Override public void deleteProjectDataSources(@NotNull String projectId, @NotNull String[] dataSourceIds) throws DBException { final DBPProject project = getProjectMetadata(projectId); - final DataSourceRegistry registry = (DataSourceRegistry) project.getDataSourceRegistry(); + final DBPDataSourceRegistry registry = project.getDataSourceRegistry(); for (String dataSourceId : dataSourceIds) { - final DataSourceDescriptor dataSource = registry.getDataSource(dataSourceId); + final DBPDataSourceContainer dataSource = registry.getDataSource(dataSourceId); if (dataSource != null) { registry.removeDataSource(dataSource); 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 adad2d4f5c..d2ce091a70 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 @@ -16,10 +16,7 @@ */ package io.cloudbeaver.model.session; -import io.cloudbeaver.DBWConstants; -import io.cloudbeaver.DBWebException; -import io.cloudbeaver.DataSourceFilter; -import io.cloudbeaver.VirtualProjectImpl; +import io.cloudbeaver.*; import io.cloudbeaver.model.WebAsyncTaskInfo; import io.cloudbeaver.model.WebConnectionInfo; import io.cloudbeaver.model.WebServerMessage; @@ -366,7 +363,7 @@ public class WebSession extends AbstractSessionPersistent implements SMSession, this, filter); DBPDataSourceRegistry dataSourceRegistry = sessionProject.getDataSourceRegistry(); - ((DataSourceRegistry) dataSourceRegistry).setAuthCredentialsProvider(this); + dataSourceRegistry.setAuthCredentialsProvider(this); addSessionProject(sessionProject); if (!project.isShared() || application.isConfigurationMode()) { this.defaultProject = sessionProject; 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 5afb3bb4ea..bd490aade0 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 @@ -160,7 +160,7 @@ public class WebNavigatorNodeInfo { } else if (node instanceof DBNLocalFolder) { DataSourceFolder folder = (DataSourceFolder) ((DBNLocalFolder) node).getFolder(); String projectName = folder.getDataSourceRegistry().getProject().getName(); - Set tempFolders = ((DataSourceRegistry) folder.getDataSourceRegistry()).getTemporaryFolders(); + Set tempFolders = folder.getDataSourceRegistry().getTemporaryFolders(); isShared = !projectName.equals(session.getUserId()) || tempFolders.contains(folder); } if (isShared) {