diff --git a/README.md b/README.md
index a656ab0327..be604f1cdb 100644
--- a/README.md
+++ b/README.md
@@ -25,6 +25,10 @@ You can see a live demo of CloudBeaver here: https://demo.cloudbeaver.io
## Changelog
+### 24.2.5. 2024-11-18
+- Updated user storage mechanism: New user logins are now stored in lowercase to prevent duplicate entries (e.g., "ADMIN" and "admin"). Note: This update does not affect previously created user logins;
+- A new setting in Global Preferences was added to restrict data import for non-admin users.
+
### 24.2.4. 2024-11-04
- General:
- Data export: Added the ability to export JSON values as embedded JSON;
diff --git a/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF
index 66edf9bbb2..5f998bc37e 100644
--- a/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF
+++ b/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF
@@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2
Bundle-Vendor: DBeaver Corp
Bundle-Name: Cloudbeaver Web Model
Bundle-SymbolicName: io.cloudbeaver.model;singleton:=true
-Bundle-Version: 1.0.65.qualifier
-Bundle-Release-Date: 20241118
+Bundle-Version: 1.0.66.qualifier
+Bundle-Release-Date: 20241202
Bundle-RequiredExecutionEnvironment: JavaSE-17
Bundle-ActivationPolicy: lazy
Bundle-ClassPath: .
diff --git a/server/bundles/io.cloudbeaver.model/pom.xml b/server/bundles/io.cloudbeaver.model/pom.xml
index 0832142631..cd0f7854f8 100644
--- a/server/bundles/io.cloudbeaver.model/pom.xml
+++ b/server/bundles/io.cloudbeaver.model/pom.xml
@@ -10,7 +10,7 @@
../
io.cloudbeaver.model
- 1.0.65-SNAPSHOT
+ 1.0.66-SNAPSHOT
eclipse-plugin
diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/DBWebException.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/DBWebException.java
index f4cc8e50ea..a06626ed51 100644
--- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/DBWebException.java
+++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/DBWebException.java
@@ -22,7 +22,6 @@
import graphql.language.SourceLocation;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.sql.SQLState;
-import org.jkiss.dbeaver.utils.GeneralUtils;
import org.jkiss.utils.CommonUtils;
import java.io.PrintWriter;
@@ -100,7 +99,7 @@ public ErrorClassification getErrorType() {
@Override
public Map getExtensions() {
StringWriter buf = new StringWriter();
- GeneralUtils.getRootCause(this).printStackTrace(new PrintWriter(buf, true));
+ CommonUtils.getRootCause(this).printStackTrace(new PrintWriter(buf, true));
Map extensions = new LinkedHashMap<>();
String stString = buf.toString();
diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebAuthProviderDescriptor.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebAuthProviderDescriptor.java
index 16822ec600..78a87c8fcb 100644
--- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebAuthProviderDescriptor.java
+++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebAuthProviderDescriptor.java
@@ -55,6 +55,7 @@ public class WebAuthProviderDescriptor extends AbstractDescriptor {
private final boolean trusted;
private final boolean isPrivate;
private final boolean isAuthHidden;
+ private final boolean isCaseInsensitive;
private final String[] requiredFeatures;
private final boolean isRequired;
private final String[] types;
@@ -69,6 +70,7 @@ public WebAuthProviderDescriptor(IConfigurationElement cfg) {
this.isPrivate = CommonUtils.toBoolean(cfg.getAttribute("private"));
this.isRequired = CommonUtils.toBoolean(cfg.getAttribute("required"));
this.isAuthHidden = CommonUtils.toBoolean(cfg.getAttribute("authHidden"));
+ this.isCaseInsensitive = CommonUtils.toBoolean(cfg.getAttribute("caseInsensitive"));
for (IConfigurationElement cfgElement : cfg.getChildren("configuration")) {
List properties = WebAuthProviderRegistry.readProperties(cfgElement);
@@ -132,6 +134,10 @@ public boolean isAuthHidden() {
return isAuthHidden;
}
+ public boolean isCaseInsensitive() {
+ return isCaseInsensitive;
+ }
+
public List getConfigurationParameters() {
return new ArrayList<>(configurationParameters.values());
}
diff --git a/server/bundles/io.cloudbeaver.product.ce/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.product.ce/META-INF/MANIFEST.MF
index eab0fb4e5a..3cc02705d6 100644
--- a/server/bundles/io.cloudbeaver.product.ce/META-INF/MANIFEST.MF
+++ b/server/bundles/io.cloudbeaver.product.ce/META-INF/MANIFEST.MF
@@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2
Bundle-Vendor: DBeaver Corp
Bundle-Name: Cloudbeaver Community Product
Bundle-SymbolicName: io.cloudbeaver.product.ce;singleton:=true
-Bundle-Version: 24.2.5.qualifier
-Bundle-Release-Date: 20241118
+Bundle-Version: 24.3.0.qualifier
+Bundle-Release-Date: 20241202
Bundle-RequiredExecutionEnvironment: JavaSE-17
Bundle-ActivationPolicy: lazy
Bundle-ClassPath: .
diff --git a/server/bundles/io.cloudbeaver.product.ce/pom.xml b/server/bundles/io.cloudbeaver.product.ce/pom.xml
index 2f72ef816c..19029a80e4 100644
--- a/server/bundles/io.cloudbeaver.product.ce/pom.xml
+++ b/server/bundles/io.cloudbeaver.product.ce/pom.xml
@@ -10,7 +10,7 @@
../
io.cloudbeaver.product.ce
- 24.2.5-SNAPSHOT
+ 24.3.0-SNAPSHOT
eclipse-plugin
diff --git a/server/bundles/io.cloudbeaver.resources.drivers.base/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.resources.drivers.base/META-INF/MANIFEST.MF
index d543d9254a..31f399616b 100644
--- a/server/bundles/io.cloudbeaver.resources.drivers.base/META-INF/MANIFEST.MF
+++ b/server/bundles/io.cloudbeaver.resources.drivers.base/META-INF/MANIFEST.MF
@@ -2,8 +2,8 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Base JDBC drivers
Bundle-SymbolicName: io.cloudbeaver.resources.drivers.base;singleton:=true
-Bundle-Version: 1.0.110.qualifier
-Bundle-Release-Date: 20241118
+Bundle-Version: 1.0.111.qualifier
+Bundle-Release-Date: 20241202
Bundle-Vendor: DBeaver Corp
Bundle-ActivationPolicy: lazy
Automatic-Module-Name: io.cloudbeaver.resources.drivers.base
diff --git a/server/bundles/io.cloudbeaver.resources.drivers.base/pom.xml b/server/bundles/io.cloudbeaver.resources.drivers.base/pom.xml
index da070a045f..d327cd569d 100644
--- a/server/bundles/io.cloudbeaver.resources.drivers.base/pom.xml
+++ b/server/bundles/io.cloudbeaver.resources.drivers.base/pom.xml
@@ -9,6 +9,6 @@
../
io.cloudbeaver.resources.drivers.base
- 1.0.110-SNAPSHOT
+ 1.0.111-SNAPSHOT
eclipse-plugin
diff --git a/server/bundles/io.cloudbeaver.server/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.server/META-INF/MANIFEST.MF
index 609e4ccc38..76578bc27f 100644
--- a/server/bundles/io.cloudbeaver.server/META-INF/MANIFEST.MF
+++ b/server/bundles/io.cloudbeaver.server/META-INF/MANIFEST.MF
@@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2
Bundle-Vendor: DBeaver Corp
Bundle-Name: Cloudbeaver Web Server
Bundle-SymbolicName: io.cloudbeaver.server;singleton:=true
-Bundle-Version: 24.2.5.qualifier
-Bundle-Release-Date: 20241118
+Bundle-Version: 24.3.0.qualifier
+Bundle-Release-Date: 20241202
Bundle-RequiredExecutionEnvironment: JavaSE-17
Bundle-ActivationPolicy: lazy
Bundle-Activator: io.cloudbeaver.server.CBPlatformActivator
diff --git a/server/bundles/io.cloudbeaver.server/pom.xml b/server/bundles/io.cloudbeaver.server/pom.xml
index c1df15d32f..e674aef409 100644
--- a/server/bundles/io.cloudbeaver.server/pom.xml
+++ b/server/bundles/io.cloudbeaver.server/pom.xml
@@ -10,7 +10,7 @@
../
io.cloudbeaver.server
- 24.2.5-SNAPSHOT
+ 24.3.0-SNAPSHOT
eclipse-plugin
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 18fde20361..de0f13c5cc 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
@@ -529,7 +529,7 @@ public synchronized void finishConfiguration(
}
if (isConfigurationMode()) {
- finishSecurityServiceConfiguration(adminName, adminPassword, authInfoList);
+ finishSecurityServiceConfiguration(adminName.toLowerCase(), adminPassword, authInfoList);
}
// Save runtime configuration
diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/websockets/CBAbstractWebSocket.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/websockets/CBAbstractWebSocket.java
index 2dac868a86..7af0f380c4 100644
--- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/websockets/CBAbstractWebSocket.java
+++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/websockets/CBAbstractWebSocket.java
@@ -25,7 +25,7 @@
public class CBAbstractWebSocket extends Session.Listener.AbstractAutoDemanding {
private static final Log log = Log.getLog(CBAbstractWebSocket.class);
- protected static final Gson gson = WSUtils.gson;
+ protected static final Gson gson = WSUtils.clientGson;
public void handleEvent(WSEvent event) {
if (!isOpen()) {
diff --git a/server/bundles/io.cloudbeaver.service.admin/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.service.admin/META-INF/MANIFEST.MF
index e1bf687cda..f753b33cdc 100644
--- a/server/bundles/io.cloudbeaver.service.admin/META-INF/MANIFEST.MF
+++ b/server/bundles/io.cloudbeaver.service.admin/META-INF/MANIFEST.MF
@@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2
Bundle-Vendor: DBeaver Corp
Bundle-Name: Cloudbeaver Web Service - Administration
Bundle-SymbolicName: io.cloudbeaver.service.admin;singleton:=true
-Bundle-Version: 1.0.109.qualifier
-Bundle-Release-Date: 20241118
+Bundle-Version: 1.0.110.qualifier
+Bundle-Release-Date: 20241202
Bundle-RequiredExecutionEnvironment: JavaSE-17
Bundle-ActivationPolicy: lazy
Bundle-ClassPath: .
diff --git a/server/bundles/io.cloudbeaver.service.admin/pom.xml b/server/bundles/io.cloudbeaver.service.admin/pom.xml
index 7b69a7997d..71acee8ddf 100644
--- a/server/bundles/io.cloudbeaver.service.admin/pom.xml
+++ b/server/bundles/io.cloudbeaver.service.admin/pom.xml
@@ -10,7 +10,7 @@
../
io.cloudbeaver.service.admin
- 1.0.109-SNAPSHOT
+ 1.0.110-SNAPSHOT
eclipse-plugin
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 48e78992a3..51c959e209 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
@@ -161,12 +161,13 @@ public AdminUserInfo createUser(
if (userName.isEmpty()) {
throw new DBWebException("Empty user name");
}
- webSession.addInfoMessage("Create new user - " + userName);
+ String userId = userName.toLowerCase();
+ webSession.addInfoMessage("Create new user - " + userId);
try {
var securityController = webSession.getAdminSecurityController();
- securityController.createUser(userName, Map.of(), enabled, authRole);
- var smUser = securityController.getUserById(userName);
+ securityController.createUser(userId, Map.of(), enabled, authRole);
+ var smUser = securityController.getUserById(userId);
return new AdminUserInfo(webSession, new WebUser(smUser));
} catch (Exception e) {
throw new DBWebException("Error creating new user", e);
diff --git a/server/bundles/io.cloudbeaver.service.auth/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.service.auth/META-INF/MANIFEST.MF
index 62fff52e87..f54eb321f8 100644
--- a/server/bundles/io.cloudbeaver.service.auth/META-INF/MANIFEST.MF
+++ b/server/bundles/io.cloudbeaver.service.auth/META-INF/MANIFEST.MF
@@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2
Bundle-Vendor: DBeaver Corp
Bundle-Name: Cloudbeaver Web Service - Authentication
Bundle-SymbolicName: io.cloudbeaver.service.auth;singleton:=true
-Bundle-Version: 1.0.109.qualifier
-Bundle-Release-Date: 20241118
+Bundle-Version: 1.0.110.qualifier
+Bundle-Release-Date: 20241202
Bundle-RequiredExecutionEnvironment: JavaSE-17
Bundle-ActivationPolicy: lazy
Bundle-ClassPath: .
diff --git a/server/bundles/io.cloudbeaver.service.auth/pom.xml b/server/bundles/io.cloudbeaver.service.auth/pom.xml
index 943eb24778..972be7be9e 100644
--- a/server/bundles/io.cloudbeaver.service.auth/pom.xml
+++ b/server/bundles/io.cloudbeaver.service.auth/pom.xml
@@ -10,7 +10,7 @@
../
io.cloudbeaver.service.auth
- 1.0.109-SNAPSHOT
+ 1.0.110-SNAPSHOT
eclipse-plugin
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 64040e3a6f..767823b4c3 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
@@ -98,9 +98,13 @@ public void reverseProxyAuthentication(@NotNull HttpServletRequest request, @Not
String firstName = request.getHeader(resolveParam(paramConfigMap.get(RPConstants.PARAM_FIRST_NAME), RPAuthProvider.X_FIRST_NAME));
String lastName = request.getHeader(resolveParam(paramConfigMap.get(RPConstants.PARAM_LAST_NAME), RPAuthProvider.X_LAST_NAME));
String fullName = request.getHeader(resolveParam(paramConfigMap.get(RPConstants.PARAM_FULL_NAME), RPAuthProvider.X_FULL_NAME));
- String logoutUrl = Objects.requireNonNull(configuration).getParameter(RPConstants.PARAM_LOGOUT_URL);
- String teamDelimiter = resolveParam(JSONUtils.getString(configuration.getParameters(),
- RPConstants.PARAM_TEAM_DELIMITER), "\\|");
+ String logoutUrl = null;
+ String teamDelimiter = DEFAULT_TEAM_DELIMITER;
+ if (configuration != null) {
+ logoutUrl = configuration.getParameter(RPConstants.PARAM_LOGOUT_URL);
+ teamDelimiter = resolveParam(JSONUtils.getString(configuration.getParameters(),
+ RPConstants.PARAM_TEAM_DELIMITER), DEFAULT_TEAM_DELIMITER);
+ }
List userTeams = teams == null ? null : (teams.isEmpty() ? List.of() : List.of(teams.split(teamDelimiter)));
if (userName != null) {
try {
diff --git a/server/bundles/io.cloudbeaver.service.data.transfer/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.service.data.transfer/META-INF/MANIFEST.MF
index 4a317c4f3f..7c899f7153 100644
--- a/server/bundles/io.cloudbeaver.service.data.transfer/META-INF/MANIFEST.MF
+++ b/server/bundles/io.cloudbeaver.service.data.transfer/META-INF/MANIFEST.MF
@@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2
Bundle-Vendor: DBeaver Corp
Bundle-Name: Cloudbeaver Web Service - Data Transfer
Bundle-SymbolicName: io.cloudbeaver.service.data.transfer;singleton:=true
-Bundle-Version: 1.0.110.qualifier
-Bundle-Release-Date: 20241118
+Bundle-Version: 1.0.111.qualifier
+Bundle-Release-Date: 20241202
Bundle-RequiredExecutionEnvironment: JavaSE-17
Bundle-ActivationPolicy: lazy
Bundle-ClassPath: .
diff --git a/server/bundles/io.cloudbeaver.service.data.transfer/pom.xml b/server/bundles/io.cloudbeaver.service.data.transfer/pom.xml
index ed68b1bc06..716f6f3734 100644
--- a/server/bundles/io.cloudbeaver.service.data.transfer/pom.xml
+++ b/server/bundles/io.cloudbeaver.service.data.transfer/pom.xml
@@ -10,7 +10,7 @@
../
io.cloudbeaver.service.data.transfer
- 1.0.110-SNAPSHOT
+ 1.0.111-SNAPSHOT
eclipse-plugin
diff --git a/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/impl/WebServiceDataTransfer.java b/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/impl/WebServiceDataTransfer.java
index 6367944b53..2d26f85dfd 100644
--- a/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/impl/WebServiceDataTransfer.java
+++ b/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/impl/WebServiceDataTransfer.java
@@ -362,7 +362,7 @@ private void importData(
processorInstance,
properties);
DatabaseMappingContainer databaseMappingContainer =
- new DatabaseMappingContainer(databaseConsumerSettings, producer.getDatabaseObject());
+ new DatabaseMappingContainer(monitor, databaseConsumerSettings, producer.getDatabaseObject(), consumer.getTargetObject());
databaseMappingContainer.getAttributeMappings(monitor);
databaseMappingContainer.setTarget(dataContainer);
consumer.setContainerMapping(databaseMappingContainer);
diff --git a/server/bundles/io.cloudbeaver.service.fs/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.service.fs/META-INF/MANIFEST.MF
index 12b77ec447..4c9a9b339a 100644
--- a/server/bundles/io.cloudbeaver.service.fs/META-INF/MANIFEST.MF
+++ b/server/bundles/io.cloudbeaver.service.fs/META-INF/MANIFEST.MF
@@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2
Bundle-Vendor: DBeaver Corp
Bundle-Name: Cloudbeaver Web Service - File System
Bundle-SymbolicName: io.cloudbeaver.service.fs;singleton:=true
-Bundle-Version: 1.0.27.qualifier
-Bundle-Release-Date: 20241118
+Bundle-Version: 1.0.28.qualifier
+Bundle-Release-Date: 20241202
Bundle-RequiredExecutionEnvironment: JavaSE-17
Bundle-ActivationPolicy: lazy
Bundle-ClassPath: .
diff --git a/server/bundles/io.cloudbeaver.service.fs/pom.xml b/server/bundles/io.cloudbeaver.service.fs/pom.xml
index 016ae1e163..c1ae61238b 100644
--- a/server/bundles/io.cloudbeaver.service.fs/pom.xml
+++ b/server/bundles/io.cloudbeaver.service.fs/pom.xml
@@ -10,7 +10,7 @@
../
io.cloudbeaver.service.fs
- 1.0.27-SNAPSHOT
+ 1.0.28-SNAPSHOT
eclipse-plugin
diff --git a/server/bundles/io.cloudbeaver.service.fs/src/io/cloudbeaver/service/fs/model/WebFSServlet.java b/server/bundles/io.cloudbeaver.service.fs/src/io/cloudbeaver/service/fs/model/WebFSServlet.java
index fa2514c98f..9a39ba821d 100644
--- a/server/bundles/io.cloudbeaver.service.fs/src/io/cloudbeaver/service/fs/model/WebFSServlet.java
+++ b/server/bundles/io.cloudbeaver.service.fs/src/io/cloudbeaver/service/fs/model/WebFSServlet.java
@@ -31,7 +31,6 @@
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.data.json.JSONUtils;
import org.jkiss.dbeaver.model.navigator.fs.DBNPathBase;
-import org.jkiss.dbeaver.utils.GeneralUtils;
import org.jkiss.utils.CommonUtils;
import org.jkiss.utils.IOUtils;
@@ -100,7 +99,7 @@ private void doPost(WebSession session, HttpServletRequest request, HttpServletR
}
} catch (Exception e) {
throw new DBWebException("File Upload Failed: Unable to Save File to the File System",
- GeneralUtils.getRootCause(e));
+ CommonUtils.getRootCause(e));
}
}
}
diff --git a/server/bundles/io.cloudbeaver.service.metadata/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.service.metadata/META-INF/MANIFEST.MF
index 6ba80756b2..5d88fe8e2d 100644
--- a/server/bundles/io.cloudbeaver.service.metadata/META-INF/MANIFEST.MF
+++ b/server/bundles/io.cloudbeaver.service.metadata/META-INF/MANIFEST.MF
@@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2
Bundle-Vendor: DBeaver Corp
Bundle-Name: Cloudbeaver Web Service - Metadata
Bundle-SymbolicName: io.cloudbeaver.service.metadata;singleton:=true
-Bundle-Version: 1.0.113.qualifier
-Bundle-Release-Date: 20241118
+Bundle-Version: 1.0.114.qualifier
+Bundle-Release-Date: 20241202
Bundle-RequiredExecutionEnvironment: JavaSE-17
Bundle-ActivationPolicy: lazy
Bundle-ClassPath: .
diff --git a/server/bundles/io.cloudbeaver.service.metadata/pom.xml b/server/bundles/io.cloudbeaver.service.metadata/pom.xml
index 0a20df5524..1e1e2f3d33 100644
--- a/server/bundles/io.cloudbeaver.service.metadata/pom.xml
+++ b/server/bundles/io.cloudbeaver.service.metadata/pom.xml
@@ -10,7 +10,7 @@
../
io.cloudbeaver.service.metadata
- 1.0.113-SNAPSHOT
+ 1.0.114-SNAPSHOT
eclipse-plugin
diff --git a/server/bundles/io.cloudbeaver.service.rm.nio/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.service.rm.nio/META-INF/MANIFEST.MF
index dbc5f5abb9..60f77cdf24 100644
--- a/server/bundles/io.cloudbeaver.service.rm.nio/META-INF/MANIFEST.MF
+++ b/server/bundles/io.cloudbeaver.service.rm.nio/META-INF/MANIFEST.MF
@@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2
Bundle-Vendor: DBeaver Corp
Bundle-Name: Cloudbeaver Resource manager NIO implementation
Bundle-SymbolicName: io.cloudbeaver.service.rm.nio;singleton:=true
-Bundle-Version: 1.0.27.qualifier
-Bundle-Release-Date: 20241118
+Bundle-Version: 1.0.28.qualifier
+Bundle-Release-Date: 20241202
Bundle-RequiredExecutionEnvironment: JavaSE-17
Bundle-ActivationPolicy: lazy
Bundle-ClassPath: .
diff --git a/server/bundles/io.cloudbeaver.service.rm.nio/pom.xml b/server/bundles/io.cloudbeaver.service.rm.nio/pom.xml
index 97b4a6b2da..6457bd6f1e 100644
--- a/server/bundles/io.cloudbeaver.service.rm.nio/pom.xml
+++ b/server/bundles/io.cloudbeaver.service.rm.nio/pom.xml
@@ -10,7 +10,7 @@
../
io.cloudbeaver.service.rm.nio
- 1.0.27-SNAPSHOT
+ 1.0.28-SNAPSHOT
eclipse-plugin
diff --git a/server/bundles/io.cloudbeaver.service.rm.nio/src/io/cloudbeaver/service/rm/fs/RMVirtualFileSystem.java b/server/bundles/io.cloudbeaver.service.rm.nio/src/io/cloudbeaver/service/rm/fs/RMVirtualFileSystem.java
index ed535b60d1..53c60d23b1 100644
--- a/server/bundles/io.cloudbeaver.service.rm.nio/src/io/cloudbeaver/service/rm/fs/RMVirtualFileSystem.java
+++ b/server/bundles/io.cloudbeaver.service.rm.nio/src/io/cloudbeaver/service/rm/fs/RMVirtualFileSystem.java
@@ -28,6 +28,7 @@
import java.net.URI;
import java.nio.file.Path;
+import java.util.List;
public class RMVirtualFileSystem extends AbstractVirtualFileSystem {
@NotNull
@@ -83,7 +84,7 @@ public Path getPathByURI(@NotNull DBRProgressMonitor monitor, @NotNull URI uri)
@NotNull
@Override
- public DBFVirtualFileSystemRoot[] getRootFolders(DBRProgressMonitor monitor) throws DBException {
- return new RMVirtualFileSystemRoot[]{new RMVirtualFileSystemRoot(this, rmProject, rmNioFileSystemProvider)};
+ public List extends DBFVirtualFileSystemRoot> getRootFolders(DBRProgressMonitor monitor) throws DBException {
+ return List.of(new RMVirtualFileSystemRoot(this, rmProject, rmNioFileSystemProvider));
}
}
diff --git a/server/bundles/io.cloudbeaver.service.rm/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.service.rm/META-INF/MANIFEST.MF
index c2c7843837..8fc6de2a28 100644
--- a/server/bundles/io.cloudbeaver.service.rm/META-INF/MANIFEST.MF
+++ b/server/bundles/io.cloudbeaver.service.rm/META-INF/MANIFEST.MF
@@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2
Bundle-Vendor: DBeaver Corp
Bundle-Name: Cloudbeaver Web Service - Resource manager
Bundle-SymbolicName: io.cloudbeaver.service.rm;singleton:=true
-Bundle-Version: 1.0.62.qualifier
-Bundle-Release-Date: 20241118
+Bundle-Version: 1.0.63.qualifier
+Bundle-Release-Date: 20241202
Bundle-RequiredExecutionEnvironment: JavaSE-17
Bundle-ActivationPolicy: lazy
Bundle-ClassPath: .
diff --git a/server/bundles/io.cloudbeaver.service.rm/pom.xml b/server/bundles/io.cloudbeaver.service.rm/pom.xml
index 4ccace9c42..24653a9748 100644
--- a/server/bundles/io.cloudbeaver.service.rm/pom.xml
+++ b/server/bundles/io.cloudbeaver.service.rm/pom.xml
@@ -10,7 +10,7 @@
../
io.cloudbeaver.service.rm
- 1.0.62-SNAPSHOT
+ 1.0.63-SNAPSHOT
eclipse-plugin
diff --git a/server/bundles/io.cloudbeaver.service.security/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.service.security/META-INF/MANIFEST.MF
index db16db1b1b..374682a3a2 100644
--- a/server/bundles/io.cloudbeaver.service.security/META-INF/MANIFEST.MF
+++ b/server/bundles/io.cloudbeaver.service.security/META-INF/MANIFEST.MF
@@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2
Bundle-Name: Cloudbeaver Web Service - Security
Bundle-Vendor: DBeaver Corp
Bundle-SymbolicName: io.cloudbeaver.service.security;singleton:=true
-Bundle-Version: 1.0.65.qualifier
-Bundle-Release-Date: 20241118
+Bundle-Version: 1.0.66.qualifier
+Bundle-Release-Date: 20241202
Bundle-RequiredExecutionEnvironment: JavaSE-17
Bundle-ActivationPolicy: lazy
Bundle-ClassPath: .
diff --git a/server/bundles/io.cloudbeaver.service.security/plugin.xml b/server/bundles/io.cloudbeaver.service.security/plugin.xml
index e9ef310594..e4b77aab29 100644
--- a/server/bundles/io.cloudbeaver.service.security/plugin.xml
+++ b/server/bundles/io.cloudbeaver.service.security/plugin.xml
@@ -4,6 +4,7 @@
diff --git a/server/bundles/io.cloudbeaver.service.security/pom.xml b/server/bundles/io.cloudbeaver.service.security/pom.xml
index 18a205d5e0..b4567ab6b5 100644
--- a/server/bundles/io.cloudbeaver.service.security/pom.xml
+++ b/server/bundles/io.cloudbeaver.service.security/pom.xml
@@ -10,7 +10,7 @@
../
io.cloudbeaver.service.security
- 1.0.65-SNAPSHOT
+ 1.0.66-SNAPSHOT
eclipse-plugin
diff --git a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/auth/provider/local/LocalAuthProvider.java b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/auth/provider/local/LocalAuthProvider.java
index fce0269e82..60cf8809cc 100644
--- a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/auth/provider/local/LocalAuthProvider.java
+++ b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/auth/provider/local/LocalAuthProvider.java
@@ -68,7 +68,9 @@ public String validateLocalAuth(@NotNull DBRProgressMonitor monitor,
throw new DBException("No user password provided");
}
String clientPasswordHash = AuthPropertyEncryption.hash.encrypt(userName, clientPassword);
- if (!storedPasswordHash.equals(clientPasswordHash)) {
+ // we also need to check a hash with lower case (CB-5833)
+ String clientPasswordHashLowerCase = AuthPropertyEncryption.hash.encrypt(userName.toLowerCase(), clientPassword);
+ if (!storedPasswordHash.equals(clientPasswordHash) && !clientPasswordHashLowerCase.equals(storedPasswordHash)) {
throw new DBException("Invalid user name or password");
}
diff --git a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/CBEmbeddedSecurityController.java b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/CBEmbeddedSecurityController.java
index 3827bfa13a..68ba34ae9f 100644
--- a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/CBEmbeddedSecurityController.java
+++ b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/CBEmbeddedSecurityController.java
@@ -116,6 +116,9 @@ private boolean isSubjectExists(String subjectId) throws DBCException {
///////////////////////////////////////////
// Users
+ /**
+ * Creates user. Saves user id in database in lower-case.
+ */
@Override
public void createUser(
@NotNull String userId,
@@ -126,6 +129,7 @@ public void createUser(
if (CommonUtils.isEmpty(userId)) {
throw new DBCException("Empty user name is not allowed");
}
+ userId = userId.toLowerCase(); // creating new users only with lowercase
if (isSubjectExists(userId)) {
throw new DBCException("User or team '" + userId + "' already exists");
}
@@ -140,6 +144,9 @@ public void createUser(
}
}
+ /**
+ * Creates user. Saves user id in database as it is.
+ */
public void createUser(
@NotNull Connection dbCon,
@NotNull String userId,
@@ -844,8 +851,13 @@ public void setUserCredentials(
}
List transformedCredentials;
WebAuthProviderDescriptor authProvider = getAuthProvider(authProviderId);
+ if (authProvider.isCaseInsensitive() && !isSubjectExists(userId) && isSubjectExists(userId.toLowerCase())) {
+ log.warn("User with id '" + userId + "' not found, credentials will be set for the user: " + userId.toLowerCase());
+ userId = userId.toLowerCase();
+ }
try {
SMAuthCredentialsProfile credProfile = getCredentialProfileByParameters(authProvider, credentials.keySet());
+ String finalUserId = userId;
transformedCredentials = credentials.entrySet().stream().map(cred -> {
String propertyName = cred.getKey();
AuthPropertyDescriptor property = credProfile.getCredentialParameter(propertyName);
@@ -853,7 +865,7 @@ public void setUserCredentials(
return null;
}
String encodedValue = CommonUtils.toString(cred.getValue());
- encodedValue = property.getEncryption().encrypt(userId, encodedValue);
+ encodedValue = property.getEncryption().encrypt(finalUserId, encodedValue);
return new String[]{propertyName, encodedValue};
}).toList();
} catch (Exception e) {
@@ -910,20 +922,38 @@ private String findUserByCredentials(
@NotNull WebAuthProviderDescriptor authProvider,
@NotNull Map authParameters,
boolean onlyActive // throws exception if user is inactive
+ ) throws DBException {
+ String userId = findUserByCredentials(authProvider, authParameters, onlyActive, false);
+ if (userId == null && authProvider.isCaseInsensitive()) {
+ // try to find user id with lower case is auth provider is case-insensitive
+ return findUserByCredentials(authProvider, authParameters, onlyActive, true);
+ }
+ return userId;
+ }
+
+ @Nullable
+ private String findUserByCredentials(
+ @NotNull WebAuthProviderDescriptor authProvider,
+ @NotNull Map authParameters,
+ boolean onlyActive,
+ boolean isCaseInsensitive
) throws DBCException {
- Map identCredentials = new LinkedHashMap<>();
+ Map identCredentials = new LinkedHashMap<>();
String[] propNames = authParameters.keySet().toArray(new String[0]);
for (AuthPropertyDescriptor prop : authProvider.getCredentialParameters(propNames)) {
if (prop.isIdentifying()) {
String propId = CommonUtils.toString(prop.getId());
- Object paramValue = authParameters.get(propId);
- if (paramValue == null) {
+ if (authParameters.get(propId) == null) {
throw new DBCException("Authentication parameter '" + prop.getId() + "' is missing");
}
if (prop.getEncryption() == AuthPropertyEncryption.hash) {
throw new DBCException("Hash encryption can't be used in identifying credentials");
}
- identCredentials.put(propId, paramValue);
+ String paramValue = CommonUtils.toString(authParameters.get(propId));
+ identCredentials.put(
+ propId,
+ isCaseInsensitive ? paramValue.toLowerCase() : paramValue
+ );
}
}
if (identCredentials.isEmpty()) {
@@ -947,9 +977,9 @@ private String findUserByCredentials(
try (PreparedStatement dbStat = dbCon.prepareStatement(database.normalizeTableNames(sql.toString()))) {
dbStat.setString(1, authProvider.getId());
int param = 2;
- for (Map.Entry credEntry : identCredentials.entrySet()) {
+ for (Map.Entry credEntry : identCredentials.entrySet()) {
dbStat.setString(param++, credEntry.getKey());
- dbStat.setString(param++, CommonUtils.toString(credEntry.getValue()));
+ dbStat.setString(param++, credEntry.getValue());
}
try (ResultSet dbResult = dbStat.executeQuery()) {
@@ -980,6 +1010,15 @@ private String findUserByCredentials(
@Override
public Map getUserCredentials(String userId, String authProviderId) throws DBCException {
WebAuthProviderDescriptor authProvider = getAuthProvider(authProviderId);
+ Map creds = getUserCredentials(authProvider, userId);
+ if (creds.isEmpty() && authProvider.isCaseInsensitive()) {
+ return getUserCredentials(authProvider, userId.toLowerCase());
+ }
+ return creds;
+ }
+
+ @NotNull
+ private Map getUserCredentials(WebAuthProviderDescriptor authProvider, String userId) throws DBCException {
try (Connection dbCon = database.openConnection()) {
try (PreparedStatement dbStat = dbCon.prepareStatement(
database.normalizeTableNames("SELECT CRED_ID,CRED_VALUE FROM {table_prefix}CB_USER_CREDENTIALS\n" +
@@ -990,7 +1029,6 @@ public Map getUserCredentials(String userId, String authProvider
try (ResultSet dbResult = dbStat.executeQuery()) {
Map credentials = new LinkedHashMap<>();
-
while (dbResult.next()) {
credentials.put(dbResult.getString(1), dbResult.getString(2));
}
@@ -1182,6 +1220,7 @@ public void createTeam(String teamId, String name, String description, String gr
if (CommonUtils.isEmpty(teamId)) {
throw new DBCException("Empty team name is not allowed");
}
+ teamId = teamId.toLowerCase();
if (isSubjectExists(teamId)) {
throw new DBCException("User or team '" + teamId + "' already exists");
}
@@ -2427,13 +2466,20 @@ private String findOrCreateExternalUserByCredentials(
return null;
}
- userId = userIdFromCredentials;
+ userId = authProvider.isCaseInsensitive() ? userIdFromCredentials.toLowerCase() : userIdFromCredentials;
if (!isSubjectExists(userId)) {
- createUser(userId,
- Map.of(),
- true,
- resolveUserAuthRole(null, authRole)
- );
+ log.debug("Create user: " + userId);
+ try (Connection dbCon = database.openConnection()) {
+ createUser(
+ dbCon,
+ userId,
+ Map.of(),
+ true,
+ resolveUserAuthRole(null, authRole)
+ );
+ } catch (SQLException e) {
+ throw new DBException("Error saving user in database", e);
+ }
}
setUserCredentials(userId, authProvider.getId(), userCredentials);
} else if (userId == null) {
diff --git a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/db/CBDatabaseInitialData.java b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/db/CBDatabaseInitialData.java
index 17c42babb2..7f2879f4f6 100644
--- a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/db/CBDatabaseInitialData.java
+++ b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/db/CBDatabaseInitialData.java
@@ -17,6 +17,7 @@
package io.cloudbeaver.service.security.db;
import org.jkiss.dbeaver.model.security.user.SMTeam;
+import org.jkiss.utils.CommonUtils;
import java.util.List;
@@ -26,7 +27,7 @@ class CBDatabaseInitialData {
private List teams;
public String getAdminName() {
- return adminName;
+ return CommonUtils.isEmpty(adminName) ? null : adminName.toLowerCase();
}
public String getAdminPassword() {
diff --git a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/internal/ClearAuthAttemptInfoJob.java b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/internal/ClearAuthAttemptInfoJob.java
index 9c700dcca4..8eb28b5721 100644
--- a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/internal/ClearAuthAttemptInfoJob.java
+++ b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/internal/ClearAuthAttemptInfoJob.java
@@ -23,7 +23,7 @@
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.runtime.AbstractJob;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
-import org.jkiss.dbeaver.utils.GeneralUtils;
+import org.jkiss.utils.CommonUtils;
public class ClearAuthAttemptInfoJob extends AbstractJob {
@@ -45,7 +45,7 @@ protected IStatus run(DBRProgressMonitor monitor) {
securityController.clearOldAuthAttemptInfo();
schedule(CHECK_PERIOD);
} catch (DBException e) {
- log.error("Error to clear the auth attempt info: " + GeneralUtils.getRootCause(e).getMessage());
+ log.error("Error to clear the auth attempt info: " + CommonUtils.getRootCause(e).getMessage());
// Check failed. Re-schedule after 5 seconds
schedule(RETRY_PERIOD);
}
diff --git a/server/bundles/io.cloudbeaver.slf4j/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.slf4j/META-INF/MANIFEST.MF
index 00ad68d5d8..7e877266d2 100644
--- a/server/bundles/io.cloudbeaver.slf4j/META-INF/MANIFEST.MF
+++ b/server/bundles/io.cloudbeaver.slf4j/META-INF/MANIFEST.MF
@@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2
Bundle-Vendor: DBeaver Corp
Bundle-Name: CloudBeaver SLF4j Binding
Bundle-SymbolicName: io.cloudbeaver.slf4j;singleton:=true
-Bundle-Version: 1.0.25.qualifier
-Bundle-Release-Date: 20241118
+Bundle-Version: 1.0.26.qualifier
+Bundle-Release-Date: 20241202
Bundle-RequiredExecutionEnvironment: JavaSE-17
Bundle-ActivationPolicy: lazy
Bundle-ClassPath: .
diff --git a/server/bundles/io.cloudbeaver.slf4j/pom.xml b/server/bundles/io.cloudbeaver.slf4j/pom.xml
index 96b8d8ab41..71d70e2ebd 100644
--- a/server/bundles/io.cloudbeaver.slf4j/pom.xml
+++ b/server/bundles/io.cloudbeaver.slf4j/pom.xml
@@ -10,7 +10,7 @@
../
io.cloudbeaver.slf4j
- 1.0.25-SNAPSHOT
+ 1.0.26-SNAPSHOT
eclipse-plugin
diff --git a/server/features/io.cloudbeaver.ce.drivers.feature/feature.xml b/server/features/io.cloudbeaver.ce.drivers.feature/feature.xml
index ec65c2a21a..16abcc7a31 100644
--- a/server/features/io.cloudbeaver.ce.drivers.feature/feature.xml
+++ b/server/features/io.cloudbeaver.ce.drivers.feature/feature.xml
@@ -2,7 +2,7 @@
diff --git a/server/features/io.cloudbeaver.ce.drivers.feature/pom.xml b/server/features/io.cloudbeaver.ce.drivers.feature/pom.xml
index 6f1c5d6ca5..2b38e45be3 100644
--- a/server/features/io.cloudbeaver.ce.drivers.feature/pom.xml
+++ b/server/features/io.cloudbeaver.ce.drivers.feature/pom.xml
@@ -9,6 +9,6 @@
../
io.cloudbeaver.ce.drivers.feature
- 1.0.133-SNAPSHOT
+ 1.0.134-SNAPSHOT
eclipse-feature
diff --git a/server/features/io.cloudbeaver.product.ce.feature/feature.xml b/server/features/io.cloudbeaver.product.ce.feature/feature.xml
index 83817d2299..3c40e2869a 100644
--- a/server/features/io.cloudbeaver.product.ce.feature/feature.xml
+++ b/server/features/io.cloudbeaver.product.ce.feature/feature.xml
@@ -2,7 +2,7 @@
diff --git a/server/features/io.cloudbeaver.product.ce.feature/pom.xml b/server/features/io.cloudbeaver.product.ce.feature/pom.xml
index 6e938928d4..d1e15f4360 100644
--- a/server/features/io.cloudbeaver.product.ce.feature/pom.xml
+++ b/server/features/io.cloudbeaver.product.ce.feature/pom.xml
@@ -10,7 +10,7 @@
../
io.cloudbeaver.product.ce.feature
- 24.2.5-SNAPSHOT
+ 24.3.0-SNAPSHOT
eclipse-feature
@@ -19,7 +19,6 @@
org.apache.maven.plugins
maven-resources-plugin
- 2.6
process-product-info
diff --git a/server/features/io.cloudbeaver.server.feature/feature.xml b/server/features/io.cloudbeaver.server.feature/feature.xml
index 9ed477595f..628631759f 100644
--- a/server/features/io.cloudbeaver.server.feature/feature.xml
+++ b/server/features/io.cloudbeaver.server.feature/feature.xml
@@ -2,7 +2,7 @@
diff --git a/server/features/io.cloudbeaver.server.feature/pom.xml b/server/features/io.cloudbeaver.server.feature/pom.xml
index ca4d958756..cf2b93d852 100644
--- a/server/features/io.cloudbeaver.server.feature/pom.xml
+++ b/server/features/io.cloudbeaver.server.feature/pom.xml
@@ -10,6 +10,6 @@
../
io.cloudbeaver.server.feature
- 24.2.5-SNAPSHOT
+ 24.3.0-SNAPSHOT
eclipse-feature
diff --git a/server/features/io.cloudbeaver.ws.feature/feature.xml b/server/features/io.cloudbeaver.ws.feature/feature.xml
index 63f31ce8cb..ccbee9242a 100644
--- a/server/features/io.cloudbeaver.ws.feature/feature.xml
+++ b/server/features/io.cloudbeaver.ws.feature/feature.xml
@@ -2,7 +2,7 @@
diff --git a/server/features/io.cloudbeaver.ws.feature/pom.xml b/server/features/io.cloudbeaver.ws.feature/pom.xml
index 6ae86adae8..03d179e748 100644
--- a/server/features/io.cloudbeaver.ws.feature/pom.xml
+++ b/server/features/io.cloudbeaver.ws.feature/pom.xml
@@ -10,6 +10,6 @@
../
io.cloudbeaver.ws.feature
- 1.0.63-SNAPSHOT
+ 1.0.64-SNAPSHOT
eclipse-feature
diff --git a/server/pom.xml b/server/pom.xml
index 43afd2610e..14cc87de26 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -19,7 +19,7 @@
CloudBeaver CE
- 24.2.5
+ 24.3.0
diff --git a/server/product/web-server/CloudbeaverServer.product b/server/product/web-server/CloudbeaverServer.product
index 03517f8893..abc42cf0ce 100644
--- a/server/product/web-server/CloudbeaverServer.product
+++ b/server/product/web-server/CloudbeaverServer.product
@@ -2,7 +2,7 @@
diff --git a/server/product/web-server/pom.xml b/server/product/web-server/pom.xml
index c508ad67b0..0218d3d2c9 100644
--- a/server/product/web-server/pom.xml
+++ b/server/product/web-server/pom.xml
@@ -9,7 +9,7 @@
1.0.0-SNAPSHOT
../../
- 24.2.5-SNAPSHOT
+ 24.3.0-SNAPSHOT
web-server
eclipse-repository
Cloudbeaver Server Product
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 d642b44e34..e2bebd4db8 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
@@ -16,15 +16,19 @@
*/
package io.cloudbeaver.test.platform;
+import io.cloudbeaver.auth.provider.local.LocalAuthProvider;
import io.cloudbeaver.auth.provider.rp.RPAuthProvider;
import io.cloudbeaver.test.WebGQLClient;
+import org.jkiss.code.NotNull;
import org.jkiss.dbeaver.model.auth.SMAuthStatus;
import org.jkiss.dbeaver.model.data.json.JSONUtils;
+import org.jkiss.utils.SecurityUtils;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
import java.util.Map;
+import java.util.Set;
public class AuthenticationTest {
private static final String GQL_OPEN_SESSION = """
@@ -39,6 +43,12 @@ mutation openSession($defaultLocale: String) {
userId
}
}""";
+ private static final String GQL_AUTH_LOGOUT = """
+ query authLogoutExtended($provider: ID, $configuration: ID) {
+ result: authLogoutExtended(provider: $provider, configuration: $configuration) {
+ redirectLinks
+ }
+ }""";
@Test
public void testLoginUser() throws Exception {
@@ -47,6 +57,34 @@ public void testLoginUser() throws Exception {
Assert.assertEquals(SMAuthStatus.SUCCESS.name(), JSONUtils.getString(authInfo, "authStatus"));
}
+
+ @Test
+ public void testLoginUserWithCamelCase() throws Exception {
+ WebGQLClient client = CEServerTestSuite.createClient();
+ for (String userId : Set.of("Test", "tESt", "tesT", "TEST")) {
+ Map credsWithCamelCase = getUserCredentials(userId);
+ // authenticating with user
+ Map authInfo = CEServerTestSuite.authenticateTestUser(client, credsWithCamelCase);
+ Assert.assertEquals(SMAuthStatus.SUCCESS.name(), JSONUtils.getString(authInfo, "authStatus"));
+ Map activeUser = client.sendQuery(GQL_ACTIVE_USER, null);
+ Assert.assertEquals(userId.toLowerCase(), JSONUtils.getString(activeUser, "userId"));
+ // making logout
+ client.sendQuery(GQL_AUTH_LOGOUT, Map.of("provider", "local"));
+
+ activeUser = client.sendQuery(GQL_ACTIVE_USER, null);
+ Assert.assertNotEquals(userId.toLowerCase(), JSONUtils.getString(activeUser, "userId"));
+ }
+ }
+
+ @NotNull
+ private Map getUserCredentials(@NotNull String userId) throws Exception {
+ return Map.of(
+ LocalAuthProvider.CRED_USER, userId,
+ LocalAuthProvider.CRED_PASSWORD, SecurityUtils.makeDigest("test")
+ );
+ }
+
+
@Test
public void testReverseProxyAnonymousModeLogin() throws Exception {
WebGQLClient client = CEServerTestSuite.createClient();
diff --git a/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/CEServerTestSuite.java b/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/CEServerTestSuite.java
index 3ca615b5ea..b133f1baa5 100644
--- a/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/CEServerTestSuite.java
+++ b/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/CEServerTestSuite.java
@@ -101,11 +101,18 @@ public static WebGQLClient createClient(@NotNull HttpClient httpClient) {
}
public static Map authenticateTestUser(@NotNull WebGQLClient client) throws Exception {
+ return authenticateTestUser(client, TEST_CREDENTIALS);
+ }
+
+ public static Map authenticateTestUser(
+ @NotNull WebGQLClient client,
+ @NotNull Map credentials
+ ) throws Exception {
return client.sendQuery(
WebGQLClient.GQL_AUTHENTICATE,
Map.of(
"provider", LocalAuthProvider.PROVIDER_ID,
- "credentials", TEST_CREDENTIALS
+ "credentials", credentials
)
);
}
diff --git a/webapp/packages/plugin-administration/src/locales/en.ts b/webapp/packages/plugin-administration/src/locales/en.ts
index 610540de9c..d1cefaf553 100644
--- a/webapp/packages/plugin-administration/src/locales/en.ts
+++ b/webapp/packages/plugin-administration/src/locales/en.ts
@@ -59,7 +59,7 @@ export default [
['administration_configuration_wizard_configuration_security_admin_credentials', 'Save credentials'],
[
'administration_configuration_wizard_configuration_security_admin_credentials_description',
- 'Allow to save credentials for pre-configured database',
+ 'Allow to save credentials for pre-configured databases',
],
['administration_configuration_wizard_configuration_security_public_credentials', 'Save users credentials'],
['administration_configuration_wizard_configuration_security_public_credentials_description', 'Allow to save credentials for non-admin users'],
diff --git a/webapp/packages/plugin-administration/src/locales/ru.ts b/webapp/packages/plugin-administration/src/locales/ru.ts
index 08a2829fb7..252de8a04e 100644
--- a/webapp/packages/plugin-administration/src/locales/ru.ts
+++ b/webapp/packages/plugin-administration/src/locales/ru.ts
@@ -41,11 +41,11 @@ export default [
['administration_configuration_wizard_configuration_security_public_credentials', 'Позволить сохранять приватные данные для пользователей'],
[
'administration_configuration_wizard_configuration_security_admin_credentials_description',
- 'Позволяет сохранять приватные данные, такие как пароли и SSH ключи',
+ 'Позволяет сохранять приватные данные для настроенных подключений',
],
[
'administration_configuration_wizard_configuration_security_public_credentials_description',
- 'Пользователи будут иметь возможность сохранять приватные данные, такие как пароли и SSH ключи',
+ 'Позволяет сохранять приватные данные (такие как пароли и SSH ключи) для пользователей, не являющихся администраторами',
],
['administration_disabled_drivers_title', 'Отключенные драйверы'],
diff --git a/webapp/packages/plugin-authentication-administration/src/Administration/Users/Teams/GrantedUsers/GrantedUsers.module.css b/webapp/packages/plugin-authentication-administration/src/Administration/Users/Teams/GrantedUsers/GrantedUsers.module.css
index 293ac777b5..fbccc496b0 100644
--- a/webapp/packages/plugin-authentication-administration/src/Administration/Users/Teams/GrantedUsers/GrantedUsers.module.css
+++ b/webapp/packages/plugin-authentication-administration/src/Administration/Users/Teams/GrantedUsers/GrantedUsers.module.css
@@ -17,6 +17,10 @@
overflow: auto !important;
}
+.placeholder {
+ margin: 0 !important;
+}
+
.loader {
z-index: 2;
}
diff --git a/webapp/packages/plugin-authentication-administration/src/Administration/Users/Teams/GrantedUsers/GrantedUsers.tsx b/webapp/packages/plugin-authentication-administration/src/Administration/Users/Teams/GrantedUsers/GrantedUsers.tsx
index 496c6fbf3b..122bff1dac 100644
--- a/webapp/packages/plugin-authentication-administration/src/Administration/Users/Teams/GrantedUsers/GrantedUsers.tsx
+++ b/webapp/packages/plugin-authentication-administration/src/Administration/Users/Teams/GrantedUsers/GrantedUsers.tsx
@@ -55,9 +55,11 @@ export const GrantedUsers: TabContainerPanelComponent = observer
if (isDefaultTeam) {
return (
-
-
- {translate('plugin_authentication_administration_team_default_users_tooltip')}
+
+
+
+ {translate('plugin_authentication_administration_team_default_users_tooltip')}
+
);
@@ -66,10 +68,12 @@ export const GrantedUsers: TabContainerPanelComponent = observer
return (
{() => (
-
+
{!users.resource.values.length ? (
-
- {translate('administration_teams_team_granted_users_empty')}
+
+
+ {translate('administration_teams_team_granted_users_empty')}
+
) : (
<>
diff --git a/webapp/packages/plugin-authentication-administration/src/Administration/Users/UserForm/Info/UserFormInfoCredentials.tsx b/webapp/packages/plugin-authentication-administration/src/Administration/Users/UserForm/Info/UserFormInfoCredentials.tsx
index ac13ee727f..c5136b7564 100644
--- a/webapp/packages/plugin-authentication-administration/src/Administration/Users/UserForm/Info/UserFormInfoCredentials.tsx
+++ b/webapp/packages/plugin-authentication-administration/src/Administration/Users/UserForm/Info/UserFormInfoCredentials.tsx
@@ -54,7 +54,16 @@ export const UserFormInfoCredentials = observer(function UserFormInfoCred
return (
{translate('authentication_user_credentials')}
-
+
{translate('authentication_user_name')}
{local && (
diff --git a/webapp/packages/plugin-authentication-administration/src/Administration/Users/UserForm/Info/UserFormInfoPart.ts b/webapp/packages/plugin-authentication-administration/src/Administration/Users/UserForm/Info/UserFormInfoPart.ts
index 19b4cb1663..240cd8e90b 100644
--- a/webapp/packages/plugin-authentication-administration/src/Administration/Users/UserForm/Info/UserFormInfoPart.ts
+++ b/webapp/packages/plugin-authentication-administration/src/Administration/Users/UserForm/Info/UserFormInfoPart.ts
@@ -104,6 +104,8 @@ export class UserFormInfoPart extends FormPart connectionKey && connection.resource.isConnecting(connectionKey));
+ const connecting = getComputed(() => (connectionKey && connection.resource.isConnecting(connectionKey)) || connection.loading);
+ const isConnectionReady = getComputed(() => !connecting && connection.data?.connected && connection.loaded && !connection.outdated);
async function handleConnect() {
- if (connecting || !connection.data || !connectionKey) {
+ if (isConnectionReady || !connection.data || !connectionKey) {
return;
}
@@ -37,11 +38,11 @@ export const ConnectionShield = observer connection.data && !connection.data.connected)) {
- if (connecting) {
- return ;
- }
+ if (connecting) {
+ return ;
+ }
+ if (!isConnectionReady) {
return (