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 9b750b5089..2bc52588d3 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/WebDataSourceRegistryProxy.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/WebDataSourceRegistryProxy.java @@ -109,7 +109,7 @@ public class WebDataSourceRegistryProxy implements DBPDataSourceRegistry, DataSo } @Override - public void addDataSource(@NotNull DBPDataSourceContainer dataSource) { + public void addDataSource(@NotNull DBPDataSourceContainer dataSource) throws DBException { dataSourceRegistry.addDataSource(dataSource); } @@ -119,7 +119,7 @@ public class WebDataSourceRegistryProxy implements DBPDataSourceRegistry, DataSo } @Override - public void updateDataSource(@NotNull DBPDataSourceContainer dataSource) { + public void updateDataSource(@NotNull DBPDataSourceContainer dataSource) throws DBException { dataSourceRegistry.updateDataSource(dataSource); } diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerRoot.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerRoot.java index c944723c49..de59ccc520 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerRoot.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerRoot.java @@ -77,7 +77,7 @@ public class DBNResourceManagerRoot extends DBNNode implements DBPHiddenObject, List projectList = getParentNode().getModel().getModelProjects(); SMSession session = null; for (DBPProject project : projectList) { - session = getParentNode().getModel().getModelAuthContext().getSpaceSession(monitor, project, false); + session = getParentNode().getModel().getModelAuthContext().getSpaceSession(monitor, project.getWorkspace(), false); if (session instanceof WebSession) { break; } 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 715621f815..079be1b693 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 @@ -42,6 +42,7 @@ import org.jkiss.dbeaver.model.sql.DBQuotaException; import org.jkiss.dbeaver.registry.*; import org.jkiss.dbeaver.runtime.DBWorkbench; import org.jkiss.utils.CommonUtils; +import org.jkiss.utils.IOUtils; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -258,7 +259,7 @@ public class LocalResourceController implements RMController { throw new DBException("Project '" + project.getName() + "' doesn't exists"); } try { - CommonUtils.deleteDirectory(targetPath); + IOUtils.deleteDirectory(targetPath); smController.deleteAllObjectPermissions(projectId, SMObjects.PROJECT); } catch (IOException e) { throw new DBException("Error deleting project '" + project.getName() + "'", e); @@ -422,7 +423,7 @@ public class LocalResourceController implements RMController { List rmResourcePath = makeResourcePath(projectId, targetPath, recursive); try { if (targetPath.toFile().isDirectory()) { - CommonUtils.deleteDirectory(targetPath); + IOUtils.deleteDirectory(targetPath); } else { Files.delete(targetPath); } 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 be7ff0e61d..9c0b36d159 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 @@ -82,7 +82,8 @@ import java.util.stream.Collectors; * Web session. * Is the main source of data in web application */ -public class WebSession extends AbstractSessionPersistent implements SMSession, SMCredentialsProvider, DBACredentialsProvider, IAdaptable { +public class WebSession extends AbstractSessionPersistent + implements SMSession, SMCredentialsProvider, DBACredentialsProvider, IAdaptable { private static final Log log = Log.getLog(WebSession.class); @@ -143,7 +144,7 @@ public class WebSession extends AbstractSessionPersistent implements SMSession, @NotNull @Override public SMAuthSpace getSessionSpace() { - return defaultProject; + return DBWorkbench.getPlatform().getWorkspace(); } @Override 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 b7c68214dc..4e852ca1d3 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 @@ -30,6 +30,7 @@ import io.cloudbeaver.server.jetty.CBJettyServer; import io.cloudbeaver.service.DBWServiceInitializer; import io.cloudbeaver.service.security.CBEmbeddedSecurityController; import io.cloudbeaver.service.security.EmbeddedSecurityControllerFactory; +import io.cloudbeaver.service.session.WebSessionManager; import io.cloudbeaver.utils.WebAppUtils; import org.eclipse.core.runtime.Platform; import org.eclipse.osgi.service.datalocation.Location; @@ -119,6 +120,8 @@ public class CBApplication extends BaseWebApplication implements WebAuthApplicat private String localHostAddress; private final List localInetAddresses = new ArrayList<>(); + private WebSessionManager sessionManager; + public CBApplication() { } @@ -981,4 +984,14 @@ public class CBApplication extends BaseWebApplication implements WebAuthApplicat patchConfigurationWithProperties(configProps, varResolver); } + public WebSessionManager getSessionManager() { + if (sessionManager == null) { + sessionManager = createSessionManager(); + } + return sessionManager; + } + + protected WebSessionManager createSessionManager() { + return new WebSessionManager(this); + } } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBPlatform.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBPlatform.java index e72dcab8a5..a934777f58 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBPlatform.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBPlatform.java @@ -47,7 +47,6 @@ import org.jkiss.dbeaver.utils.ContentUtils; import org.jkiss.dbeaver.utils.GeneralUtils; import org.osgi.framework.Bundle; -import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -79,7 +78,6 @@ public class CBPlatform extends BasePlatformImpl { private DBACertificateStorage certificateStorage; private WebWorkspace workspace; - private WebSessionManager sessionManager; private final List applicableDrivers = new ArrayList<>(); public static CBPlatform getInstance() { @@ -145,14 +143,12 @@ public class CBPlatform extends BasePlatformImpl { this.queryManager.registerMetaListener(qmLogWriter); this.certificateStorage = new DefaultCertificateStorage( - new File(WebPlatformActivator.getInstance().getStateLocation().toFile(), "security")); + WebPlatformActivator.getInstance().getStateLocation().toFile().toPath().resolve("security")); super.initialize(); refreshApplicableDrivers(); - sessionManager = WebSessionManager.getInstance(); - new WebSessionMonitorJob(this).scheduleMonitor(); log.info("Web platform initialized (" + (System.currentTimeMillis() - startTime) + "ms)"); @@ -273,7 +269,7 @@ public class CBPlatform extends BasePlatformImpl { } public WebSessionManager getSessionManager() { - return sessionManager; + return application.getSessionManager(); } public void refreshApplicableDrivers() { 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 71349b7dc4..2e30c4bf64 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 @@ -363,8 +363,9 @@ public class WebServiceCore implements DBWServiceCore { newDataSource.setName(CommonUtils.notNull(connectionConfig.getName(), "NewConnection")); } - sessionRegistry.addDataSource(newDataSource); try { + sessionRegistry.addDataSource(newDataSource); + sessionRegistry.checkForErrors(); } catch (DBException e) { sessionRegistry.removeDataSource(newDataSource); @@ -405,8 +406,8 @@ public class WebServiceCore implements DBWServiceCore { WebServiceUtils.setConnectionConfiguration(dataSource.getDriver(), dataSource.getConnectionConfiguration(), config); WebServiceUtils.saveAuthProperties(dataSource, dataSource.getConnectionConfiguration(), config.getCredentials(), config.isSaveCredentials()); - sessionRegistry.updateDataSource(dataSource); try { + sessionRegistry.updateDataSource(dataSource); sessionRegistry.checkForErrors(); } catch (DBException e) { throw new DBWebException("Failed to update connection", e); @@ -450,8 +451,9 @@ public class WebServiceCore implements DBWServiceCore { if (!CommonUtils.isEmpty(connectionName)) { newDataSource.setName(connectionName); } - projectRegistry.addDataSource(newDataSource); try { + projectRegistry.addDataSource(newDataSource); + projectRegistry.checkForErrors(); } catch (DBException e) { throw new DBWebException(e.getMessage(), e.getCause()); @@ -631,7 +633,11 @@ public class WebServiceCore implements DBWServiceCore { try { registry.checkForErrors(); } catch (DBException e) { - registry.addDataSource(dataSourceContainer); + try { + registry.addDataSource(dataSourceContainer); + } catch (DBException ex) { + log.error("Error re-adding after delete attempt", e); + } throw new DBWebException("Failed to delete connection", e); } webSession.removeConnection(connectionInfo); diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/session/WebSessionManager.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/session/WebSessionManager.java index b4d5f967cf..2d074040dc 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/session/WebSessionManager.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/session/WebSessionManager.java @@ -37,24 +37,17 @@ import java.util.*; import java.util.stream.Collectors; /** - * Various constants + * Web session manager */ public class WebSessionManager { private static final Log log = Log.getLog(WebSessionManager.class); - private static WebSessionManager instance; - - public synchronized static WebSessionManager getInstance() { - if (instance == null) { - instance = new WebSessionManager(); - } - return instance; - } - + private final CBApplication application; private final Map sessionMap = new HashMap<>(); - public WebSessionManager() { + public WebSessionManager(CBApplication application) { + this.application = application; } public WebSession closeSession(@NotNull HttpServletRequest request) throws DBException { @@ -73,6 +66,10 @@ public class WebSessionManager { return null; } + protected CBApplication getApplication() { + return application; + } + public boolean touchSession(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response) throws DBWebException { WebSession webSession = getWebSession(request, response, false); long maxSessionIdleTime = CBApplication.getInstance().getMaxSessionIdleTime(); @@ -95,17 +92,11 @@ public class WebSessionManager { HttpSession httpSession = request.getSession(true); String sessionId = httpSession.getId(); WebSession webSession; - long maxSessionIdleTime = CBApplication.getInstance().getMaxSessionIdleTime(); synchronized (sessionMap) { webSession = sessionMap.get(sessionId); if (webSession == null) { - CBApplication application = CBApplication.getInstance(); - Map sessionHandlers = WebHandlerRegistry.getInstance().getSessionHandlers() - .stream() - .collect(Collectors.toMap(WebSessionHandlerDescriptor::getId, WebSessionHandlerDescriptor::getInstance)); try { - - webSession = new WebSession(httpSession, application, sessionHandlers, maxSessionIdleTime); + webSession = createWebSessionImpl(httpSession); } catch (DBException e) { throw new DBWebException("Failed to create web session", e); } @@ -125,7 +116,7 @@ public class WebSessionManager { if (updateInfo) { // Update only once per request if (!CommonUtils.toBoolean(request.getAttribute("sessionUpdated"))) { - webSession.updateInfo(request, response, maxSessionIdleTime); + webSession.updateInfo(request, response, application.getMaxSessionIdleTime()); request.setAttribute("sessionUpdated", true); } } @@ -134,6 +125,18 @@ public class WebSessionManager { return webSession; } + @NotNull + protected WebSession createWebSessionImpl(@NotNull HttpSession httpSession) throws DBException { + return new WebSession(httpSession, application, getSessionHandlers(), application.getMaxSessionIdleTime()); + } + + @NotNull + protected Map getSessionHandlers() { + return WebHandlerRegistry.getInstance().getSessionHandlers() + .stream() + .collect(Collectors.toMap(WebSessionHandlerDescriptor::getId, WebSessionHandlerDescriptor::getInstance)); + } + @Nullable public WebSession getWebSession(@NotNull String sessionId) { synchronized (sessionMap) { 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 932e05d1b8..795fb7d469 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 @@ -356,8 +356,12 @@ public class WebServiceAdmin implements DBWServiceAdmin { webSession.addInfoMessage("Create new connection"); DBPDataSourceRegistry registry = getGlobalRegistry(webSession); DBPDataSourceContainer dataSource = WebServiceUtils.createConnectionFromConfig(config, registry); - registry.addDataSource(dataSource); - dataSource.persistConfiguration(); + try { + registry.addDataSource(dataSource); + } catch (DBException e) { + throw new DBWebException("Error adding datasource", e); + } + webSession.addInfoMessage( "New connection was created - " + WebServiceUtils.getConnectionContainerInfo(dataSource) ); diff --git a/server/bundles/io.cloudbeaver.service.security/db/cb_schema_create.sql b/server/bundles/io.cloudbeaver.service.security/db/cb_schema_create.sql index b6af496124..bc6b63f0c0 100644 --- a/server/bundles/io.cloudbeaver.service.security/db/cb_schema_create.sql +++ b/server/bundles/io.cloudbeaver.service.security/db/cb_schema_create.sql @@ -289,7 +289,7 @@ CREATE TABLE CB_USER_SECRETS ( USER_ID VARCHAR(128) NOT NULL, SECRET_ID VARCHAR(512) NOT NULL, - SECRET_VALUE VARCHAR(30000) NOT NULL, + SECRET_VALUE VARCHAR(65000) NOT NULL, SECRET_LABEL VARCHAR(128), SECRET_DESCRIPTION VARCHAR(1024), diff --git a/server/bundles/io.cloudbeaver.service.security/db/cb_schema_update_10.sql b/server/bundles/io.cloudbeaver.service.security/db/cb_schema_update_10.sql index 58afb573fb..a4039aac8d 100644 --- a/server/bundles/io.cloudbeaver.service.security/db/cb_schema_update_10.sql +++ b/server/bundles/io.cloudbeaver.service.security/db/cb_schema_update_10.sql @@ -2,7 +2,7 @@ CREATE TABLE CB_USER_SECRETS ( USER_ID VARCHAR(128) NOT NULL, SECRET_ID VARCHAR(512) NOT NULL, - SECRET_VALUE VARCHAR(30000) NOT NULL, + SECRET_VALUE VARCHAR(65000) NOT NULL, SECRET_LABEL VARCHAR(128), SECRET_DESCRIPTION VARCHAR(1024),