From d701cb4fbeaa8e3b565ae22dc99f4a009326f468 Mon Sep 17 00:00:00 2001 From: Evgenia Bezborodova <139753579+EvgeniaBzzz@users.noreply.github.com> Date: Mon, 20 May 2024 12:25:15 +0300 Subject: [PATCH 1/5] Update CB README 24-0-5.md --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 33e30bb77e..edd6fee183 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,16 @@ You can see live demo of CloudBeaver here: https://demo.cloudbeaver.io ## Changelog +### 24.0.5. 2024-05-20 +- The process of application update was improved - you can track the application update process now; +- All popup dialogs became available for screen readers, including JAWS, to improve the experience for users with disabilities; +- Data Editor: + - Large text values (more than 100 Kb) are now automatically opened in the Value panel; +- DuckDB: + - Spatial data visualization support was added; + - The driver has been updated to version 0.10.2; +- Different bug fixes and enhancements have been made. + ### 24.0.4. 2024-05-06 - Added the ability to stop the process of file upload in the table; - Row count calculation in the grid can be cancelled for Data Editor and SQL Editor; From eaf19cf1d2ec13251b2445a8e44576ec7f124986 Mon Sep 17 00:00:00 2001 From: Alexey Date: Mon, 20 May 2024 22:17:55 +0800 Subject: [PATCH 2/5] fix: dev mode hot module replacement (#2643) --- .../core-cli/configs/webpack.config.js | 62 +++++++------------ .../configs/webpack.product.dev.config.js | 10 +-- 2 files changed, 26 insertions(+), 46 deletions(-) diff --git a/webapp/packages/core-cli/configs/webpack.config.js b/webapp/packages/core-cli/configs/webpack.config.js index e1bce14321..c9d0e997bf 100644 --- a/webapp/packages/core-cli/configs/webpack.config.js +++ b/webapp/packages/core-cli/configs/webpack.config.js @@ -128,23 +128,32 @@ module.exports = (env, argv) => { }, }; - return { - context: resolve(__dirname, '../../../../../'), - experiments: { - layers: true, - }, - entry: { + let entry = {}; + + if (devMode) { + entry = { + main: { + import: main, + }, + sso: { + import: sso, + }, + }; + } else { + entry = { main: { import: main, - runtime: 'main-runtime', - layer: 'main', }, sso: { import: sso, runtime: 'sso-runtime', - layer: 'sso', }, - }, + }; + } + + return { + context: resolve(__dirname, '../../../../../'), + entry, output: { filename: 'js/[name]-[contenthash].js', chunkFilename: 'js/[name]-[contenthash].js', @@ -183,7 +192,6 @@ module.exports = (env, argv) => { priority: 20, reuseExistingChunk: true, enforce: true, - layer: 'main', }, packages: { chunks: 'initial', @@ -191,7 +199,6 @@ module.exports = (env, argv) => { name: 'packages', priority: 10, reuseExistingChunk: true, - layer: 'main', }, packagesAsync: { chunks: 'async', @@ -206,7 +213,6 @@ module.exports = (env, argv) => { }, priority: 10, reuseExistingChunk: true, - layer: 'main', }, extendedVendorAsync: { chunks: 'async', @@ -214,7 +220,6 @@ module.exports = (env, argv) => { name: 'extended-vendor-async', priority: -5, reuseExistingChunk: true, - layer: 'main', }, extendedVendor: { chunks: 'initial', @@ -222,7 +227,6 @@ module.exports = (env, argv) => { test: new RegExp(`[\\/]node_modules/(${excludedFromVendor.join('|')}).*?`, ''), priority: -5, reuseExistingChunk: true, - layer: 'main', }, vendorAsync: { chunks: 'async', @@ -230,7 +234,6 @@ module.exports = (env, argv) => { name: 'vendor-async', priority: -10, reuseExistingChunk: true, - layer: 'main', }, vendor: { chunks: 'initial', @@ -238,21 +241,20 @@ module.exports = (env, argv) => { test: new RegExp(`[\\/]node_modules/(?!:${excludedFromVendor.join('|')}).*?`, ''), priority: -10, reuseExistingChunk: true, - layer: 'main', }, asyncCommons: { chunks: 'async', name: 'commons-async', filename: 'js/[name]-[contenthash].js', priority: -15, - layer: 'main', + reuseExistingChunk: true, }, commons: { chunks: 'initial', name: 'commons', filename: 'js/[name]-[contenthash].js', priority: -15, - layer: 'main', + reuseExistingChunk: true, }, defaultAsync: { chunks: 'async', @@ -260,7 +262,6 @@ module.exports = (env, argv) => { filename: '[name]-[contenthash].js', priority: -20, reuseExistingChunk: true, - layer: 'main', }, default: { chunks: 'initial', @@ -268,23 +269,6 @@ module.exports = (env, argv) => { filename: '[name]-[contenthash].js', priority: -20, reuseExistingChunk: true, - layer: 'main', - }, - defaultAsyncSso: { - chunks: 'async', - name: 'bundle-async', - filename: '[name]-[contenthash].js', - priority: -20, - reuseExistingChunk: true, - layer: 'sso', - }, - defaultSso: { - chunks: 'initial', - name: 'bundle', - filename: '[name]-[contenthash].js', - priority: -20, - reuseExistingChunk: true, - layer: 'sso', }, }, }, @@ -342,8 +326,8 @@ module.exports = (env, argv) => { }), new IgnoreNotFoundExportPlugin(), new MiniCssExtractPlugin({ - filename: devMode ? 'styles/[name].css' : 'styles/[name]-[contenthash].css', - chunkFilename: devMode ? 'styles/[name].bundle.css' : 'styles/[name]-[contenthash].css', + filename: 'styles/[name]-[contenthash].css', + chunkFilename: 'styles/[name]-[contenthash].css', ignoreOrder: true, // Enable to remove warnings about conflicting order insert: linkTag => { document.head.appendChild(linkTag); diff --git a/webapp/packages/core-cli/configs/webpack.product.dev.config.js b/webapp/packages/core-cli/configs/webpack.product.dev.config.js index 9002d59605..bc376bde22 100644 --- a/webapp/packages/core-cli/configs/webpack.product.dev.config.js +++ b/webapp/packages/core-cli/configs/webpack.product.dev.config.js @@ -50,17 +50,13 @@ module.exports = (env, argv) => { devtoolModuleFilenameTemplate: 'file:///[absolute-resource-path]', }, watchOptions: { - aggregateTimeout: 3000, + aggregateTimeout: 1000, ignored: ['**/node_modules', '**/packages/*/src/**/*.{ts,tsx}'], }, optimization: { minimize: false, - // moduleIds: 'named', - - // improve performance - removeAvailableModules: false, - removeEmptyChunks: false, - // splitChunks: false, + runtimeChunk: 'single', + moduleIds: 'named', }, infrastructureLogging: { level: 'warn', From 7cd22a84c2f792f22303bf36b6223dd7207b26e5 Mon Sep 17 00:00:00 2001 From: Serge Rider Date: Mon, 20 May 2024 16:44:25 +0200 Subject: [PATCH 3/5] dbeaver/dbeaver devops#1201 base java image (#2642) * dbeaver/dbeaver-devops#1201 Base Java image * dbeaver/dbeaver-devops#1201 Fix scripts * dbeaver/dbeaver-devops#1201 hilevel default env var --------- Co-authored-by: mayerro --- deploy/docker/{ => base-java}/Dockerfile | 11 +++-------- deploy/docker/cloudbeaver-ce/Dockerfile | 10 ++++++++++ deploy/docker/{ => cloudbeaver-ce}/docker-compose.yml | 0 deploy/docker/make-docker-container.sh | 2 +- 4 files changed, 14 insertions(+), 9 deletions(-) rename deploy/docker/{ => base-java}/Dockerfile (88%) create mode 100644 deploy/docker/cloudbeaver-ce/Dockerfile rename deploy/docker/{ => cloudbeaver-ce}/docker-compose.yml (100%) diff --git a/deploy/docker/Dockerfile b/deploy/docker/base-java/Dockerfile similarity index 88% rename from deploy/docker/Dockerfile rename to deploy/docker/base-java/Dockerfile index 0a110689fa..3d6522ffb1 100644 --- a/deploy/docker/Dockerfile +++ b/deploy/docker/base-java/Dockerfile @@ -2,9 +2,11 @@ FROM ubuntu:23.10 MAINTAINER DBeaver Corp, devops@dbeaver.com +ENV DEBIAN_FRONTEND=noninteractive + RUN set -eux; \ apt-get update; \ - DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + apt-get install -y --no-install-recommends \ # curl required for historical reasons, see https://github.com/adoptium/containers/issues/255 curl \ wget \ @@ -43,10 +45,3 @@ RUN set -eux; \ ### Patch java security COPY java.security* ${JAVA_HOME}/conf/security/java.security - -COPY cloudbeaver /opt/cloudbeaver - -EXPOSE 8978 -RUN find /opt/cloudbeaver -type d -exec chmod 775 {} \; -WORKDIR /opt/cloudbeaver/ -ENTRYPOINT ["./run-server.sh"] diff --git a/deploy/docker/cloudbeaver-ce/Dockerfile b/deploy/docker/cloudbeaver-ce/Dockerfile new file mode 100644 index 0000000000..361df92c0a --- /dev/null +++ b/deploy/docker/cloudbeaver-ce/Dockerfile @@ -0,0 +1,10 @@ +FROM dbeaver/base-java + +MAINTAINER DBeaver Corp, devops@dbeaver.com + +COPY cloudbeaver /opt/cloudbeaver + +EXPOSE 8978 +RUN find /opt/cloudbeaver -type d -exec chmod 775 {} \; +WORKDIR /opt/cloudbeaver/ +ENTRYPOINT ["./run-server.sh"] diff --git a/deploy/docker/docker-compose.yml b/deploy/docker/cloudbeaver-ce/docker-compose.yml similarity index 100% rename from deploy/docker/docker-compose.yml rename to deploy/docker/cloudbeaver-ce/docker-compose.yml diff --git a/deploy/docker/make-docker-container.sh b/deploy/docker/make-docker-container.sh index 17f869b3e4..f38c98d2a1 100755 --- a/deploy/docker/make-docker-container.sh +++ b/deploy/docker/make-docker-container.sh @@ -1,3 +1,3 @@ cd .. -docker build -t dbeaver/cloudbeaver:dev . --file ./docker/Dockerfile +docker build -t dbeaver/cloudbeaver:dev . --file ./docker/cloudbeaver-ce/Dockerfile From 72ce16b2e8d37d5d1b0de9ea2141a281a906f716 Mon Sep 17 00:00:00 2001 From: Alexander Skoblikov Date: Mon, 20 May 2024 18:05:09 +0300 Subject: [PATCH 4/5] CB-931 ldap identity provider (#2609) * CB-931 ldap identity provider * CB-931 add bruteforce protection to ldap --------- Co-authored-by: Evgenia Bezborodova <139753579+EvgeniaBzzz@users.noreply.github.com> --- .../io.cloudbeaver.model/META-INF/MANIFEST.MF | 1 + .../provider/fa/AbstractSessionExternal.java | 79 +++++++++ .../META-INF/MANIFEST.MF | 14 ++ .../build.properties | 5 + .../plugin.xml | 31 ++++ .../io.cloudbeaver.service.ldap.auth/pom.xml | 16 ++ .../service/ldap/auth/LdapAuthProvider.java | 166 ++++++++++++++++++ .../service/ldap/auth/LdapConstants.java | 29 +++ .../service/ldap/auth/LdapSession.java | 41 +++++ .../service/ldap/auth/LdapSettings.java | 54 ++++++ server/bundles/pom.xml | 2 + .../io.cloudbeaver.server.feature/feature.xml | 2 + 12 files changed, 440 insertions(+) create mode 100644 server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/auth/provider/fa/AbstractSessionExternal.java create mode 100644 server/bundles/io.cloudbeaver.service.ldap.auth/META-INF/MANIFEST.MF create mode 100644 server/bundles/io.cloudbeaver.service.ldap.auth/build.properties create mode 100644 server/bundles/io.cloudbeaver.service.ldap.auth/plugin.xml create mode 100644 server/bundles/io.cloudbeaver.service.ldap.auth/pom.xml create mode 100644 server/bundles/io.cloudbeaver.service.ldap.auth/src/io/cloudbeaver/service/ldap/auth/LdapAuthProvider.java create mode 100644 server/bundles/io.cloudbeaver.service.ldap.auth/src/io/cloudbeaver/service/ldap/auth/LdapConstants.java create mode 100644 server/bundles/io.cloudbeaver.service.ldap.auth/src/io/cloudbeaver/service/ldap/auth/LdapSession.java create mode 100644 server/bundles/io.cloudbeaver.service.ldap.auth/src/io/cloudbeaver/service/ldap/auth/LdapSettings.java diff --git a/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF index fa743ca1e8..b1ef7fd2b3 100644 --- a/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF +++ b/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF @@ -22,6 +22,7 @@ Require-Bundle: org.jkiss.dbeaver.data.gis;visibility:=reexport, Export-Package: io.cloudbeaver, io.cloudbeaver.auth, io.cloudbeaver.auth.provider, + io.cloudbeaver.auth.provider.fa, io.cloudbeaver.auth.provider.local, io.cloudbeaver.auth.provisioning, io.cloudbeaver.websocket, diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/auth/provider/fa/AbstractSessionExternal.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/auth/provider/fa/AbstractSessionExternal.java new file mode 100644 index 0000000000..f0ac26016a --- /dev/null +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/auth/provider/fa/AbstractSessionExternal.java @@ -0,0 +1,79 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2024 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.cloudbeaver.auth.provider.fa; + +import org.jkiss.code.NotNull; +import org.jkiss.code.Nullable; +import org.jkiss.dbeaver.model.auth.*; + +import java.time.LocalDateTime; +import java.util.Map; + +public abstract class AbstractSessionExternal implements SMSessionExternal { + + @NotNull + protected final Map authParameters; + @NotNull + protected final SMSession parentSession; + @NotNull + protected final SMAuthSpace space; + + protected AbstractSessionExternal( + @NotNull SMSession parentSession, + @NotNull SMAuthSpace space, + @NotNull Map authParameters + ) { + this.parentSession = parentSession; + this.space = space; + this.authParameters = authParameters; + } + + @NotNull + @Override + public SMAuthSpace getSessionSpace() { + return space; + } + + @NotNull + @Override + public SMSessionContext getSessionContext() { + return this.parentSession.getSessionContext(); + } + + @Nullable + @Override + public SMSessionPrincipal getSessionPrincipal() { + return parentSession.getSessionPrincipal(); + } + + @NotNull + @Override + public LocalDateTime getSessionStart() { + return parentSession.getSessionStart(); + } + + @Override + public void close() { + // do nothing + } + + @Override + public Map getAuthParameters() { + return authParameters; + } +} diff --git a/server/bundles/io.cloudbeaver.service.ldap.auth/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.service.ldap.auth/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..983d13ae7d --- /dev/null +++ b/server/bundles/io.cloudbeaver.service.ldap.auth/META-INF/MANIFEST.MF @@ -0,0 +1,14 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Vendor: Cloudbeaver LDAP +Bundle-Vendor: DBeaver Corp +Bundle-SymbolicName: io.cloudbeaver.service.ldap.auth;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Release-Date: 20240506 +Bundle-RequiredExecutionEnvironment: JavaSE-17 +Bundle-ActivationPolicy: lazy +Bundle-ClassPath: . +Require-Bundle: org.jkiss.dbeaver.model;visibility:=reexport, + org.jkiss.dbeaver.registry;visibility:=reexport, + io.cloudbeaver.model +Automatic-Module-Name: io.cloudbeaver.service.ldap.auth diff --git a/server/bundles/io.cloudbeaver.service.ldap.auth/build.properties b/server/bundles/io.cloudbeaver.service.ldap.auth/build.properties new file mode 100644 index 0000000000..95692a59c9 --- /dev/null +++ b/server/bundles/io.cloudbeaver.service.ldap.auth/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = target/classes/ +bin.includes = .,\ + META-INF/,\ + plugin.xml diff --git a/server/bundles/io.cloudbeaver.service.ldap.auth/plugin.xml b/server/bundles/io.cloudbeaver.service.ldap.auth/plugin.xml new file mode 100644 index 0000000000..4abd568426 --- /dev/null +++ b/server/bundles/io.cloudbeaver.service.ldap.auth/plugin.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/server/bundles/io.cloudbeaver.service.ldap.auth/pom.xml b/server/bundles/io.cloudbeaver.service.ldap.auth/pom.xml new file mode 100644 index 0000000000..09ebea89c1 --- /dev/null +++ b/server/bundles/io.cloudbeaver.service.ldap.auth/pom.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + + io.cloudbeaver + bundles + 1.0.0-SNAPSHOT + ../ + + io.cloudbeaver.service.ldap.auth + 1.0.0-SNAPSHOT + eclipse-plugin + + diff --git a/server/bundles/io.cloudbeaver.service.ldap.auth/src/io/cloudbeaver/service/ldap/auth/LdapAuthProvider.java b/server/bundles/io.cloudbeaver.service.ldap.auth/src/io/cloudbeaver/service/ldap/auth/LdapAuthProvider.java new file mode 100644 index 0000000000..4a86e2fb4e --- /dev/null +++ b/server/bundles/io.cloudbeaver.service.ldap.auth/src/io/cloudbeaver/service/ldap/auth/LdapAuthProvider.java @@ -0,0 +1,166 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2024 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.cloudbeaver.service.ldap.auth; + +import io.cloudbeaver.DBWUserIdentity; +import io.cloudbeaver.auth.SMAuthProviderExternal; +import io.cloudbeaver.auth.SMBruteForceProtected; +import io.cloudbeaver.auth.provider.local.LocalAuthProviderConstants; +import io.cloudbeaver.model.session.WebSession; +import io.cloudbeaver.model.user.WebUser; +import org.jkiss.code.NotNull; +import org.jkiss.code.Nullable; +import org.jkiss.dbeaver.DBException; +import org.jkiss.dbeaver.model.DBPObject; +import org.jkiss.dbeaver.model.auth.SMSession; +import org.jkiss.dbeaver.model.data.json.JSONUtils; +import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; +import org.jkiss.dbeaver.model.security.SMAuthProviderCustomConfiguration; +import org.jkiss.dbeaver.model.security.SMController; +import org.jkiss.utils.CommonUtils; + +import javax.naming.Context; +import javax.naming.directory.DirContext; +import javax.naming.directory.InitialDirContext; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; +import java.util.UUID; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class LdapAuthProvider implements SMAuthProviderExternal, SMBruteForceProtected { + public LdapAuthProvider() { + } + + @Override + public Map authExternalUser( + @NotNull DBRProgressMonitor monitor, + @Nullable SMAuthProviderCustomConfiguration providerConfig, + @NotNull Map authParameters + ) throws DBException { + if (providerConfig == null) { + throw new DBException("LDAP provider config is null"); + } + String userName = JSONUtils.getString(authParameters, LdapConstants.CRED_USERNAME); + if (CommonUtils.isEmpty(userName)) { + throw new DBException("LDAP user name is empty"); + } + String password = JSONUtils.getString(authParameters, LdapConstants.CRED_PASSWORD); + if (CommonUtils.isEmpty(password)) { + throw new DBException("LDAP password is empty"); + } + String unit = CommonUtils.nullIfEmpty(JSONUtils.getString(authParameters, LdapConstants.CRED_UNITS)); + + LdapSettings ldapSettings = new LdapSettings(providerConfig); + Hashtable environment = new Hashtable<>(); + environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); + + var ldapProviderUrl = "ldap://" + ldapSettings.getHost() + ":" + ldapSettings.getPort(); + environment.put(Context.PROVIDER_URL, ldapProviderUrl); + environment.put(Context.SECURITY_AUTHENTICATION, "simple"); + + String cn = "cn=" + userName; + var principal = Stream.of(cn, unit, ldapSettings.getBaseDN()) + .filter(CommonUtils::isNotEmpty) + .collect(Collectors.joining(",")); + + environment.put(Context.SECURITY_PRINCIPAL, principal); + environment.put(Context.SECURITY_CREDENTIALS, password); + try { + DirContext context = new InitialDirContext(environment); + context.close(); + Map userData = new HashMap<>(); + userData.put(LdapConstants.CRED_USERNAME, userName); + userData.put(LdapConstants.CRED_SESSION_ID, UUID.randomUUID()); + return userData; + } catch (Exception e) { + throw new DBException("LDAP authentication failed: " + e.getMessage(), e); + } + } + + @NotNull + @Override + public DBWUserIdentity getUserIdentity( + @NotNull DBRProgressMonitor monitor, + @Nullable SMAuthProviderCustomConfiguration customConfiguration, + @NotNull Map authParameters + ) throws DBException { + String userName = JSONUtils.getString(authParameters, LocalAuthProviderConstants.CRED_USER); + if (CommonUtils.isEmpty(userName)) { + throw new DBException("LDAP user name is empty"); + } + return new DBWUserIdentity(userName, userName); + } + + @Nullable + @Override + public DBPObject getUserDetails( + @NotNull DBRProgressMonitor monitor, + @NotNull WebSession webSession, + @NotNull SMSession session, + @NotNull WebUser user, + boolean selfIdentity + ) throws DBException { + return null; + } + + @NotNull + @Override + public String validateLocalAuth( + @NotNull DBRProgressMonitor monitor, + @NotNull SMController securityController, + @NotNull SMAuthProviderCustomConfiguration providerConfig, + @NotNull Map userCredentials, + @Nullable String activeUserId + ) throws DBException { + String userId = JSONUtils.getString(userCredentials, LdapConstants.CRED_USERNAME); + if (CommonUtils.isEmpty(userId)) { + throw new DBException("LDAP user id not found"); + } + return activeUserId == null ? userId : activeUserId; + } + + @Override + public SMSession openSession( + @NotNull DBRProgressMonitor monitor, + @NotNull SMSession mainSession, + @Nullable SMAuthProviderCustomConfiguration customConfiguration, + @NotNull Map userCredentials + ) throws DBException { + return new LdapSession(mainSession, mainSession.getSessionSpace(), userCredentials); + } + + @Override + public void closeSession(@NotNull SMSession mainSession, SMSession session) throws DBException { + + } + + @Override + public void refreshSession( + @NotNull DBRProgressMonitor monitor, + @NotNull SMSession mainSession, + SMSession session + ) throws DBException { + + } + + @Override + public Object getInputUsername(@NotNull Map cred) { + return cred.get(LdapConstants.CRED_USERNAME); + } +} diff --git a/server/bundles/io.cloudbeaver.service.ldap.auth/src/io/cloudbeaver/service/ldap/auth/LdapConstants.java b/server/bundles/io.cloudbeaver.service.ldap.auth/src/io/cloudbeaver/service/ldap/auth/LdapConstants.java new file mode 100644 index 0000000000..02fcfbea6d --- /dev/null +++ b/server/bundles/io.cloudbeaver.service.ldap.auth/src/io/cloudbeaver/service/ldap/auth/LdapConstants.java @@ -0,0 +1,29 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2024 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.cloudbeaver.service.ldap.auth; + +public interface LdapConstants { + String PARAM_HOST = "ldap-host"; + String PARAM_PORT = "ldap-port"; + String PARAM_DN = "ldap-dn"; + + + String CRED_USERNAME = "user"; + String CRED_PASSWORD = "password"; + String CRED_UNITS = "units"; + String CRED_SESSION_ID = "session-id"; +} diff --git a/server/bundles/io.cloudbeaver.service.ldap.auth/src/io/cloudbeaver/service/ldap/auth/LdapSession.java b/server/bundles/io.cloudbeaver.service.ldap.auth/src/io/cloudbeaver/service/ldap/auth/LdapSession.java new file mode 100644 index 0000000000..c4326af395 --- /dev/null +++ b/server/bundles/io.cloudbeaver.service.ldap.auth/src/io/cloudbeaver/service/ldap/auth/LdapSession.java @@ -0,0 +1,41 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2024 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.cloudbeaver.service.ldap.auth; + +import io.cloudbeaver.auth.provider.fa.AbstractSessionExternal; +import org.jkiss.code.NotNull; +import org.jkiss.dbeaver.model.auth.SMAuthSpace; +import org.jkiss.dbeaver.model.auth.SMSession; +import org.jkiss.dbeaver.model.data.json.JSONUtils; + +import java.util.Map; + +public class LdapSession extends AbstractSessionExternal { + protected LdapSession( + @NotNull SMSession parentSession, + @NotNull SMAuthSpace space, + @NotNull Map authParameters + ) { + super(parentSession, space, authParameters); + } + + @NotNull + @Override + public String getSessionId() { + return JSONUtils.getString(authParameters, LdapConstants.CRED_SESSION_ID, "sessionNotFound"); + } +} diff --git a/server/bundles/io.cloudbeaver.service.ldap.auth/src/io/cloudbeaver/service/ldap/auth/LdapSettings.java b/server/bundles/io.cloudbeaver.service.ldap.auth/src/io/cloudbeaver/service/ldap/auth/LdapSettings.java new file mode 100644 index 0000000000..9bce30ee14 --- /dev/null +++ b/server/bundles/io.cloudbeaver.service.ldap.auth/src/io/cloudbeaver/service/ldap/auth/LdapSettings.java @@ -0,0 +1,54 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2024 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.cloudbeaver.service.ldap.auth; + +import org.jkiss.code.NotNull; +import org.jkiss.dbeaver.model.security.SMAuthProviderCustomConfiguration; +import org.jkiss.utils.CommonUtils; + +public class LdapSettings { + @NotNull + private final SMAuthProviderCustomConfiguration providerConfiguration; + @NotNull + private final String host; + @NotNull + private final String baseDN; + private final int port; + + protected LdapSettings(SMAuthProviderCustomConfiguration providerConfiguration) { + this.providerConfiguration = providerConfiguration; + this.host = providerConfiguration.getParameter(LdapConstants.PARAM_HOST); + this.port = CommonUtils.isNotEmpty(providerConfiguration.getParameter(LdapConstants.PARAM_PORT)) ? Integer.parseInt( + providerConfiguration.getParameter(LdapConstants.PARAM_PORT)) : 389; + this.baseDN = providerConfiguration.getParameterOrDefault(LdapConstants.PARAM_DN, ""); + } + + + @NotNull + public String getBaseDN() { + return baseDN; + } + + @NotNull + public String getHost() { + return host; + } + + public int getPort() { + return port; + } +} diff --git a/server/bundles/pom.xml b/server/bundles/pom.xml index 5ce7dcb36f..4cd1b54263 100644 --- a/server/bundles/pom.xml +++ b/server/bundles/pom.xml @@ -24,7 +24,9 @@ io.cloudbeaver.service.rm io.cloudbeaver.service.rm.nio io.cloudbeaver.service.data.transfer + io.cloudbeaver.service.security + io.cloudbeaver.service.ldap.auth io.cloudbeaver.resources.drivers.base diff --git a/server/features/io.cloudbeaver.server.feature/feature.xml b/server/features/io.cloudbeaver.server.feature/feature.xml index 887f69b061..3b96765cfa 100644 --- a/server/features/io.cloudbeaver.server.feature/feature.xml +++ b/server/features/io.cloudbeaver.server.feature/feature.xml @@ -39,7 +39,9 @@ + + From e3a859fee7679ee150ef4d8ac50589eb587b8d29 Mon Sep 17 00:00:00 2001 From: alex <48489896+devnaumov@users.noreply.github.com> Date: Tue, 21 May 2024 10:10:47 +0200 Subject: [PATCH 5/5] Cb 5133 tree expand focus (#2605) * CB-5133 make tree expand focusable * CB-5133 make tree expand clickable * CB-5133 add label for the expand button --------- Co-authored-by: Daria Marutkina <125263541+dariamarutkina@users.noreply.github.com> --- webapp/packages/core-blocks/src/Menu/Menu.m.css | 8 +++++++- .../src/Tree/TreeNode/TreeNodeExpand.tsx | 15 +++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/webapp/packages/core-blocks/src/Menu/Menu.m.css b/webapp/packages/core-blocks/src/Menu/Menu.m.css index 851b929b69..63a2520c16 100644 --- a/webapp/packages/core-blocks/src/Menu/Menu.m.css +++ b/webapp/packages/core-blocks/src/Menu/Menu.m.css @@ -1,10 +1,16 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2024 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ .menuButton { composes: theme-ripple from global; } .menuButton { background: none; border: none; - outline: none !important; color: inherit; cursor: pointer; diff --git a/webapp/packages/core-blocks/src/Tree/TreeNode/TreeNodeExpand.tsx b/webapp/packages/core-blocks/src/Tree/TreeNode/TreeNodeExpand.tsx index 6ca250ae7a..49b8c15252 100644 --- a/webapp/packages/core-blocks/src/Tree/TreeNode/TreeNodeExpand.tsx +++ b/webapp/packages/core-blocks/src/Tree/TreeNode/TreeNodeExpand.tsx @@ -10,9 +10,11 @@ import { useContext } from 'react'; import { EventContext } from '@cloudbeaver/core-events'; +import { Clickable } from '../../Clickable'; import { getComputed } from '../../getComputed'; import { Icon } from '../../Icon'; import { Loader } from '../../Loader/Loader'; +import { useTranslate } from '../../localization/useTranslate'; import { s } from '../../s'; import { useS } from '../../useS'; import { useStateDelay } from '../../useStateDelay'; @@ -29,6 +31,7 @@ interface Props { } export const TreeNodeExpand = observer(function TreeNodeExpand({ leaf, big, filterActive, disabled, className }) { + const translate = useTranslate(); const styles = useS(style); const context = useContext(TreeNodeContext); @@ -85,14 +88,22 @@ export const TreeNodeExpand = observer(function TreeNodeExpand({ leaf, bi } } + const title = translate('ui_expand'); + return ( -
{loading && } {expandable && } -
+ ); });