From 12e0107617f78588341c4d88381569bc07c7c794 Mon Sep 17 00:00:00 2001 From: serge-rider Date: Wed, 18 Sep 2024 15:40:15 +0200 Subject: [PATCH 1/5] 24.2.2 version bump --- webapp/packages/product-default/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/packages/product-default/package.json b/webapp/packages/product-default/package.json index 95ad13e66a..4bd8b88606 100644 --- a/webapp/packages/product-default/package.json +++ b/webapp/packages/product-default/package.json @@ -5,7 +5,7 @@ "src/**/*.scss", "public/**/*" ], - "version": "24.2.1", + "version": "24.2.2", "description": "CloudBeaver Community", "license": "Apache-2.0", "main": "dist/index.js", From 46309e9505d060008088e934a12a7c133376df43 Mon Sep 17 00:00:00 2001 From: Anastasiya <45152336+LonwoLonwo@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:58:39 +0300 Subject: [PATCH 2/5] Update README.md link (#2923) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5bcf48ae8f..2149dc9704 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,6 @@ You can see a live demo of CloudBeaver here: https://demo.cloudbeaver.io ## Contribution As a community-driven open-source project, we warmly welcome contributions through GitHub pull requests. -[We are happy to reward](https://dbeaver.com/help-beaver/) our most active contributors every major sprint. +[We are happy to reward](https://dbeaver.com/help-dbeaver/) our most active contributors every major sprint. The most significant contribution to our code for the major release 24.2.0 was made by: 1. [matthieukhl](https://github.com/matthieukhl) From 90acaaf00e1404899d3e469c7c121a3810865a3c Mon Sep 17 00:00:00 2001 From: Serge Rider Date: Thu, 19 Sep 2024 08:28:15 +0200 Subject: [PATCH 3/5] dbeaver/pro#3336 RCP model refactoring. Remove VFS from base model (#2913) * dbeaver/pro#3336 RCP model refactoring. Remove VFS from base model * dbeaver/pro#3336 Simplify DBNNodeWithResource * dbeaver/pro#3336 Web node info fix * dbeaver/pro#3336 Code style * dbeaver/pro#3336 Fix node project get --- .../model/rm/DBNResourceManagerProject.java | 28 +++--- .../model/rm/DBNResourceManagerResource.java | 1 + .../model/session/WebSessionWorkspace.java | 7 ++ .../navigator/WebNavigatorNodeInfo.java | 25 ++--- .../navigator/impl/WebServiceNavigator.java | 23 ++--- .../CBEmbeddedSecurityController.java | 97 ++++++++----------- 6 files changed, 89 insertions(+), 92 deletions(-) diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerProject.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerProject.java index cf601dae8c..7500c25460 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerProject.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerProject.java @@ -20,7 +20,6 @@ import org.jkiss.code.NotNull; import org.jkiss.code.Nullable; import org.jkiss.dbeaver.DBException; -import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.model.DBIcon; import org.jkiss.dbeaver.model.DBPImage; import org.jkiss.dbeaver.model.DBPObject; @@ -37,7 +36,6 @@ import java.util.List; public class DBNResourceManagerProject extends DBNAbstractResourceManagerNode { - private static final Log log = Log.getLog(DBNResourceManagerProject.class); private final RMProject project; @@ -123,24 +121,18 @@ public DBNNode refreshNode(DBRProgressMonitor monitor, Object source) throws DBE return this; } - @Override - public String toString() { - return getNodeDisplayName(); - } - - + @NotNull @Override public DBPProject getOwnerProject() { List globalProjects = getModel().getModelProjects(); - if (globalProjects == null) { - return null; - } - for (DBPProject modelProject : globalProjects) { - if (CommonUtils.equalObjects(modelProject.getId(), project.getId())) { - return modelProject; + if (globalProjects != null) { + for (DBPProject modelProject : globalProjects) { + if (CommonUtils.equalObjects(modelProject.getId(), project.getId())) { + return modelProject; + } } } - return null; + throw new IllegalStateException("Project '" + project.getId() + "' not found in workspace"); } @Nullable @@ -148,4 +140,10 @@ public DBPProject getOwnerProject() { public DBPObject getObjectDetails(@NotNull DBRProgressMonitor monitor, @NotNull SMSessionContext sessionContext, @NotNull Object dataSource) throws DBException { return project; } + + @Override + public String toString() { + return getNodeDisplayName(); + } + } diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerResource.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerResource.java index 30919d34ca..0fdc50e6e4 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerResource.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerResource.java @@ -203,6 +203,7 @@ public DBPObject getObjectDetails(@NotNull DBRProgressMonitor monitor, @NotNull return resource; } + @NotNull @Override public DBPProject getOwnerProject() { return getParentNode().getOwnerProject(); diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebSessionWorkspace.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebSessionWorkspace.java index f1a86e49c4..f24bf8c90a 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebSessionWorkspace.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebSessionWorkspace.java @@ -19,6 +19,8 @@ import io.cloudbeaver.WebProjectImpl; import org.jkiss.code.NotNull; import org.jkiss.code.Nullable; +import org.jkiss.dbeaver.model.DBPAdaptable; +import org.jkiss.dbeaver.model.DBPImage; import org.jkiss.dbeaver.model.app.DBPPlatform; import org.jkiss.dbeaver.model.app.DBPProject; import org.jkiss.dbeaver.model.app.DBPWorkspace; @@ -132,6 +134,11 @@ public void dispose() { clearProjects(); } + @Override + public DBPImage getResourceIcon(DBPAdaptable resourceAdapter) { + return null; + } + public void setActiveProject(DBPProject activeProject) { this.activeProject = (WebProjectImpl) activeProject; } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/WebNavigatorNodeInfo.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/WebNavigatorNodeInfo.java index 18bf967868..6e31e3113e 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/WebNavigatorNodeInfo.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/WebNavigatorNodeInfo.java @@ -111,7 +111,7 @@ public String getPlainName() { // for renaming node @Property public String getProjectId() { - DBPProject ownerProject = node.getOwnerProject(); + DBPProject ownerProject = node.getOwnerProjectOrNull(); return ownerProject == null ? null : ownerProject.getId(); } @@ -119,11 +119,11 @@ public String getProjectId() { @Deprecated public String getFullName() { String nodeName; - if (node instanceof DBNDatabaseNode && !(node instanceof DBNDataSource)) { - DBSObject object = ((DBNDatabaseNode) node).getObject(); + if (node instanceof DBNDatabaseNode dbNode && !(node instanceof DBNDataSource)) { + DBSObject object = dbNode.getObject(); nodeName = DBUtils.getObjectFullName(object, DBPEvaluationContext.UI); - } else if (node instanceof DBNDataSource) { - DBPDataSourceContainer object = ((DBNDataSource) node).getDataSourceContainer(); + } else if (node instanceof DBNDataSource dataSource) { + DBPDataSourceContainer object = dataSource.getDataSourceContainer(); nodeName = object.getName(); } else { nodeName = node.getNodeTargetName(); @@ -235,7 +235,7 @@ public String[] getFeatures() { if (objectManager != null && objectManager.canDeleteObject(object)) { features.add(NODE_FEATURE_CAN_DELETE); } - if (objectManager instanceof DBEObjectRenamer && ((DBEObjectRenamer) objectManager).canRenameObject(object)) { + if (objectManager instanceof DBEObjectRenamer renamer && renamer.canRenameObject(object)) { if (!object.getDataSource().getContainer().getNavigatorSettings().isShowOnlyEntities()) { features.add(NODE_FEATURE_CAN_RENAME); } @@ -282,9 +282,10 @@ private boolean isDistributedSpecialFolderNode() { @Property public WebPropertyInfo[] getNodeDetails() throws DBWebException { - if (node instanceof DBPObjectWithDetails) { + if (node instanceof DBPObjectWithDetails objectWithDetails) { try { - DBPObject objectDetails = ((DBPObjectWithDetails) node).getObjectDetails(session.getProgressMonitor(), session.getSessionContext(), node); + DBPObject objectDetails = objectWithDetails.getObjectDetails( + session.getProgressMonitor(), session.getSessionContext(), node); if (objectDetails != null) { return WebServiceUtils.getObjectProperties(session, objectDetails); } @@ -301,8 +302,8 @@ public WebPropertyInfo[] getNodeDetails() throws DBWebException { @Property public WebDatabaseObjectInfo getObject() { - if (node instanceof DBNDatabaseNode) { - DBSObject object = ((DBNDatabaseNode) node).getObject(); + if (node instanceof DBNDatabaseNode dbNode) { + DBSObject object = dbNode.getObject(); return object == null ? null : new WebDatabaseObjectInfo(session, object); } return null; @@ -320,10 +321,10 @@ public String getObjectId() { @Property public DBSObjectFilter getFilter() throws DBWebException { - if (!(node instanceof DBNDatabaseNode)) { + if (!(node instanceof DBNDatabaseNode dbNode)) { throw new DBWebException("Invalid navigator node type: " + node.getClass().getName()); } - DBSObjectFilter filter = ((DBNDatabaseNode) node).getNodeFilter(((DBNDatabaseNode) node).getItemsMeta(), true); + DBSObjectFilter filter = dbNode.getNodeFilter(dbNode.getItemsMeta(), true); return filter == null || filter.isEmpty() || !filter.isEnabled() ? null : filter; } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java index 28f54520c8..96690ea4de 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java @@ -228,11 +228,12 @@ public boolean setNavigatorNodeFilter( filter.setExclude(exclude); } filter.setEnabled(true); - ((DBNDatabaseNode) node).setNodeFilter( - ((DBNDatabaseNode) node).getItemsMeta(), filter, true); - if (hasNodeEditPermission(webSession, node, ((WebProjectImpl) node.getOwnerProject()).getRmProject())) { - // Save settings - ((DBNDatabaseNode) node).getDataSourceContainer().persistConfiguration(); + if (node instanceof DBNDatabaseNode dbNode) { + dbNode.setNodeFilter(dbNode.getItemsMeta(), filter, true); + if (hasNodeEditPermission(webSession, node, ((WebProjectImpl) node.getOwnerProject()).getRmProject())) { + // Save settings + dbNode.getDataSourceContainer().persistConfiguration(); + } } } catch (DBException e) { if (e instanceof DBWebException) { @@ -255,14 +256,14 @@ public boolean refreshNavigatorNode( if (node == null) { throw new DBWebException("Navigator node '" + nodePath + "' not found"); } - if (node instanceof DBNDataSource) { + if (node instanceof DBNDataSource dbnDataSource) { // Do not refresh entire tree - just clear child nodes // Otherwise refresh may fail if navigator settings were changed. - DBPDataSource dataSource = ((DBNDataSource) node).getDataSource(); - if (dataSource instanceof DBPRefreshableObject) { - ((DBPRefreshableObject) dataSource).refreshObject(monitor); + DBPDataSource dataSource = dbnDataSource.getDataSource(); + if (dataSource instanceof DBPRefreshableObject refreshableObject) { + refreshableObject.refreshObject(monitor); } - ((DBNDataSource) node).cleanupNode(); + dbnDataSource.cleanupNode(); } else if (node instanceof DBNLocalFolder) { // Refresh can't be applied to the local folder node return true; @@ -425,7 +426,7 @@ private String renameConnectionFolder(@NotNull WebSession session, DBNNode node, List siblings = Arrays.stream( ((DBNLocalFolder) node).getLogicalParent().getChildren(session.getProgressMonitor())) .filter(n -> n instanceof DBNLocalFolder) - .map(DBNNode::getName).collect(Collectors.toList()); + .map(DBNNode::getName).toList(); if (siblings.contains(newName)) { throw new DBWebException("Name " + newName + " is unavailable or invalid"); } 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 7b21ede7fb..c8887edeed 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 @@ -515,7 +515,7 @@ public SMUser[] findUsers(@NotNull SMUserFilter filter) try (PreparedStatement dbStat = dbCon.prepareStatement( database.normalizeTableNames("SELECT USER_ID,IS_ACTIVE,DEFAULT_AUTH_ROLE FROM {table_prefix}CB_USER" + buildUsersFilter(filter) + "\nORDER BY USER_ID " + getOffsetLimitPart(filter)))) { - int parameterIndex = setUsersFilterValues(dbStat, filter, 1); + setUsersFilterValues(dbStat, filter, 1); try (ResultSet dbResult = dbStat.executeQuery()) { while (dbResult.next()) { @@ -531,14 +531,11 @@ public SMUser[] findUsers(@NotNull SMUserFilter filter) } readSubjectsMetas(dbCon, SMSubjectType.user, filter.getUserIdMask(), result); - StringBuilder teamsSql = new StringBuilder() - .append("SELECT USER_ID,TEAM_ID FROM {table_prefix}CB_USER_TEAM") - .append("\n") - .append("WHERE USER_ID IN (") - .append(SQLUtils.generateParamList(result.size())) - .append(")"); + String teamsSql = + "SELECT USER_ID,TEAM_ID FROM {table_prefix}CB_USER_TEAM\n" + + "WHERE USER_ID IN (" + SQLUtils.generateParamList(result.size()) + ")"; // Read teams - try (PreparedStatement dbStat = dbCon.prepareStatement(database.normalizeTableNames(teamsSql.toString()))) { + try (PreparedStatement dbStat = dbCon.prepareStatement(database.normalizeTableNames(teamsSql))) { int parameterIndex = 1; for (String userId : result.keySet()) { dbStat.setString(parameterIndex++, userId); @@ -574,7 +571,7 @@ private String buildUsersFilter(SMUserFilter filter) { if (filter.getEnabledState() != null) { whereParts.add("IS_ACTIVE=?"); } - if (whereParts.size() > 0) { + if (!whereParts.isEmpty()) { where.append(whereParts.stream().collect(Collectors.joining(" AND ", " WHERE ", ""))); } return where.toString(); @@ -858,7 +855,7 @@ public void setUserCredentials( String encodedValue = CommonUtils.toString(cred.getValue()); encodedValue = property.getEncryption().encrypt(userId, encodedValue); return new String[]{propertyName, encodedValue}; - }).collect(Collectors.toList()); + }).toList(); } catch (Exception e) { throw new DBCException(e.getMessage(), e); } @@ -1037,7 +1034,7 @@ public String[] getUserLinkedProviders(@NotNull String userId) throws DBExceptio @NotNull @Override - public SMPropertyDescriptor[] getMetaParametersBySubjectType(SMSubjectType subjectType) throws DBException { + public SMPropertyDescriptor[] getMetaParametersBySubjectType(SMSubjectType subjectType) { // First add global metas List props = new ArrayList<>( WebMetaParametersRegistry.getInstance().getMetaParameters(subjectType)); @@ -1083,9 +1080,11 @@ public SMTeam[] readAllTeams() throws DBCException { } } } - query = database.normalizeTableNames("SELECT SUBJECT_ID,PERMISSION_ID\n" + - "FROM {table_prefix}CB_AUTH_PERMISSIONS AP, {table_prefix}CB_TEAM R\n" + - "WHERE AP.SUBJECT_ID IN (R.TEAM_ID,?)\n"); + query = database.normalizeTableNames(""" + SELECT SUBJECT_ID,PERMISSION_ID + FROM {table_prefix}CB_AUTH_PERMISSIONS AP, {table_prefix}CB_TEAM R + WHERE AP.SUBJECT_ID IN (R.TEAM_ID,?) + """); try (PreparedStatement dbPreparedStatement = dbCon.prepareStatement(query)) { dbPreparedStatement.setString(1, defaultUserTeam); try (ResultSet dbResult = dbPreparedStatement.executeQuery()) { @@ -1422,7 +1421,7 @@ private String createSmSession( @NotNull Map parameters, @NotNull SMSessionType sessionType, Connection dbCon - ) throws SQLException, DBException { + ) throws SQLException { var sessionId = UUID.randomUUID().toString(); try (PreparedStatement dbStat = dbCon.prepareStatement( database.normalizeTableNames( @@ -1754,11 +1753,10 @@ private void updateAuthStatus( SMAuthConfigurationReference providerId = entry.getKey(); String authJson = gson.toJson(entry.getValue()); boolean configIdExist = providerId.getAuthProviderConfigurationId() != null; - var sqlBuilder = new StringBuilder(); - sqlBuilder.append("UPDATE {table_prefix}CB_AUTH_ATTEMPT_INFO SET AUTH_STATE=? ") - .append("WHERE AUTH_ID=? AND AUTH_PROVIDER_ID=? AND ") - .append(configIdExist ? "AUTH_PROVIDER_CONFIGURATION_ID=?" : "AUTH_PROVIDER_CONFIGURATION_ID IS NULL"); - try (PreparedStatement dbStat = dbCon.prepareStatement(database.normalizeTableNames(sqlBuilder.toString()))) { + String sqlBuilder = "UPDATE {table_prefix}CB_AUTH_ATTEMPT_INFO SET AUTH_STATE=? " + + "WHERE AUTH_ID=? AND AUTH_PROVIDER_ID=? AND " + + (configIdExist ? "AUTH_PROVIDER_CONFIGURATION_ID=?" : "AUTH_PROVIDER_CONFIGURATION_ID IS NULL"); + try (PreparedStatement dbStat = dbCon.prepareStatement(database.normalizeTableNames(sqlBuilder))) { dbStat.setString(1, authJson); dbStat.setString(2, authId); dbStat.setString(3, providerId.getAuthProviderId()); @@ -1848,16 +1846,14 @@ private SMAuthInfo getAuthStatus(@NotNull String authId, boolean readExpiredData if (authProviderConfiguration != null) { WebAuthProviderDescriptor authProviderDescriptor = getAuthProvider(authProviderId); var authProviderInstance = authProviderDescriptor.getInstance(); - if (SMAuthProviderFederated.class.isAssignableFrom(authProviderInstance.getClass())) { - signInLink = buildRedirectLink(((SMAuthProviderFederated) authProviderInstance).getRedirectLink( + if (authProviderInstance instanceof SMAuthProviderFederated providerFederated) { + signInLink = buildRedirectLink(providerFederated.getRedirectLink( authProviderConfiguration, Map.of()), authId); - var userCustomSignOutLink = - ((SMAuthProviderFederated) authProviderInstance).getUserSignOutLink( - application.getAuthConfiguration() - .getAuthProviderConfiguration(authProviderConfiguration), - authProviderData); - signOutLink = userCustomSignOutLink; + signOutLink = providerFederated.getUserSignOutLink( + application.getAuthConfiguration() + .getAuthProviderConfiguration(authProviderConfiguration), + authProviderData); } } @@ -1867,16 +1863,13 @@ private SMAuthInfo getAuthStatus(@NotNull String authId, boolean readExpiredData } if (smAuthStatus != SMAuthStatus.SUCCESS) { - switch (smAuthStatus) { - case IN_PROGRESS: - return SMAuthInfo.inProgress(authId, signInLink, signOutLink, authData, isMainAuth, forceSessionsLogout); - case ERROR: - return SMAuthInfo.error(authId, authError, isMainAuth, errorCode); - case EXPIRED: - return SMAuthInfo.expired(authId, readExpiredData ? authData : Map.of(), isMainAuth); - default: - throw new SMException("Unknown auth status:" + smAuthStatus); - } + return switch (smAuthStatus) { + case IN_PROGRESS -> + SMAuthInfo.inProgress(authId, signInLink, signOutLink, authData, isMainAuth, forceSessionsLogout); + case ERROR -> SMAuthInfo.error(authId, authError, isMainAuth, errorCode); + case EXPIRED -> SMAuthInfo.expired(authId, readExpiredData ? authData : Map.of(), isMainAuth); + default -> throw new SMException("Unknown auth status:" + smAuthStatus); + }; } SMTokens smTokens = findTokenBySmSession(smSessionId); @@ -2260,10 +2253,9 @@ private void autoUpdateUserTeams( String userId, SMTeam[] allTeams ) throws DBCException { - if (!(authProvider.getInstance() instanceof SMAuthProviderAssigner)) { + if (!(authProvider.getInstance() instanceof SMAuthProviderAssigner authProviderAssigner)) { return; } - SMAuthProviderAssigner authProviderAssigner = (SMAuthProviderAssigner) authProvider.getInstance(); String externalTeamIdMetadataFieldName = authProviderAssigner.getExternalTeamIdMetadataFieldName(); if (!CommonUtils.isEmpty(externalTeamIdMetadataFieldName)) { @@ -2584,7 +2576,7 @@ private SMAuthPermissions getTokenPermissions(@NotNull String token) throws DBEx try (Connection dbCon = database.openConnection(); PreparedStatement dbStat = dbCon.prepareStatement( database.normalizeTableNames("SELECT USER_ID, EXPIRATION_TIME, SESSION_ID, AUTH_ROLE FROM {table_prefix}CB_AUTH_TOKEN " + - "WHERE TOKEN_ID=?")); + "WHERE TOKEN_ID=?")) ) { dbStat.setString(1, token); try (var dbResult = dbStat.executeQuery()) { @@ -2608,17 +2600,16 @@ private SMAuthPermissions getTokenPermissions(@NotNull String token) throws DBEx @Override public SMAuthProviderDescriptor[] getAvailableAuthProviders() throws DBException { - if (!(application.getAppConfiguration() instanceof WebAuthConfiguration)) { + if (!(application.getAppConfiguration() instanceof WebAuthConfiguration appConfiguration)) { throw new DBException("Web application doesn't support external authentication"); } - WebAuthConfiguration appConfiguration = (WebAuthConfiguration) application.getAppConfiguration(); Set customConfigurations = appConfiguration.getAuthCustomConfigurations(); List providers = WebAuthProviderRegistry.getInstance().getAuthProviders().stream() .filter(ap -> !ap.isTrusted() && appConfiguration.isAuthProviderEnabled(ap.getId()) && (!ap.isConfigurable() || hasProviderConfiguration(ap, customConfigurations))) - .map(WebAuthProviderDescriptor::createDescriptorBean).collect(Collectors.toList()); + .map(WebAuthProviderDescriptor::createDescriptorBean).toList(); if (!CommonUtils.isEmpty(customConfigurations)) { // Attach custom configs to providers @@ -3009,12 +3000,12 @@ public List getObjectPermissionGrants( var grantedPermissionsBySubjectId = new HashMap(); try (Connection dbCon = database.openConnection()) { try (PreparedStatement dbStat = dbCon.prepareStatement(database.normalizeTableNames( - "SELECT OP.SUBJECT_ID,S.SUBJECT_TYPE, OP.PERMISSION\n" + - "FROM {table_prefix}CB_OBJECT_PERMISSIONS OP, {table_prefix}CB_AUTH_SUBJECT S\n" + - "WHERE S.SUBJECT_ID = OP.SUBJECT_ID AND OP.OBJECT_TYPE=? AND OP.OBJECT_ID=?"))) { + """ + SELECT OP.SUBJECT_ID,S.SUBJECT_TYPE, OP.PERMISSION + FROM {table_prefix}CB_OBJECT_PERMISSIONS OP, {table_prefix}CB_AUTH_SUBJECT S + WHERE S.SUBJECT_ID = OP.SUBJECT_ID AND OP.OBJECT_TYPE=? AND OP.OBJECT_ID=?"""))) { dbStat.setString(1, smObjectType.name()); dbStat.setString(2, objectId); - List result = new ArrayList<>(); try (ResultSet dbResult = dbStat.executeQuery()) { while (dbResult.next()) { String subjectId = dbResult.getString(1); @@ -3211,11 +3202,10 @@ public void clearOldAuthAttemptInfo() throws DBException { public Set getFilteredSubjects(Set allSubjects) { try (Connection dbCon = database.openConnection()) { Set result = new HashSet<>(); - var sqlBuilder = new StringBuilder("SELECT SUBJECT_ID FROM {table_prefix}CB_AUTH_SUBJECT U ") - .append("WHERE SUBJECT_ID IN (") - .append(SQLUtils.generateParamList(allSubjects.size())) - .append(")"); - try (var dbStat = dbCon.prepareStatement(database.normalizeTableNames(sqlBuilder.toString()))) { + String sqlBuilder = + "SELECT SUBJECT_ID FROM {table_prefix}CB_AUTH_SUBJECT U " + + "WHERE SUBJECT_ID IN (" + SQLUtils.generateParamList(allSubjects.size()) + ")"; + try (var dbStat = dbCon.prepareStatement(database.normalizeTableNames(sqlBuilder))) { int parameterIndex = 1; for (String subjectId : allSubjects) { dbStat.setString(parameterIndex++, subjectId); @@ -3235,7 +3225,6 @@ public Set getFilteredSubjects(Set allSubjects) { private SMSubjectType getSubjectType(@NotNull String subjectId) { try (Connection dbCon = database.openConnection()) { - Set result = new HashSet<>(); String sqlBuilder = "SELECT SUBJECT_TYPE FROM {table_prefix}CB_AUTH_SUBJECT U WHERE SUBJECT_ID = ?"; try (var dbStat = dbCon.prepareStatement(database.normalizeTableNames(sqlBuilder))) { dbStat.setString(1, subjectId); From efb42d33a72854cc643a628cbc4c7f63f3acf5b8 Mon Sep 17 00:00:00 2001 From: Alexander Skoblikov Date: Thu, 19 Sep 2024 12:14:23 +0300 Subject: [PATCH 4/5] Dbeaver/dbeaver vscode#3 remove redundunt plugins (#2891) * CB-5530 wip * dbeaver-vscode#3 cleanup servlets * dbeaver-vscode#3 endpoint fixes * dbeaver-vscode#3 resolve conflicts * dbeaver-vscode#3 fix conflict * dbeaver-vscode# jetty 12 conflict fixes * dbeaver-vscode#3 servlets filter --------- Co-authored-by: mr-anton-t <42037741+mr-anton-t@users.noreply.github.com> --- .../io.cloudbeaver.model/META-INF/MANIFEST.MF | 1 + .../BaseServerConfigurationController.java | 2 + .../model/app/BaseWebApplication.java | 1 - .../model/session/BaseWebSession.java | 9 +- .../cloudbeaver/model/session/WebSession.java | 20 +++ .../model/session/WebUserContext.java | 1 + .../registry/WebDriverRegistry.java | 0 .../cloudbeaver/server/BaseGQLPlatform.java | 147 ++++++++++++++++++ .../service/DBWServiceBindingServlet.java | 3 + .../META-INF/MANIFEST.MF | 3 + .../model/user/WebAuthProviderInfo.java | 6 +- .../server/AppWebSessionManager.java | 64 ++++++++ .../io/cloudbeaver/server/CBApplication.java | 3 +- .../src/io/cloudbeaver/server/CBPlatform.java | 134 +++------------- .../cloudbeaver/server/CBPreferenceStore.java | 4 - .../server/GQLApplicationAdapter.java | 44 ++++++ .../server/events/WSUserEventHandler.java | 6 +- .../server/graphql/GraphQLEndpoint.java | 6 +- .../server/jetty/CBJettyServer.java | 30 ++-- .../server/jetty/CBSessionHandler.java | 6 +- .../server/jobs/PeriodicSystemJob.java | 6 +- .../server/jobs/SessionStateJob.java | 9 +- .../server/jobs/WebDataSourceMonitorJob.java | 11 +- .../server/jobs/WebSessionMonitorJob.java | 9 +- .../server/servlets/CBStatusServlet.java | 3 +- .../websockets/CBJettyWebSocketManager.java | 6 +- .../service/WebServiceBindingBase.java | 3 +- .../service/WebServiceServletBase.java | 23 ++- .../service/core/WebServiceBindingCore.java | 3 +- .../service/core/impl/WebServiceCore.java | 3 +- .../service/session/WebSessionManager.java | 22 ++- .../service/sql/WebSQLFileLoaderServlet.java | 3 +- .../service/sql/WebSQLResultServlet.java | 3 +- .../service/sql/WebServiceBindingSQL.java | 10 +- .../service/admin/WebServiceBindingAdmin.java | 3 + .../WebServiceBindingDataTransfer.java | 3 + .../service/fs/WebServiceBindingFS.java | 3 + 37 files changed, 439 insertions(+), 174 deletions(-) rename server/bundles/{io.cloudbeaver.server => io.cloudbeaver.model}/src/io/cloudbeaver/registry/WebDriverRegistry.java (100%) create mode 100644 server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/server/BaseGQLPlatform.java create mode 100644 server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/AppWebSessionManager.java create mode 100644 server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/GQLApplicationAdapter.java diff --git a/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF index 226b75a8b0..531c58d95b 100644 --- a/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF +++ b/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF @@ -30,6 +30,7 @@ Export-Package: io.cloudbeaver, io.cloudbeaver.model, io.cloudbeaver.model.app, io.cloudbeaver.model.fs, + io.cloudbeaver.model.log, io.cloudbeaver.model.rm, io.cloudbeaver.model.rm.local, io.cloudbeaver.model.rm.lock, diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/app/BaseServerConfigurationController.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/app/BaseServerConfigurationController.java index 6ea3bcea9d..516ef29e2a 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/app/BaseServerConfigurationController.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/app/BaseServerConfigurationController.java @@ -18,6 +18,7 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import org.jkiss.code.NotNull; /** * Abstract class that contains methods for loading configuration with gson. @@ -25,6 +26,7 @@ public abstract class BaseServerConfigurationController implements WebServerConfigurationController { + @NotNull public Gson getGson() { return getGsonBuilder().create(); } diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/app/BaseWebApplication.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/app/BaseWebApplication.java index a23a02823d..0517fef9b1 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/app/BaseWebApplication.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/app/BaseWebApplication.java @@ -59,7 +59,6 @@ public abstract class BaseWebApplication extends BaseApplicationImpl implements public static final String CLI_PARAM_WEB_CONFIG = "-web-config"; public static final String LOGBACK_FILE_NAME = "logback.xml"; - private static final Log log = Log.getLog(BaseWebApplication.class); private String instanceId; diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/BaseWebSession.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/BaseWebSession.java index 9f51137716..8d516be802 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/BaseWebSession.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/BaseWebSession.java @@ -51,14 +51,14 @@ public abstract class BaseWebSession extends AbstractSessionPersistent { @NotNull protected final WebUserContext userContext; @NotNull - protected final WebAuthApplication application; + protected final WebApplication application; protected volatile long lastAccessTime; private final List sessionEventHandlers = new CopyOnWriteArrayList<>(); private WebSessionEventsFilter eventsFilter = new WebSessionEventsFilter(); private final WebSessionWorkspace workspace; - public BaseWebSession(@NotNull String id, @NotNull WebAuthApplication application) throws DBException { + public BaseWebSession(@NotNull String id, @NotNull WebApplication application) throws DBException { this.id = id; this.application = application; this.createTime = System.currentTimeMillis(); @@ -232,6 +232,9 @@ public boolean isValid() { @Property public long getRemainingTime() { - return application.getMaxSessionIdleTime() + lastAccessTime - System.currentTimeMillis(); + if (application instanceof WebAuthApplication authApplication) { + return authApplication.getMaxSessionIdleTime() + lastAccessTime - System.currentTimeMillis(); + } + return Integer.MAX_VALUE; } } 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 bf0bc809c9..42c1d5c122 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 @@ -26,6 +26,7 @@ import io.cloudbeaver.model.WebAsyncTaskInfo; import io.cloudbeaver.model.WebConnectionInfo; import io.cloudbeaver.model.WebServerMessage; +import io.cloudbeaver.model.app.WebApplication; import io.cloudbeaver.model.app.WebAuthApplication; import io.cloudbeaver.model.user.WebUser; import io.cloudbeaver.service.DBWSessionHandler; @@ -88,6 +89,7 @@ * Web session. * Is the main source of data in web application */ +//TODO: split to authenticated and non authenticated context public class WebSession extends BaseWebSession implements SMSessionWithAuth, SMCredentialsProvider, DBACredentialsProvider, IAdaptable { @@ -140,6 +142,24 @@ public WebSession( updateSessionParameters(requestInfo); } + protected WebSession( + @NotNull String id, + @Nullable String locale, + @NotNull WebApplication application, + @NotNull Map sessionHandlers + ) throws DBException { + super(id, application); + this.lastAccessTime = this.createTime; + this.sessionHandlers = sessionHandlers; + setLocale(locale); + //force authorization of anonymous session to avoid access error, + //because before authorization could be called by any request, + //but now 'updateInfo' is called only in special requests, + //and the order of requests is not guaranteed. + //look at CB-4747 + refreshSessionAuth(); + } + @Nullable @Override public SMSessionPrincipal getSessionPrincipal() { diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebUserContext.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebUserContext.java index 08d2b06eaf..f94462297b 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebUserContext.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebUserContext.java @@ -46,6 +46,7 @@ * Web user context. * Contains user state and services based on available permissions */ +//TODO: split to authenticated and non authenticated context public class WebUserContext implements SMCredentialsProvider { private static final Log log = Log.getLog(WebUserContext.class); diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/registry/WebDriverRegistry.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebDriverRegistry.java similarity index 100% rename from server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/registry/WebDriverRegistry.java rename to server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebDriverRegistry.java diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/server/BaseGQLPlatform.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/server/BaseGQLPlatform.java new file mode 100644 index 0000000000..ca5d26fd6a --- /dev/null +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/server/BaseGQLPlatform.java @@ -0,0 +1,147 @@ +/* + * 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.server; + +import io.cloudbeaver.DBWConstants; +import org.eclipse.core.runtime.Plugin; +import org.jkiss.code.NotNull; +import org.jkiss.dbeaver.Log; +import org.jkiss.dbeaver.model.DBConstants; +import org.jkiss.dbeaver.model.app.DBACertificateStorage; +import org.jkiss.dbeaver.model.app.DBPWorkspace; +import org.jkiss.dbeaver.model.impl.app.DefaultCertificateStorage; +import org.jkiss.dbeaver.model.qm.QMRegistry; +import org.jkiss.dbeaver.model.qm.QMUtils; +import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; +import org.jkiss.dbeaver.registry.BasePlatformImpl; +import org.jkiss.dbeaver.registry.DataSourceProviderRegistry; +import org.jkiss.dbeaver.runtime.SecurityProviderUtils; +import org.jkiss.dbeaver.runtime.qm.QMLogFileWriter; +import org.jkiss.dbeaver.runtime.qm.QMRegistryImpl; +import org.jkiss.dbeaver.utils.ContentUtils; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +public abstract class BaseGQLPlatform extends BasePlatformImpl { + private static final Log log = Log.getLog(BaseGQLPlatform.class); + public static final String WORK_DATA_FOLDER_NAME = ".work-data"; + + private Path tempFolder; + + private QMRegistryImpl queryManager; + private QMLogFileWriter qmLogWriter; + private DBACertificateStorage certificateStorage; + private WebGlobalWorkspace workspace; + + @Override + protected synchronized void initialize() { + // Register BC security provider + SecurityProviderUtils.registerSecurityProvider(); + + // Register properties adapter + this.workspace = new WebGlobalWorkspace(this); + this.workspace.initializeProjects(); + QMUtils.initApplication(this); + + this.queryManager = new QMRegistryImpl(); + + this.qmLogWriter = new QMLogFileWriter(); + this.queryManager.registerMetaListener(qmLogWriter); + + this.certificateStorage = new DefaultCertificateStorage( + WebPlatformActivator.getInstance() + .getStateLocation() + .toFile() + .toPath() + .resolve(DBConstants.CERTIFICATE_STORAGE_FOLDER)); + super.initialize(); + } + + @Override + protected Plugin getProductPlugin() { + return WebPlatformActivator.getInstance(); + } + + @NotNull + @Override + public DBACertificateStorage getCertificateStorage() { + return certificateStorage; + } + + @NotNull + @Override + public DBPWorkspace getWorkspace() { + return workspace; + } + + @NotNull + public Path getTempFolder(@NotNull DBRProgressMonitor monitor, @NotNull String name) { + if (tempFolder == null) { + // Make temp folder + monitor.subTask("Create temp folder"); + tempFolder = workspace.getAbsolutePath().resolve(DBWConstants.WORK_DATA_FOLDER_NAME); + } + if (!Files.exists(tempFolder)) { + try { + Files.createDirectories(tempFolder); + } catch (IOException e) { + log.error("Can't create temp directory " + tempFolder, e); + } + } + Path folder = tempFolder.resolve(name); + if (!Files.exists(folder)) { + try { + Files.createDirectories(folder); + } catch (IOException e) { + log.error("Error creating temp folder '" + folder.toAbsolutePath() + "'", e); + } + } + return folder; + } + + @Override + public synchronized void dispose() { + super.dispose(); + if (this.qmLogWriter != null) { + this.queryManager.unregisterMetaListener(qmLogWriter); + this.qmLogWriter.dispose(); + this.qmLogWriter = null; + } + if (this.queryManager != null) { + this.queryManager.dispose(); + //queryManager = null; + } + DataSourceProviderRegistry.dispose(); + + // Remove temp folder + if (tempFolder != null) { + + if (!ContentUtils.deleteFileRecursive(tempFolder.toFile())) { + log.warn("Can't delete temp folder '" + tempFolder.toAbsolutePath() + "'"); + } + tempFolder = null; + } + } + + @NotNull + public QMRegistry getQueryManager() { + return queryManager; + } + +} diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/service/DBWServiceBindingServlet.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/service/DBWServiceBindingServlet.java index 1018ee3037..5b7e52cc95 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/service/DBWServiceBindingServlet.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/service/DBWServiceBindingServlet.java @@ -23,6 +23,9 @@ * Servlet service */ public interface DBWServiceBindingServlet extends DBWServiceBinding { + default boolean isApplicable(WebApplication application) { + return true; + } void addServlets(APPLICATION application, DBWServletContext servletContext) throws DBException; } diff --git a/server/bundles/io.cloudbeaver.server/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.server/META-INF/MANIFEST.MF index 93455b8266..9f073c8022 100644 --- a/server/bundles/io.cloudbeaver.server/META-INF/MANIFEST.MF +++ b/server/bundles/io.cloudbeaver.server/META-INF/MANIFEST.MF @@ -28,8 +28,11 @@ Export-Package: io.cloudbeaver, io.cloudbeaver.server.events, io.cloudbeaver.server, io.cloudbeaver.server.actions, + io.cloudbeaver.server.jetty, + io.cloudbeaver.server.graphql, io.cloudbeaver.server.jobs, io.cloudbeaver.server.servlets, + io.cloudbeaver.server.websockets, io.cloudbeaver.service, io.cloudbeaver.service.navigator, io.cloudbeaver.service.session, diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/user/WebAuthProviderInfo.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/user/WebAuthProviderInfo.java index c3c211c970..e50916d9e6 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/user/WebAuthProviderInfo.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/user/WebAuthProviderInfo.java @@ -21,6 +21,7 @@ import io.cloudbeaver.auth.provisioning.SMProvisioner; import io.cloudbeaver.registry.WebAuthProviderConfiguration; import io.cloudbeaver.registry.WebAuthProviderDescriptor; +import io.cloudbeaver.server.CBAppConfig; import io.cloudbeaver.server.CBApplication; import io.cloudbeaver.server.CBPlatform; import org.jkiss.dbeaver.Log; @@ -64,7 +65,10 @@ public String getDescription() { } public boolean isDefaultProvider() { - return descriptor.getId().equals(CBPlatform.getInstance().getApplication().getAppConfiguration().getDefaultAuthProvider()); + if (CBPlatform.getInstance().getApplication().getAppConfiguration() instanceof CBAppConfig cbAppConfig) { + return descriptor.getId().equals(cbAppConfig.getDefaultAuthProvider()); + } + return false; } public boolean isConfigurable() { diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/AppWebSessionManager.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/AppWebSessionManager.java new file mode 100644 index 0000000000..13cfc7796a --- /dev/null +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/AppWebSessionManager.java @@ -0,0 +1,64 @@ +/* + * 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.server; + +import io.cloudbeaver.DBWebException; +import io.cloudbeaver.model.session.BaseWebSession; +import io.cloudbeaver.model.session.WebHeadlessSession; +import io.cloudbeaver.model.session.WebSession; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Session; +import org.jkiss.code.NotNull; +import org.jkiss.code.Nullable; +import org.jkiss.dbeaver.DBException; + +import java.util.Collection; + +public interface AppWebSessionManager { + BaseWebSession closeSession(@NotNull HttpServletRequest request); + + @NotNull + WebSession getWebSession( + @NotNull HttpServletRequest request, + @NotNull HttpServletResponse response + ) throws DBWebException; + + @NotNull + WebSession getWebSession( + @NotNull HttpServletRequest request, + @NotNull HttpServletResponse response, + boolean errorOnNoFound + ) throws DBWebException; + + @Nullable + BaseWebSession getSession(@NotNull String sessionId); + + @Nullable + WebSession findWebSession(HttpServletRequest request); + + WebSession findWebSession(HttpServletRequest request, boolean errorOnNoFound) throws DBWebException; + + Collection getAllActiveSessions(); + + WebSession getOrRestoreSession(Request httpRequest); + + WebHeadlessSession getHeadlessSession(Request request, Session session, boolean create) throws DBException; + + boolean touchSession(HttpServletRequest request, HttpServletResponse response) throws DBWebException; +} 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 9ab8930088..a5bff0eace 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 @@ -74,7 +74,8 @@ /** * This class controls all aspects of the application's execution */ -public abstract class CBApplication extends BaseWebApplication implements WebAuthApplication { +public abstract class CBApplication extends + BaseWebApplication implements WebAuthApplication, GQLApplicationAdapter { private static final Log log = Log.getLog(CBApplication.class); 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 68199270c5..1c4e0fadd5 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 @@ -17,43 +17,29 @@ package io.cloudbeaver.server; -import io.cloudbeaver.DBWConstants; import io.cloudbeaver.auth.NoAuthCredentialsProvider; import io.cloudbeaver.server.jobs.SessionStateJob; import io.cloudbeaver.server.jobs.WebDataSourceMonitorJob; import io.cloudbeaver.server.jobs.WebSessionMonitorJob; import io.cloudbeaver.service.session.WebSessionManager; import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Plugin; import org.eclipse.core.runtime.Status; import org.jkiss.code.NotNull; import org.jkiss.code.Nullable; import org.jkiss.dbeaver.Log; -import org.jkiss.dbeaver.model.DBConstants; import org.jkiss.dbeaver.model.DBFileController; -import org.jkiss.dbeaver.model.app.DBACertificateStorage; -import org.jkiss.dbeaver.model.app.DBPWorkspace; import org.jkiss.dbeaver.model.connection.DBPDataSourceProviderDescriptor; import org.jkiss.dbeaver.model.connection.DBPDriver; import org.jkiss.dbeaver.model.connection.DBPDriverLibrary; -import org.jkiss.dbeaver.model.impl.app.DefaultCertificateStorage; import org.jkiss.dbeaver.model.preferences.DBPPreferenceStore; -import org.jkiss.dbeaver.model.qm.QMRegistry; -import org.jkiss.dbeaver.model.qm.QMUtils; import org.jkiss.dbeaver.model.runtime.AbstractJob; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; -import org.jkiss.dbeaver.registry.BasePlatformImpl; import org.jkiss.dbeaver.registry.DataSourceProviderRegistry; import org.jkiss.dbeaver.runtime.DBWorkbench; -import org.jkiss.dbeaver.runtime.SecurityProviderUtils; -import org.jkiss.dbeaver.runtime.qm.QMLogFileWriter; -import org.jkiss.dbeaver.runtime.qm.QMRegistryImpl; -import org.jkiss.dbeaver.utils.ContentUtils; import org.jkiss.utils.IOUtils; import java.io.IOException; import java.nio.file.Files; -import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -61,7 +47,7 @@ /** * CBPlatform */ -public class CBPlatform extends BasePlatformImpl { +public class CBPlatform extends BaseGQLPlatform { // The plug-in ID public static final String PLUGIN_ID = "io.cloudbeaver.server"; //$NON-NLS-1$ @@ -71,25 +57,19 @@ public class CBPlatform extends BasePlatformImpl { public static final String TEMP_FILE_IMPORT_FOLDER = "temp-import-files"; @Nullable - private static CBApplication application = null; + private static GQLApplicationAdapter application = null; - private Path tempFolder; - - private QMRegistryImpl queryManager; - private QMLogFileWriter qmLogWriter; - private DBACertificateStorage certificateStorage; - private WebGlobalWorkspace workspace; private CBPreferenceStore preferenceStore; - private final List applicableDrivers = new ArrayList<>(); + protected final List applicableDrivers = new ArrayList<>(); public static CBPlatform getInstance() { return (CBPlatform) DBWorkbench.getPlatform(); } - CBPlatform() { + protected CBPlatform() { } - public static void setApplication(CBApplication application) { + public static void setApplication(@NotNull GQLApplicationAdapter application) { CBPlatform.application = application; } @@ -98,32 +78,23 @@ protected synchronized void initialize() { long startTime = System.currentTimeMillis(); log.info("Initialize web platform...: "); this.preferenceStore = new CBPreferenceStore(this, WebPlatformActivator.getInstance().getPreferences()); - // Register BC security provider - SecurityProviderUtils.registerSecurityProvider(); - - // Register properties adapter - this.workspace = new WebGlobalWorkspace(this); - this.workspace.initializeProjects(); - - QMUtils.initApplication(this); - this.queryManager = new QMRegistryImpl(); - - this.qmLogWriter = new QMLogFileWriter(); - this.queryManager.registerMetaListener(qmLogWriter); - - this.certificateStorage = new DefaultCertificateStorage( - WebPlatformActivator.getInstance().getStateLocation().toFile().toPath().resolve(DBConstants.CERTIFICATE_STORAGE_FOLDER)); super.initialize(); - refreshApplicableDrivers(); - new WebSessionMonitorJob(this) - .scheduleMonitor(); + scheduleServerJobs(); + log.info("Web platform initialized (" + (System.currentTimeMillis() - startTime) + "ms)"); + } - new SessionStateJob(this) - .scheduleMonitor(); + protected void scheduleServerJobs() { + if (getSessionManager() instanceof WebSessionManager webSessionManager) { + new WebSessionMonitorJob(this, webSessionManager) + .scheduleMonitor(); - new WebDataSourceMonitorJob(this) + new SessionStateJob(this, webSessionManager) + .scheduleMonitor(); + } + + new WebDataSourceMonitorJob(this, getSessionManager()) .scheduleMonitor(); new AbstractJob("Delete temp folder") { @@ -138,7 +109,6 @@ protected IStatus run(DBRProgressMonitor monitor) { return Status.OK_STATUS; } }.schedule(); - log.info("Web platform initialized (" + (System.currentTimeMillis() - startTime) + "ms)"); } public synchronized void dispose() { @@ -147,26 +117,6 @@ public synchronized void dispose() { super.dispose(); - if (this.qmLogWriter != null) { - this.queryManager.unregisterMetaListener(qmLogWriter); - this.qmLogWriter.dispose(); - this.qmLogWriter = null; - } - if (this.queryManager != null) { - this.queryManager.dispose(); - //queryManager = null; - } - DataSourceProviderRegistry.dispose(); - - // Remove temp folder - if (tempFolder != null) { - - if (!ContentUtils.deleteFileRecursive(tempFolder.toFile())) { - log.warn("Can't delete temp folder '" + tempFolder.toAbsolutePath() + "'"); - } - tempFolder = null; - } - CBPlatform.application = null; System.gc(); log.debug("Shutdown completed in " + (System.currentTimeMillis() - startTime) + "ms"); @@ -174,13 +124,7 @@ public synchronized void dispose() { @NotNull @Override - public DBPWorkspace getWorkspace() { - return workspace; - } - - @NotNull - @Override - public CBApplication getApplication() { + public GQLApplicationAdapter getApplication() { return application; } @@ -188,10 +132,6 @@ public List getApplicableDrivers() { return applicableDrivers; } - @NotNull - public QMRegistry getQueryManager() { - return queryManager; - } @NotNull @Override @@ -199,48 +139,12 @@ public DBPPreferenceStore getPreferenceStore() { return preferenceStore; } - @NotNull - @Override - public DBACertificateStorage getCertificateStorage() { - return certificateStorage; - } - - @NotNull - public Path getTempFolder(@NotNull DBRProgressMonitor monitor, @NotNull String name) { - if (tempFolder == null) { - // Make temp folder - monitor.subTask("Create temp folder"); - tempFolder = workspace.getAbsolutePath().resolve(DBWConstants.WORK_DATA_FOLDER_NAME); - } - if (!Files.exists(tempFolder)) { - try { - Files.createDirectories(tempFolder); - } catch (IOException e) { - log.error("Can't create temp directory " + tempFolder, e); - } - } - Path folder = tempFolder.resolve(name); - if (!Files.exists(folder)) { - try { - Files.createDirectories(folder); - } catch (IOException e) { - log.error("Error creating temp folder '" + folder.toAbsolutePath() + "'", e); - } - } - return folder; - } - - @Override - protected Plugin getProductPlugin() { - return WebPlatformActivator.getInstance(); - } - @Override public boolean isShuttingDown() { return false; } - public WebSessionManager getSessionManager() { + public AppWebSessionManager getSessionManager() { return application.getSessionManager(); } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBPreferenceStore.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBPreferenceStore.java index 09c98a86cb..a40bf64584 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBPreferenceStore.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBPreferenceStore.java @@ -187,10 +187,6 @@ public void save() throws IOException { throw new RuntimeException("Not Implemented"); } - public CBApplication getApp() { - return cbPlatform.getApplication(); - } - private Map productConf() { var app = cbPlatform.getApplication(); return app.getProductConfiguration(); diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/GQLApplicationAdapter.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/GQLApplicationAdapter.java new file mode 100644 index 0000000000..f747216547 --- /dev/null +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/GQLApplicationAdapter.java @@ -0,0 +1,44 @@ +/* + * 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.server; + +import io.cloudbeaver.model.app.WebApplication; +import io.cloudbeaver.registry.WebDriverRegistry; +import org.jkiss.code.NotNull; + +import java.net.InetAddress; +import java.util.List; +import java.util.Map; + +//FIXME: this interface should not exist, +// the logic of platforms and applications should be separated from each other +public interface GQLApplicationAdapter extends WebApplication { + AppWebSessionManager getSessionManager(); + + WebDriverRegistry getDriverRegistry(); + + @NotNull + Map getProductConfiguration(); + + List getLocalInetAddresses(); + + Map getInitActions(); + + boolean isLicenseValid(); + + String getLicenseStatus(); +} diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/WSUserEventHandler.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/WSUserEventHandler.java index 4188468da5..14dc4cdb76 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/WSUserEventHandler.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/WSUserEventHandler.java @@ -32,7 +32,11 @@ public void handleEvent(@NotNull EVENT event) { if (eventType == null) { return; } - WebSessionManager sessionManager = CBPlatform.getInstance().getSessionManager(); + var appSessionManager = CBPlatform.getInstance().getSessionManager(); + if (!(appSessionManager instanceof WebSessionManager)) { + return; + } + var sessionManager = (WebSessionManager) appSessionManager; switch (eventType) { case CLOSE_USER_SESSIONS: if (event instanceof WSUserCloseSessionsEvent closeSessionsEvent) { diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLEndpoint.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLEndpoint.java index c3d9bf0f91..b004e7e80d 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLEndpoint.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLEndpoint.java @@ -32,10 +32,12 @@ import io.cloudbeaver.model.session.WebSession; import io.cloudbeaver.registry.WebServiceRegistry; import io.cloudbeaver.server.CBApplication; +import io.cloudbeaver.server.CBPlatform; import io.cloudbeaver.server.HttpConstants; import io.cloudbeaver.service.DBWBindingContext; import io.cloudbeaver.service.DBWServiceBindingGraphQL; import io.cloudbeaver.service.WebServiceBindingBase; +import io.cloudbeaver.utils.WebAppUtils; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; @@ -124,7 +126,7 @@ protected void doOptions(HttpServletRequest request, HttpServletResponse respons } private void setDevelHeaders(HttpServletRequest request, HttpServletResponse response) { - if (CBApplication.getInstance().isDevelMode()) { + if (WebAppUtils.getWebApplication().getServerConfiguration().isDevelMode()) { // response.setHeader(HEADER_ACCESS_CONTROL_ALLOW_ORIGIN, "*"); // response.setHeader(HEADER_ACCESS_CONTROL_ALLOW_HEADERS, "*"); // response.setHeader(HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS, "*"); @@ -211,7 +213,7 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t if (path == null) { path = request.getServletPath(); } - boolean develMode = CBApplication.getInstance().isDevelMode(); + boolean develMode = WebAppUtils.getWebApplication().getServerConfiguration().isDevelMode(); if (path.contentEquals("/schema.json") && develMode) { executeQuery(request, response, GraphQLConstants.SCHEMA_READ_QUERY, null, null); diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBJettyServer.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBJettyServer.java index ddf67a7d43..ac37138be0 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBJettyServer.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBJettyServer.java @@ -16,6 +16,7 @@ */ package io.cloudbeaver.server.jetty; +import io.cloudbeaver.server.GQLApplicationAdapter; import io.cloudbeaver.registry.WebServiceRegistry; import io.cloudbeaver.server.CBApplication; import io.cloudbeaver.server.CBServerConfig; @@ -117,11 +118,15 @@ public void runServer() { // Add extensions from services CBJettyServletContext servletContext = new CBJettyServletContext(servletContextHandler); - for (DBWServiceBindingServlet wsd : WebServiceRegistry.getInstance().getWebServices(DBWServiceBindingServlet.class)) { - try { - wsd.addServlets(this.application, servletContext); - } catch (DBException e) { - log.error(e.getMessage(), e); + for (DBWServiceBindingServlet wsd : WebServiceRegistry.getInstance() + .getWebServices(DBWServiceBindingServlet.class) + ) { + if (wsd.isApplicable(this.application)) { + try { + wsd.addServlets(this.application, servletContext); + } catch (DBException e) { + log.error(e.getMessage(), e); + } } } @@ -136,7 +141,12 @@ public void runServer() { ); servletContextHandler.insertHandler(webSocketHandler); - initSessionManager(this.application, server, servletContextHandler); + initSessionManager( + this.application.getMaxSessionIdleTime(), + this.application, + server, + servletContextHandler + ); server.setHandler(servletContextHandler); @@ -184,14 +194,14 @@ private Path getSslConfigurationPath() { return sslConfiguration.isAbsolute() ? sslConfiguration : application.getHomeDirectory().resolve(sslConfiguration); } - private void initSessionManager( - @NotNull CBApplication application, + public static void initSessionManager( + long maxIdleTime, + @NotNull GQLApplicationAdapter application, @NotNull Server server, @NotNull ServletContextHandler servletContextHandler ) { // Init sessions persistence - SessionHandler sessionHandler = new SessionHandler(); - var maxIdleTime = application.getMaxSessionIdleTime(); + CBSessionHandler sessionHandler = new CBSessionHandler(application); int intMaxIdleSeconds; if (maxIdleTime > Integer.MAX_VALUE) { log.warn("Max session idle time value is greater than Integer.MAX_VALUE. Integer.MAX_VALUE will be used instead"); diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBSessionHandler.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBSessionHandler.java index 907c9e3758..6fa6d0f7b8 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBSessionHandler.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBSessionHandler.java @@ -16,7 +16,7 @@ */ package io.cloudbeaver.server.jetty; -import io.cloudbeaver.server.CBApplication; +import io.cloudbeaver.server.GQLApplicationAdapter; import jakarta.servlet.SessionCookieConfig; import org.eclipse.jetty.ee10.servlet.ServletContextHandler; import org.eclipse.jetty.ee10.servlet.SessionHandler; @@ -28,9 +28,9 @@ public class CBSessionHandler extends SessionHandler { private final CBCookieConfig cbCookieConfig; - private final CBApplication application; + private final GQLApplicationAdapter application; - public CBSessionHandler(CBApplication application) { + public CBSessionHandler(GQLApplicationAdapter application) { this.cbCookieConfig = new CBCookieConfig(); this.application = application; } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jobs/PeriodicSystemJob.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jobs/PeriodicSystemJob.java index 053749b7d8..15d4de80d8 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jobs/PeriodicSystemJob.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jobs/PeriodicSystemJob.java @@ -16,20 +16,20 @@ */ package io.cloudbeaver.server.jobs; -import io.cloudbeaver.server.CBPlatform; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.jkiss.code.NotNull; +import org.jkiss.dbeaver.model.app.DBPPlatform; import org.jkiss.dbeaver.model.runtime.AbstractJob; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; public abstract class PeriodicSystemJob extends AbstractJob { @NotNull - protected final CBPlatform platform; + protected final DBPPlatform platform; private final long periodMs; - public PeriodicSystemJob(@NotNull String name, @NotNull CBPlatform platform, long periodMs) { + public PeriodicSystemJob(@NotNull String name, @NotNull DBPPlatform platform, long periodMs) { super(name); this.platform = platform; this.periodMs = periodMs; diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jobs/SessionStateJob.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jobs/SessionStateJob.java index 5f2d9a6eaa..354934ebc4 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jobs/SessionStateJob.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jobs/SessionStateJob.java @@ -16,23 +16,26 @@ */ package io.cloudbeaver.server.jobs; -import io.cloudbeaver.server.CBPlatform; +import io.cloudbeaver.service.session.WebSessionManager; import org.jkiss.code.NotNull; import org.jkiss.dbeaver.Log; +import org.jkiss.dbeaver.model.app.DBPPlatform; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; public class SessionStateJob extends PeriodicSystemJob { private static final Log log = Log.getLog(SessionStateJob.class); private static final int PERIOD_MS = 30_000; // once per 30 seconds + private final WebSessionManager sessionManager; - public SessionStateJob(@NotNull CBPlatform platform) { + public SessionStateJob(@NotNull DBPPlatform platform, WebSessionManager sessionManager) { super("Session state sender", platform, PERIOD_MS); + this.sessionManager = sessionManager; } @Override protected void doJob(@NotNull DBRProgressMonitor monitor) { try { - platform.getSessionManager().sendSessionsStates(); + sessionManager.sendSessionsStates(); } catch (Exception e) { log.error("Error sending session state", e); } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jobs/WebDataSourceMonitorJob.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jobs/WebDataSourceMonitorJob.java index 5a244b6156..961bf38ce6 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jobs/WebDataSourceMonitorJob.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jobs/WebDataSourceMonitorJob.java @@ -16,9 +16,9 @@ */ package io.cloudbeaver.server.jobs; +import io.cloudbeaver.server.AppWebSessionManager; import io.cloudbeaver.model.session.BaseWebSession; import io.cloudbeaver.model.session.WebSession; -import io.cloudbeaver.server.CBPlatform; import org.jkiss.code.NotNull; import org.jkiss.dbeaver.model.DBPDataSource; import org.jkiss.dbeaver.model.app.DBPPlatform; @@ -34,14 +34,19 @@ * Web data source monitor job. */ public class WebDataSourceMonitorJob extends DataSourceMonitorJob { + private final AppWebSessionManager sessionManager; - public WebDataSourceMonitorJob(DBPPlatform platform) { + public WebDataSourceMonitorJob( + @NotNull DBPPlatform platform, + @NotNull AppWebSessionManager sessionManager + ) { super(platform); + this.sessionManager = sessionManager; } @Override protected void doJob() { - Collection allSessions = CBPlatform.getInstance().getSessionManager().getAllActiveSessions(); + Collection allSessions = sessionManager.getAllActiveSessions(); allSessions.parallelStream().forEach(s -> { checkDataSourceAliveInWorkspace(s.getWorkspace(), s.getLastAccessTimeMillis()); }); diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jobs/WebSessionMonitorJob.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jobs/WebSessionMonitorJob.java index 11fc79c569..c17dc270f4 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jobs/WebSessionMonitorJob.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jobs/WebSessionMonitorJob.java @@ -16,9 +16,10 @@ */ package io.cloudbeaver.server.jobs; -import io.cloudbeaver.server.CBPlatform; +import io.cloudbeaver.service.session.WebSessionManager; import org.jkiss.code.NotNull; import org.jkiss.dbeaver.Log; +import org.jkiss.dbeaver.model.app.DBPPlatform; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; /** @@ -27,15 +28,17 @@ public class WebSessionMonitorJob extends PeriodicSystemJob { private static final Log log = Log.getLog(WebSessionMonitorJob.class); private static final int MONITOR_INTERVAL = 10000; // once per 10 seconds + private final WebSessionManager sessionManager; - public WebSessionMonitorJob(@NotNull CBPlatform platform) { + public WebSessionMonitorJob(@NotNull DBPPlatform platform, @NotNull WebSessionManager sessionManager) { super("Web session monitor", platform, MONITOR_INTERVAL); + this.sessionManager = sessionManager; } @Override protected void doJob(@NotNull DBRProgressMonitor monitor) { try { - platform.getSessionManager().expireIdleSessions(); + sessionManager.expireIdleSessions(); } catch (Exception e) { log.error("Error on expire idle sessions", e); } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/servlets/CBStatusServlet.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/servlets/CBStatusServlet.java index 53979a462c..78cd34091c 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/servlets/CBStatusServlet.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/servlets/CBStatusServlet.java @@ -19,6 +19,7 @@ import com.google.gson.stream.JsonWriter; import io.cloudbeaver.server.CBApplication; import io.cloudbeaver.server.CBConstants; +import io.cloudbeaver.server.CBPlatform; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServletRequest; @@ -45,7 +46,7 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t infoMap.put("health", "ok"); infoMap.put("product.name", GeneralUtils.getProductName()); infoMap.put("product.version", GeneralUtils.getProductVersion().toString()); - CBApplication.getInstance().getStatusInfo(infoMap); + CBPlatform.getInstance().getApplication().getStatusInfo(infoMap); try (JsonWriter writer = new JsonWriter(response.getWriter())) { JSONUtils.serializeMap(writer, infoMap); } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/websockets/CBJettyWebSocketManager.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/websockets/CBJettyWebSocketManager.java index 26b958fbb2..06cd85f1c1 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/websockets/CBJettyWebSocketManager.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/websockets/CBJettyWebSocketManager.java @@ -16,11 +16,11 @@ */ package io.cloudbeaver.server.websockets; +import io.cloudbeaver.server.AppWebSessionManager; import io.cloudbeaver.model.session.BaseWebSession; import io.cloudbeaver.model.session.WebHeadlessSession; import io.cloudbeaver.model.session.WebHttpRequestInfo; import io.cloudbeaver.server.CBPlatform; -import io.cloudbeaver.service.session.WebSessionManager; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.websocket.server.ServerUpgradeRequest; @@ -42,9 +42,9 @@ public class CBJettyWebSocketManager implements WebSocketCreator { private static final Log log = Log.getLog(CBJettyWebSocketManager.class); private final Map> socketBySessionId = new ConcurrentHashMap<>(); - private final WebSessionManager webSessionManager; + private final AppWebSessionManager webSessionManager; - public CBJettyWebSocketManager(@NotNull WebSessionManager webSessionManager) { + public CBJettyWebSocketManager(@NotNull AppWebSessionManager webSessionManager) { this.webSessionManager = webSessionManager; new WebSocketPingPongJob(CBPlatform.getInstance(), this).scheduleMonitor(); diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/WebServiceBindingBase.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/WebServiceBindingBase.java index 7a85a39e97..faea6732e0 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/WebServiceBindingBase.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/WebServiceBindingBase.java @@ -27,6 +27,7 @@ import io.cloudbeaver.server.CBPlatform; import io.cloudbeaver.server.graphql.GraphQLEndpoint; import io.cloudbeaver.service.security.SMUtils; +import io.cloudbeaver.utils.WebAppUtils; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.jkiss.code.NotNull; @@ -250,7 +251,7 @@ private void checkServicePermissions(Method method, WebActionSet actionSet) thro } private void checkActionPermissions(@NotNull Method method, @NotNull WebAction webAction) throws DBWebException { - CBApplication application = CBApplication.getInstance(); + var application = CBPlatform.getInstance().getApplication(); if (application.isInitializationMode() && webAction.initializationRequired()) { String message = "Server initialization in progress: " + String.join(",", application.getInitActions().values()) + ".\nDo not restart the server."; diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/WebServiceServletBase.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/WebServiceServletBase.java index c6644a5223..3768ff0617 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/WebServiceServletBase.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/WebServiceServletBase.java @@ -1,7 +1,24 @@ +/* + * 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; import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import io.cloudbeaver.model.app.WebApplication; import io.cloudbeaver.model.session.WebSession; import io.cloudbeaver.server.CBApplication; import io.cloudbeaver.server.CBPlatform; @@ -27,13 +44,13 @@ public abstract class WebServiceServletBase extends HttpServlet { .setPrettyPrinting() .create(); - private final CBApplication application; + private final WebApplication application; - public WebServiceServletBase(CBApplication application) { + public WebServiceServletBase(WebApplication application) { this.application = application; } - public CBApplication getApplication() { + public WebApplication getApplication() { return application; } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/WebServiceBindingCore.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/WebServiceBindingCore.java index a04c44847f..ea6b0264b8 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/WebServiceBindingCore.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/WebServiceBindingCore.java @@ -29,7 +29,6 @@ import io.cloudbeaver.service.DBWBindingContext; import io.cloudbeaver.service.WebServiceBindingBase; import io.cloudbeaver.service.core.impl.WebServiceCore; -import io.cloudbeaver.service.session.WebSessionManager; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -50,7 +49,7 @@ public WebServiceBindingCore() { @Override public void bindWiring(DBWBindingContext model) throws DBWebException { CBPlatform platform = CBPlatform.getInstance(); - WebSessionManager sessionManager = platform.getSessionManager(); + var sessionManager = platform.getSessionManager(); model.getQueryType() .dataFetcher("serverConfig", env -> getService(env).getServerConfig()) .dataFetcher("productSettings", env -> getService(env).getProductSettings(getWebSession(env))) 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 f77c7cf6ab..f67ce87cc4 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 @@ -29,7 +29,6 @@ import io.cloudbeaver.server.CBPlatform; import io.cloudbeaver.service.core.DBWServiceCore; import io.cloudbeaver.service.security.SMUtils; -import io.cloudbeaver.service.session.WebSessionManager; import io.cloudbeaver.utils.WebConnectionFolderUtils; import io.cloudbeaver.utils.WebDataSourceUtils; import io.cloudbeaver.utils.WebEventUtils; @@ -291,7 +290,7 @@ public boolean touchSession(@NotNull HttpServletRequest request, @NotNull HttpSe @Deprecated public WebSession updateSession(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response) throws DBWebException { - WebSessionManager sessionManager = CBPlatform.getInstance().getSessionManager(); + var sessionManager = CBPlatform.getInstance().getSessionManager(); sessionManager.touchSession(request, response); return sessionManager.getWebSession(request, response, true); } 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 3380cd4872..92017155d1 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 @@ -18,6 +18,7 @@ import io.cloudbeaver.DBWebException; import io.cloudbeaver.auth.SMTokenCredentialProvider; +import io.cloudbeaver.server.AppWebSessionManager; import io.cloudbeaver.model.session.*; import io.cloudbeaver.registry.WebHandlerRegistry; import io.cloudbeaver.registry.WebSessionHandlerDescriptor; @@ -47,7 +48,7 @@ /** * Web session manager */ -public class WebSessionManager { +public class WebSessionManager implements AppWebSessionManager { private static final Log log = Log.getLog(WebSessionManager.class); @@ -61,6 +62,7 @@ public WebSessionManager(CBApplication application) { /** * Closes Web Session, associated to HttpSession from {@code request} */ + @Override public BaseWebSession closeSession(@NotNull HttpServletRequest request) { HttpSession session = request.getSession(); if (session != null) { @@ -82,8 +84,10 @@ protected CBApplication getApplication() { } @Deprecated - public boolean touchSession(@NotNull HttpServletRequest request, - @NotNull HttpServletResponse response) throws DBWebException { + public boolean touchSession( + @NotNull HttpServletRequest request, + @NotNull HttpServletResponse response + ) throws DBWebException { WebSession webSession = getWebSession(request, response, false); var requestInfo = new WebHttpRequestInfo(request); webSession.updateSessionParameters(requestInfo); @@ -91,12 +95,16 @@ public boolean touchSession(@NotNull HttpServletRequest request, return true; } + @Override @NotNull - public WebSession getWebSession(@NotNull HttpServletRequest request, - @NotNull HttpServletResponse response) throws DBWebException { + public WebSession getWebSession( + @NotNull HttpServletRequest request, + @NotNull HttpServletResponse response + ) throws DBWebException { return getWebSession(request, response, true); } + @Override @NotNull public WebSession getWebSession( @NotNull HttpServletRequest request, @@ -231,6 +239,7 @@ protected Map getSessionHandlers() { .collect(Collectors.toMap(WebSessionHandlerDescriptor::getId, WebSessionHandlerDescriptor::getInstance)); } + @Override @Nullable public BaseWebSession getSession(@NotNull String sessionId) { synchronized (sessionMap) { @@ -238,6 +247,7 @@ public BaseWebSession getSession(@NotNull String sessionId) { } } + @Override @Nullable public WebSession findWebSession(HttpServletRequest request) { String sessionId = request.getSession().getId(); @@ -250,6 +260,7 @@ public WebSession findWebSession(HttpServletRequest request) { } } + @Override public WebSession findWebSession(HttpServletRequest request, boolean errorOnNoFound) throws DBWebException { WebSession webSession = findWebSession(request); if (webSession != null) { @@ -282,6 +293,7 @@ public void expireIdleSessions() { } } + @Override public Collection getAllActiveSessions() { synchronized (sessionMap) { return new ArrayList<>(sessionMap.values()); diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLFileLoaderServlet.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLFileLoaderServlet.java index bc52ac542a..34f70e363f 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLFileLoaderServlet.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLFileLoaderServlet.java @@ -20,6 +20,7 @@ import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; import io.cloudbeaver.DBWebException; +import io.cloudbeaver.model.app.WebApplication; import io.cloudbeaver.model.session.WebSession; import io.cloudbeaver.server.CBApplication; import io.cloudbeaver.server.CBPlatform; @@ -60,7 +61,7 @@ public class WebSQLFileLoaderServlet extends WebServiceServletBase { .setPrettyPrinting() .create(); - public WebSQLFileLoaderServlet(CBApplication application) { + public WebSQLFileLoaderServlet(WebApplication application) { super(application); } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLResultServlet.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLResultServlet.java index 31c5ff26f3..42652e9843 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLResultServlet.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLResultServlet.java @@ -17,6 +17,7 @@ package io.cloudbeaver.service.sql; import io.cloudbeaver.DBWebException; +import io.cloudbeaver.model.app.WebApplication; import io.cloudbeaver.model.session.WebSession; import io.cloudbeaver.server.CBApplication; import io.cloudbeaver.server.servlets.CBStaticServlet; @@ -51,7 +52,7 @@ public class WebSQLResultServlet extends WebServiceServletBase { private final DBWServiceSQL sqlService; - public WebSQLResultServlet(CBApplication application, DBWServiceSQL sqlService) { + public WebSQLResultServlet(WebApplication application, DBWServiceSQL sqlService) { super(application); this.sqlService = sqlService; } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebServiceBindingSQL.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebServiceBindingSQL.java index 7c5ddcd015..78065051a4 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebServiceBindingSQL.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebServiceBindingSQL.java @@ -19,6 +19,7 @@ import graphql.schema.DataFetchingEnvironment; import io.cloudbeaver.DBWebException; import io.cloudbeaver.model.WebConnectionInfo; +import io.cloudbeaver.model.app.WebApplication; import io.cloudbeaver.model.session.WebSession; import io.cloudbeaver.server.CBApplication; import io.cloudbeaver.service.DBWBindingContext; @@ -39,7 +40,7 @@ /** * Web service implementation */ -public class WebServiceBindingSQL extends WebServiceBindingBase implements DBWServiceBindingServlet { +public class WebServiceBindingSQL extends WebServiceBindingBase implements DBWServiceBindingServlet { public WebServiceBindingSQL() { super(DBWServiceSQL.class, new WebServiceSQL(), "schema/service.sql.graphqls"); @@ -294,7 +295,7 @@ public static WebSQLContextInfo getSQLContext(WebSQLProcessor processor, String } @Override - public void addServlets(CBApplication application, DBWServletContext servletContext) throws DBException { + public void addServlets(WebApplication application, DBWServletContext servletContext) throws DBException { servletContext.addServlet( "sqlResultValueViewer", new WebSQLResultServlet(application, getServiceImpl()), @@ -307,6 +308,11 @@ public void addServlets(CBApplication application, DBWServletContext servletCont ); } + @Override + public boolean isApplicable(WebApplication application) { + return application.isMultiuser(); + } + private static class WebSQLConfiguration { private final Map processors = new HashMap<>(); diff --git a/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/WebServiceBindingAdmin.java b/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/WebServiceBindingAdmin.java index 973f010f6d..8a9bca7de0 100644 --- a/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/WebServiceBindingAdmin.java +++ b/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/WebServiceBindingAdmin.java @@ -202,6 +202,9 @@ public void bindWiring(DBWBindingContext model) throws DBWebException { @Override public void addServlets(CBApplication application, DBWServletContext servletContext) throws DBException { + if(!application.isMultiuser()) { + return; + } servletContext.addServlet("adminLogs", new WebAdminLogsServlet(application), application.getServicesURI() + "logs/*"); } diff --git a/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/WebServiceBindingDataTransfer.java b/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/WebServiceBindingDataTransfer.java index 5c6daa5356..10151d5467 100644 --- a/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/WebServiceBindingDataTransfer.java +++ b/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/WebServiceBindingDataTransfer.java @@ -66,6 +66,9 @@ public void bindWiring(DBWBindingContext model) { @Override public void addServlets(CBApplication application, DBWServletContext servletContext) throws DBException { + if (!application.isMultiuser()) { + return; + } servletContext.addServlet( "dataTransfer", new WebDataTransferServlet(application, getServiceImpl()), diff --git a/server/bundles/io.cloudbeaver.service.fs/src/io/cloudbeaver/service/fs/WebServiceBindingFS.java b/server/bundles/io.cloudbeaver.service.fs/src/io/cloudbeaver/service/fs/WebServiceBindingFS.java index d4d616dace..2d8b5515fe 100644 --- a/server/bundles/io.cloudbeaver.service.fs/src/io/cloudbeaver/service/fs/WebServiceBindingFS.java +++ b/server/bundles/io.cloudbeaver.service.fs/src/io/cloudbeaver/service/fs/WebServiceBindingFS.java @@ -118,6 +118,9 @@ public void bindWiring(DBWBindingContext model) throws DBWebException { @Override public void addServlets(CBApplication application, DBWServletContext servletContext) throws DBException { + if (!application.isMultiuser()) { + return; + } servletContext.addServlet( "fileSystems", new WebFSServlet(application, getServiceImpl()), From b869bddded11c437d0e883bbb352f8cdd806fdf3 Mon Sep 17 00:00:00 2001 From: Ainur <59531286+yagudin10@users.noreply.github.com> Date: Thu, 19 Sep 2024 12:48:30 +0200 Subject: [PATCH 5/5] CB-5045 move configs to model package (#2705) * CB-5045 move configs to model package * CB-5045 jetty 12 fix * CB-5045 fix conflicts --------- Co-authored-by: kseniaguzeeva <112612526+kseniaguzeeva@users.noreply.github.com> Co-authored-by: Aleksandr Skoblikov --- .../io.cloudbeaver.model/META-INF/MANIFEST.MF | 1 + .../app/BaseAuthWebAppConfiguration.java | 144 ---------------- .../model/config}/CBAppConfig.java | 159 ++++++++++++------ .../model/config}/CBServerConfig.java | 5 +- .../config}/PasswordPolicyConfiguration.java | 2 +- .../config}/SMControllerConfiguration.java | 2 +- .../model/config}/WebDatabaseConfig.java | 2 +- .../io/cloudbeaver/server/CBConstants.java | 2 + .../src/io/cloudbeaver/WebServiceUtils.java | 2 +- .../model/WebDatabaseDriverInfo.java | 2 +- .../WebDatasourceAccessCheckHandler.java | 2 +- .../io/cloudbeaver/model/WebServerConfig.java | 2 +- .../model/user/WebAuthProviderInfo.java | 2 +- .../io/cloudbeaver/server/CBApplication.java | 10 +- .../cloudbeaver/server/CBApplicationCE.java | 1 + .../CBServerConfigurationController.java | 8 +- ...ServerConfigurationControllerEmbedded.java | 3 +- .../server/jetty/CBJettyServer.java | 2 +- .../server/servlets/CBStaticServlet.java | 3 +- .../server/servlets/ProxyResourceHandler.java | 2 +- .../service/sql/WebSQLDataLOBReceiver.java | 2 +- .../cloudbeaver/service/sql/WebSQLUtils.java | 2 +- .../service/admin/AdminServerConfig.java | 2 +- .../admin/impl/ConnectionSearcher.java | 2 +- .../service/admin/impl/WebServiceAdmin.java | 39 ++++- .../impl/WebDataTransferImportServlet.java | 4 +- .../CBEmbeddedSecurityController.java | 38 ++--- .../EmbeddedSecurityControllerFactory.java | 3 +- .../security/bruteforce/BruteForceUtils.java | 2 +- .../service/security/db/CBDatabase.java | 1 + .../internal/utils/DBConfigurationUtils.java | 2 +- 31 files changed, 206 insertions(+), 247 deletions(-) delete mode 100644 server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/app/BaseAuthWebAppConfiguration.java rename server/bundles/{io.cloudbeaver.server/src/io/cloudbeaver/server => io.cloudbeaver.model/src/io/cloudbeaver/model/config}/CBAppConfig.java (66%) rename server/bundles/{io.cloudbeaver.server/src/io/cloudbeaver/server => io.cloudbeaver.model/src/io/cloudbeaver/model/config}/CBServerConfig.java (97%) rename server/bundles/{io.cloudbeaver.service.security/src/io/cloudbeaver/service/security => io.cloudbeaver.model/src/io/cloudbeaver/model/config}/PasswordPolicyConfiguration.java (97%) rename server/bundles/{io.cloudbeaver.service.security/src/io/cloudbeaver/service/security => io.cloudbeaver.model/src/io/cloudbeaver/model/config}/SMControllerConfiguration.java (98%) rename server/bundles/{io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/db => io.cloudbeaver.model/src/io/cloudbeaver/model/config}/WebDatabaseConfig.java (98%) rename server/bundles/{io.cloudbeaver.server => io.cloudbeaver.model}/src/io/cloudbeaver/server/CBConstants.java (97%) diff --git a/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF index 531c58d95b..8cd9ac3ac9 100644 --- a/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF +++ b/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF @@ -29,6 +29,7 @@ Export-Package: io.cloudbeaver, io.cloudbeaver.websocket, io.cloudbeaver.model, io.cloudbeaver.model.app, + io.cloudbeaver.model.config, io.cloudbeaver.model.fs, io.cloudbeaver.model.log, io.cloudbeaver.model.rm, diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/app/BaseAuthWebAppConfiguration.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/app/BaseAuthWebAppConfiguration.java deleted file mode 100644 index 3067b311df..0000000000 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/app/BaseAuthWebAppConfiguration.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * 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.model.app; - -import com.google.gson.annotations.Expose; -import io.cloudbeaver.auth.provider.local.LocalAuthProviderConstants; -import io.cloudbeaver.registry.WebAuthProviderDescriptor; -import io.cloudbeaver.registry.WebAuthProviderRegistry; -import org.jkiss.code.NotNull; -import org.jkiss.code.Nullable; -import org.jkiss.dbeaver.model.security.SMAuthProviderCustomConfiguration; -import org.jkiss.utils.ArrayUtils; - -import java.util.*; - -public abstract class BaseAuthWebAppConfiguration extends BaseWebAppConfiguration implements WebAuthConfiguration { - private String defaultAuthProvider; - private String[] enabledAuthProviders; - private final Set authConfigurations; - // Legacy auth configs, left for backward compatibility - @Expose(serialize = false) - private final Map authConfiguration; - - public BaseAuthWebAppConfiguration() { - super(); - this.defaultAuthProvider = LocalAuthProviderConstants.PROVIDER_ID; - this.enabledAuthProviders = null; - this.authConfigurations = new LinkedHashSet<>(); - this.authConfiguration = new LinkedHashMap<>(); - } - - public BaseAuthWebAppConfiguration(BaseAuthWebAppConfiguration src) { - super(src); - this.defaultAuthProvider = src.defaultAuthProvider; - this.enabledAuthProviders = src.enabledAuthProviders; - this.authConfigurations = new LinkedHashSet<>(src.authConfigurations); - this.authConfiguration = new LinkedHashMap<>(src.authConfiguration); - } - - @Override - public String getDefaultAuthProvider() { - return defaultAuthProvider; - } - - public void setDefaultAuthProvider(String defaultAuthProvider) { - this.defaultAuthProvider = defaultAuthProvider; - } - - @Override - public String[] getEnabledAuthProviders() { - if (enabledAuthProviders == null) { - // No config - enable all providers (+backward compatibility) - return WebAuthProviderRegistry.getInstance().getAuthProviders() - .stream().map(WebAuthProviderDescriptor::getId).toArray(String[]::new); - } - return enabledAuthProviders; - } - - public void setEnabledAuthProviders(String[] enabledAuthProviders) { - this.enabledAuthProviders = enabledAuthProviders; - } - - - @Override - public boolean isAuthProviderEnabled(String id) { - var authProviderDescriptor = WebAuthProviderRegistry.getInstance().getAuthProvider(id); - if (authProviderDescriptor == null) { - return false; - } - - if (!ArrayUtils.contains(getEnabledAuthProviders(), id)) { - return false; - } - if (!ArrayUtils.isEmpty(authProviderDescriptor.getRequiredFeatures())) { - for (String rf : authProviderDescriptor.getRequiredFeatures()) { - if (!isFeatureEnabled(rf)) { - return false; - } - } - } - return true; - } - - //////////////////////////////////////////// - // Auth provider configs - @Override - public Set getAuthCustomConfigurations() { - return authConfigurations; - } - - @Override - @Nullable - public SMAuthProviderCustomConfiguration getAuthProviderConfiguration(@NotNull String id) { - synchronized (authConfigurations) { - return authConfigurations.stream().filter(c -> c.getId().equals(id)).findAny().orElse(null); - } - } - - public void addAuthProviderConfiguration(@NotNull SMAuthProviderCustomConfiguration config) { - synchronized (authConfigurations) { - authConfigurations.removeIf(c -> c.getId().equals(config.getId())); - authConfigurations.add(config); - } - } - - public void setAuthProvidersConfigurations(Collection authProviders) { - synchronized (authConfigurations) { - authConfigurations.clear(); - authConfigurations.addAll(authProviders); - } - } - - public boolean deleteAuthProviderConfiguration(@NotNull String id) { - synchronized (authConfigurations) { - return authConfigurations.removeIf(c -> c.getId().equals(id)); - } - } - - public void loadLegacyCustomConfigs() { - // Convert legacy map of configs into list - if (!authConfiguration.isEmpty()) { - for (Map.Entry entry : authConfiguration.entrySet()) { - entry.getValue().setId(entry.getKey()); - authConfigurations.add(entry.getValue()); - } - authConfiguration.clear(); - } - } -} diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBAppConfig.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/config/CBAppConfig.java similarity index 66% rename from server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBAppConfig.java rename to server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/config/CBAppConfig.java index 798de0732c..a2fc07f6be 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBAppConfig.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/config/CBAppConfig.java @@ -14,21 +14,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.cloudbeaver.server; +package io.cloudbeaver.model.config; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import io.cloudbeaver.DBWebException; -import io.cloudbeaver.WebServiceUtils; -import io.cloudbeaver.model.app.BaseAuthWebAppConfiguration; +import com.google.gson.annotations.Expose; +import io.cloudbeaver.auth.provider.local.LocalAuthProviderConstants; +import io.cloudbeaver.model.app.BaseWebAppConfiguration; import io.cloudbeaver.model.app.WebAuthConfiguration; import io.cloudbeaver.registry.WebAuthProviderDescriptor; import io.cloudbeaver.registry.WebAuthProviderRegistry; import org.jkiss.code.NotNull; -import org.jkiss.dbeaver.DBException; +import org.jkiss.code.Nullable; import org.jkiss.dbeaver.Log; -import org.jkiss.dbeaver.model.connection.DBPDriver; import org.jkiss.dbeaver.model.navigator.DBNBrowseSettings; +import org.jkiss.dbeaver.model.security.SMAuthProviderCustomConfiguration; import org.jkiss.dbeaver.registry.DataSourceNavigatorSettings; import org.jkiss.utils.ArrayUtils; import org.jkiss.utils.CommonUtils; @@ -38,11 +36,15 @@ /** * Application configuration */ -public class CBAppConfig extends BaseAuthWebAppConfiguration implements WebAuthConfiguration { +public class CBAppConfig extends BaseWebAppConfiguration implements WebAuthConfiguration { private static final Log log = Log.getLog(CBAppConfig.class); public static final DataSourceNavigatorSettings.Preset PRESET_WEB = new DataSourceNavigatorSettings.Preset("web", "Web", "Default view"); public static final DataSourceNavigatorSettings DEFAULT_VIEW_SETTINGS = PRESET_WEB.getSettings(); + private final Set authConfigurations; + // Legacy auth configs, left for backward compatibility + @Expose(serialize = false) + private final Map authConfiguration; private boolean supportsCustomConnections; private boolean supportsConnectionBrowser; @@ -66,9 +68,14 @@ public class CBAppConfig extends BaseAuthWebAppConfiguration implements WebAuthC private DataSourceNavigatorSettings defaultNavigatorSettings; private final Map resourceQuotas; + private String defaultAuthProvider; + private String[] enabledAuthProviders; public CBAppConfig() { - super(); + this.defaultAuthProvider = LocalAuthProviderConstants.PROVIDER_ID; + this.enabledAuthProviders = null; + this.authConfigurations = new LinkedHashSet<>(); + this.authConfiguration = new LinkedHashMap<>(); this.anonymousAccessEnabled = false; this.anonymousUserRole = DEFAULT_APP_ANONYMOUS_TEAM_NAME; this.anonymousUserTeam = DEFAULT_APP_ANONYMOUS_TEAM_NAME; @@ -91,6 +98,10 @@ public CBAppConfig() { public CBAppConfig(CBAppConfig src) { super(src); + this.defaultAuthProvider = src.defaultAuthProvider; + this.enabledAuthProviders = src.enabledAuthProviders; + this.authConfigurations = new LinkedHashSet<>(src.authConfigurations); + this.authConfiguration = new LinkedHashMap<>(src.authConfiguration); this.anonymousAccessEnabled = src.anonymousAccessEnabled; this.anonymousUserRole = src.anonymousUserRole; this.anonymousUserTeam = src.anonymousUserTeam; @@ -169,6 +180,10 @@ public String[] getEnabledDrivers() { return enabledDrivers; } + public void setEnabledDrivers(String[] enabledDrivers) { + this.enabledDrivers = enabledDrivers; + } + public String[] getDisabledDrivers() { return disabledDrivers; } @@ -204,19 +219,6 @@ public Map getPluginConfig(@NotNull String pluginId) { return getPluginConfig(pluginId, false); } - public T getPluginOptions(@NotNull String pluginId, @NotNull String option, Class theClass) throws DBException { - Map iamSettingsMap = CBPlatform.getInstance().getApplication().getAppConfiguration().getPluginOption( - pluginId, option); - if (CommonUtils.isEmpty(iamSettingsMap)) { - throw new DBException("Settings '" + option + "' not specified in plugin '" + pluginId + "' configuration"); - } - - Gson gson = new GsonBuilder().create(); - return gson.fromJson( - gson.toJsonTree(iamSettingsMap), - theClass); - } - //////////////////////////////////////////// // Quotas @@ -264,43 +266,100 @@ public boolean isGrantConnectionsAccessToAnonymousTeam() { return grantConnectionsAccessToAnonymousTeam; } + public boolean isDriverForceEnabled(@NotNull String driverId) { + return ArrayUtils.containsIgnoreCase(getEnabledDrivers(), driverId); + } + + public boolean isSystemVariablesResolvingEnabled() { + return systemVariablesResolvingEnabled; + } + + @Override + public String getDefaultAuthProvider() { + return defaultAuthProvider; + } - // we disable embedded drivers by default and enable it in enabled drivers list - // that's why we need so complicated logic for disabling drivers + public void setDefaultAuthProvider(String defaultAuthProvider) { + this.defaultAuthProvider = defaultAuthProvider; + } - public void updateDisabledDriversConfig(String[] disabledDriversConfig) { - Set disabledIds = new LinkedHashSet<>(Arrays.asList(disabledDriversConfig)); - Set enabledIds = new LinkedHashSet<>(Arrays.asList(this.enabledDrivers)); + @Override + public String[] getEnabledAuthProviders() { + if (enabledAuthProviders == null) { + // No config - enable all providers (+backward compatibility) + return WebAuthProviderRegistry.getInstance().getAuthProviders() + .stream().map(WebAuthProviderDescriptor::getId).toArray(String[]::new); + } + return enabledAuthProviders; + } - // remove all disabled embedded drivers from enabled drivers list - enabledIds.removeAll(disabledIds); + public void setEnabledAuthProviders(String[] enabledAuthProviders) { + this.enabledAuthProviders = enabledAuthProviders; + } - // enable embedded driver if it is not in disabled drivers list - for (String driverId : this.disabledDrivers) { - if (disabledIds.contains(driverId)) { - // driver is also disabled - continue; - } - // driver is removed from disabled list - // we need to enable if it is embedded - try { - DBPDriver driver = WebServiceUtils.getDriverById(driverId); - if (driver.isEmbedded()) { - enabledIds.add(driverId); + @Override + public boolean isAuthProviderEnabled(String id) { + var authProviderDescriptor = WebAuthProviderRegistry.getInstance().getAuthProvider(id); + if (authProviderDescriptor == null) { + return false; + } + + if (!ArrayUtils.contains(getEnabledAuthProviders(), id)) { + return false; + } + if (!ArrayUtils.isEmpty(authProviderDescriptor.getRequiredFeatures())) { + for (String rf : authProviderDescriptor.getRequiredFeatures()) { + if (!isFeatureEnabled(rf)) { + return false; } - } catch (DBWebException e) { - log.error("Failed to find driver by id", e); } } - this.disabledDrivers = disabledDriversConfig; - this.enabledDrivers = enabledIds.toArray(String[]::new); + return true; } - public boolean isDriverForceEnabled(@NotNull String driverId) { - return ArrayUtils.containsIgnoreCase(getEnabledDrivers(), driverId); + //////////////////////////////////////////// + // Auth provider configs + @Override + public Set getAuthCustomConfigurations() { + return authConfigurations; } - public boolean isSystemVariablesResolvingEnabled() { - return systemVariablesResolvingEnabled; + @Override + @Nullable + public SMAuthProviderCustomConfiguration getAuthProviderConfiguration(@NotNull String id) { + synchronized (authConfigurations) { + return authConfigurations.stream().filter(c -> c.getId().equals(id)).findAny().orElse(null); + } + } + + public void addAuthProviderConfiguration(@NotNull SMAuthProviderCustomConfiguration config) { + synchronized (authConfigurations) { + authConfigurations.removeIf(c -> c.getId().equals(config.getId())); + authConfigurations.add(config); + } + } + + public void setAuthProvidersConfigurations(Collection authProviders) { + synchronized (authConfigurations) { + authConfigurations.clear(); + authConfigurations.addAll(authProviders); + } + } + + public boolean deleteAuthProviderConfiguration(@NotNull String id) { + synchronized (authConfigurations) { + return authConfigurations.removeIf(c -> c.getId().equals(id)); + } + } + + public void loadLegacyCustomConfigs() { + // Convert legacy map of configs into list + if (!authConfiguration.isEmpty()) { + for (Map.Entry entry : authConfiguration.entrySet()) { + entry.getValue().setId(entry.getKey()); + authConfigurations.add(entry.getValue()); + } + authConfiguration.clear(); + } } } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBServerConfig.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/config/CBServerConfig.java similarity index 97% rename from server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBServerConfig.java rename to server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/config/CBServerConfig.java index fc02e4baa5..2ab813e572 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBServerConfig.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/config/CBServerConfig.java @@ -14,13 +14,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.cloudbeaver.server; +package io.cloudbeaver.model.config; import com.google.gson.annotations.SerializedName; import io.cloudbeaver.auth.CBAuthConstants; import io.cloudbeaver.model.app.WebServerConfiguration; -import io.cloudbeaver.service.security.SMControllerConfiguration; -import io.cloudbeaver.service.security.db.WebDatabaseConfig; +import io.cloudbeaver.server.CBConstants; import org.jkiss.code.NotNull; import org.jkiss.dbeaver.Log; diff --git a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/PasswordPolicyConfiguration.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/config/PasswordPolicyConfiguration.java similarity index 97% rename from server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/PasswordPolicyConfiguration.java rename to server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/config/PasswordPolicyConfiguration.java index 28076d7174..fb5e674afa 100644 --- a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/PasswordPolicyConfiguration.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/config/PasswordPolicyConfiguration.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.cloudbeaver.service.security; +package io.cloudbeaver.model.config; import org.jkiss.dbeaver.model.meta.Property; diff --git a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/SMControllerConfiguration.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/config/SMControllerConfiguration.java similarity index 98% rename from server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/SMControllerConfiguration.java rename to server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/config/SMControllerConfiguration.java index 70a704faf1..ad22bd5736 100644 --- a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/SMControllerConfiguration.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/config/SMControllerConfiguration.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package io.cloudbeaver.service.security; +package io.cloudbeaver.model.config; public class SMControllerConfiguration { //in minutes diff --git a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/db/WebDatabaseConfig.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/config/WebDatabaseConfig.java similarity index 98% rename from server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/db/WebDatabaseConfig.java rename to server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/config/WebDatabaseConfig.java index 27bf86f04f..8a5ef39010 100644 --- a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/db/WebDatabaseConfig.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/config/WebDatabaseConfig.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.cloudbeaver.service.security.db; +package io.cloudbeaver.model.config; import org.jkiss.code.NotNull; import org.jkiss.dbeaver.model.connection.InternalDatabaseConfig; diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBConstants.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/server/CBConstants.java similarity index 97% rename from server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBConstants.java rename to server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/server/CBConstants.java index f87ae5e1cd..0103994c19 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBConstants.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/server/CBConstants.java @@ -87,4 +87,6 @@ public class CBConstants { public static final String QUOTA_PROP_FILE_LIMIT = "dataExportFileSizeLimit"; public static final String ADMIN_AUTO_GRANT = "auto-grant"; + public static final String HOST_LOCALHOST = "localhost"; + public static final String HOST_127_0_0_1 = "127.0.0.1"; } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java index 3383195c22..4c60dd58d8 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java @@ -22,11 +22,11 @@ import io.cloudbeaver.model.WebConnectionConfig; import io.cloudbeaver.model.WebNetworkHandlerConfigInput; import io.cloudbeaver.model.WebPropertyInfo; +import io.cloudbeaver.model.config.CBAppConfig; import io.cloudbeaver.model.session.WebActionParameters; import io.cloudbeaver.model.session.WebSession; import io.cloudbeaver.registry.WebAuthProviderDescriptor; import io.cloudbeaver.registry.WebAuthProviderRegistry; -import io.cloudbeaver.server.CBAppConfig; import io.cloudbeaver.server.CBApplication; import io.cloudbeaver.server.CBPlatform; import io.cloudbeaver.service.navigator.WebPropertyFilter; diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDatabaseDriverInfo.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDatabaseDriverInfo.java index f9e207bbcb..c1bf020243 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDatabaseDriverInfo.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDatabaseDriverInfo.java @@ -18,9 +18,9 @@ import io.cloudbeaver.DBWebException; import io.cloudbeaver.WebServiceUtils; +import io.cloudbeaver.model.config.CBAppConfig; import io.cloudbeaver.model.session.WebSession; import io.cloudbeaver.model.utils.ConfigurationUtils; -import io.cloudbeaver.server.CBAppConfig; import io.cloudbeaver.server.CBApplication; import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.Log; diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDatasourceAccessCheckHandler.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDatasourceAccessCheckHandler.java index 2e0fc051d5..2e3ca7aea1 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDatasourceAccessCheckHandler.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDatasourceAccessCheckHandler.java @@ -17,8 +17,8 @@ package io.cloudbeaver.model; +import io.cloudbeaver.model.config.CBAppConfig; import io.cloudbeaver.model.utils.ConfigurationUtils; -import io.cloudbeaver.server.CBAppConfig; import io.cloudbeaver.server.CBApplication; import org.jkiss.dbeaver.model.connection.DBPDriver; diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebServerConfig.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebServerConfig.java index 826331eea4..02b99023ec 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebServerConfig.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebServerConfig.java @@ -16,11 +16,11 @@ */ package io.cloudbeaver.model; +import io.cloudbeaver.model.config.PasswordPolicyConfiguration; import io.cloudbeaver.registry.WebServiceDescriptor; import io.cloudbeaver.registry.WebServiceRegistry; import io.cloudbeaver.server.CBApplication; import io.cloudbeaver.server.CBPlatform; -import io.cloudbeaver.service.security.PasswordPolicyConfiguration; import org.jkiss.code.Nullable; import org.jkiss.dbeaver.model.meta.Property; import org.jkiss.dbeaver.model.navigator.DBNBrowseSettings; diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/user/WebAuthProviderInfo.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/user/WebAuthProviderInfo.java index e50916d9e6..e9caa0ea1d 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/user/WebAuthProviderInfo.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/user/WebAuthProviderInfo.java @@ -19,9 +19,9 @@ import io.cloudbeaver.WebServiceUtils; import io.cloudbeaver.auth.SMAuthProviderFederated; import io.cloudbeaver.auth.provisioning.SMProvisioner; +import io.cloudbeaver.model.config.CBAppConfig; import io.cloudbeaver.registry.WebAuthProviderConfiguration; import io.cloudbeaver.registry.WebAuthProviderDescriptor; -import io.cloudbeaver.server.CBAppConfig; import io.cloudbeaver.server.CBApplication; import io.cloudbeaver.server.CBPlatform; import org.jkiss.dbeaver.Log; 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 a5bff0eace..f6e36bc2a9 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 @@ -21,12 +21,14 @@ import io.cloudbeaver.model.app.BaseWebApplication; import io.cloudbeaver.model.app.WebAuthApplication; import io.cloudbeaver.model.app.WebAuthConfiguration; +import io.cloudbeaver.model.config.CBAppConfig; +import io.cloudbeaver.model.config.CBServerConfig; +import io.cloudbeaver.model.config.SMControllerConfiguration; import io.cloudbeaver.registry.WebDriverRegistry; import io.cloudbeaver.registry.WebServiceRegistry; import io.cloudbeaver.server.jetty.CBJettyServer; import io.cloudbeaver.service.DBWServiceInitializer; import io.cloudbeaver.service.DBWServiceServerConfigurator; -import io.cloudbeaver.service.security.SMControllerConfiguration; import io.cloudbeaver.service.session.WebSessionManager; import io.cloudbeaver.utils.WebDataSourceUtils; import org.eclipse.core.runtime.Platform; @@ -84,8 +86,6 @@ public abstract class CBApplication extends * In configuration mode sessions expire after a week */ private static final long CONFIGURATION_MODE_SESSION_IDLE_TIME = 60 * 60 * 1000 * 24 * 7; - public static final String HOST_LOCALHOST = "localhost"; - public static final String HOST_127_0_0_1 = "127.0.0.1"; static { @@ -222,9 +222,9 @@ protected void startServer() { if (CommonUtils.isEmpty(localHostAddress)) { localHostAddress = System.getProperty(CBConstants.VAR_CB_LOCAL_HOST_ADDR); } - if (CommonUtils.isEmpty(localHostAddress) || HOST_127_0_0_1.equals(localHostAddress) || "::0".equals( + if (CommonUtils.isEmpty(localHostAddress) || CBConstants.HOST_127_0_0_1.equals(localHostAddress) || "::0".equals( localHostAddress)) { - localHostAddress = HOST_LOCALHOST; + localHostAddress = CBConstants.HOST_LOCALHOST; } final Runtime runtime = Runtime.getRuntime(); diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBApplicationCE.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBApplicationCE.java index 7a00e3474c..1ee1b5c0f8 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBApplicationCE.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBApplicationCE.java @@ -17,6 +17,7 @@ package io.cloudbeaver.server; import io.cloudbeaver.auth.NoAuthCredentialsProvider; +import io.cloudbeaver.model.config.CBServerConfig; import io.cloudbeaver.model.rm.local.LocalResourceController; import io.cloudbeaver.service.security.CBEmbeddedSecurityController; import io.cloudbeaver.service.security.EmbeddedSecurityControllerFactory; diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBServerConfigurationController.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBServerConfigurationController.java index 25c0d26390..7acde3722b 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBServerConfigurationController.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBServerConfigurationController.java @@ -21,8 +21,10 @@ import com.google.gson.InstanceCreator; import io.cloudbeaver.model.app.BaseServerConfigurationController; import io.cloudbeaver.model.app.BaseWebApplication; -import io.cloudbeaver.service.security.PasswordPolicyConfiguration; -import io.cloudbeaver.service.security.SMControllerConfiguration; +import io.cloudbeaver.model.config.CBAppConfig; +import io.cloudbeaver.model.config.CBServerConfig; +import io.cloudbeaver.model.config.PasswordPolicyConfiguration; +import io.cloudbeaver.model.config.SMControllerConfiguration; import io.cloudbeaver.utils.WebAppUtils; import org.jkiss.code.NotNull; import org.jkiss.code.Nullable; @@ -158,7 +160,7 @@ public T parseServerConfiguration() { hostName = InetAddress.getLocalHost().getHostName(); } catch (UnknownHostException e) { log.debug("Error resolving localhost address: " + e.getMessage()); - hostName = CBApplication.HOST_LOCALHOST; + hostName = CBConstants.HOST_LOCALHOST; } } config.setServerURL("http://" + hostName + ":" + config.getServerPort()); diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBServerConfigurationControllerEmbedded.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBServerConfigurationControllerEmbedded.java index 600b7aeed4..7031b941a6 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBServerConfigurationControllerEmbedded.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBServerConfigurationControllerEmbedded.java @@ -19,7 +19,8 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.InstanceCreator; -import io.cloudbeaver.service.security.db.WebDatabaseConfig; +import io.cloudbeaver.model.config.CBServerConfig; +import io.cloudbeaver.model.config.WebDatabaseConfig; import org.jkiss.code.NotNull; import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.model.data.json.JSONUtils; diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBJettyServer.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBJettyServer.java index ac37138be0..daa6f8e378 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBJettyServer.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBJettyServer.java @@ -19,7 +19,7 @@ import io.cloudbeaver.server.GQLApplicationAdapter; import io.cloudbeaver.registry.WebServiceRegistry; import io.cloudbeaver.server.CBApplication; -import io.cloudbeaver.server.CBServerConfig; +import io.cloudbeaver.model.config.CBServerConfig; import io.cloudbeaver.server.graphql.GraphQLEndpoint; import io.cloudbeaver.server.servlets.CBImageServlet; import io.cloudbeaver.server.servlets.CBStaticServlet; diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/servlets/CBStaticServlet.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/servlets/CBStaticServlet.java index b191027991..e558dd4c75 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/servlets/CBStaticServlet.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/servlets/CBStaticServlet.java @@ -20,13 +20,14 @@ import io.cloudbeaver.DBWebException; import io.cloudbeaver.auth.CBAuthConstants; import io.cloudbeaver.auth.SMAuthProviderFederated; +import io.cloudbeaver.model.config.CBAppConfig; +import io.cloudbeaver.model.config.CBServerConfig; import io.cloudbeaver.model.session.WebActionParameters; import io.cloudbeaver.model.session.WebSession; import io.cloudbeaver.registry.WebAuthProviderDescriptor; import io.cloudbeaver.registry.WebAuthProviderRegistry; import io.cloudbeaver.registry.WebHandlerRegistry; import io.cloudbeaver.registry.WebServletHandlerDescriptor; -import io.cloudbeaver.server.CBAppConfig; import io.cloudbeaver.server.CBApplication; import io.cloudbeaver.server.CBPlatform; import jakarta.servlet.ServletException; diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/servlets/ProxyResourceHandler.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/servlets/ProxyResourceHandler.java index 12b89242f5..c9c20d874b 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/servlets/ProxyResourceHandler.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/servlets/ProxyResourceHandler.java @@ -16,8 +16,8 @@ */ package io.cloudbeaver.server.servlets; +import io.cloudbeaver.model.config.CBServerConfig; import io.cloudbeaver.server.CBApplication; -import io.cloudbeaver.server.CBServerConfig; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Request; diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLDataLOBReceiver.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLDataLOBReceiver.java index fbfced3597..2d3a9e5fa5 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLDataLOBReceiver.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLDataLOBReceiver.java @@ -20,7 +20,7 @@ import io.cloudbeaver.server.CBConstants; import io.cloudbeaver.server.CBPlatform; import org.jkiss.dbeaver.Log; -import org.jkiss.dbeaver.model.exec.*; +import org.jkiss.dbeaver.model.exec.DBCException; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; import org.jkiss.dbeaver.model.runtime.VoidProgressMonitor; import org.jkiss.dbeaver.model.sql.DBQuotaException; diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLUtils.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLUtils.java index 667539783d..2e55d43b34 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLUtils.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLUtils.java @@ -16,9 +16,9 @@ */ package io.cloudbeaver.service.sql; +import io.cloudbeaver.model.config.CBAppConfig; import io.cloudbeaver.model.session.WebSession; import io.cloudbeaver.registry.WebServiceRegistry; -import io.cloudbeaver.server.CBAppConfig; import io.cloudbeaver.server.CBApplication; import io.cloudbeaver.utils.CBModelConstants; import org.jkiss.code.NotNull; diff --git a/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/AdminServerConfig.java b/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/AdminServerConfig.java index 0ba9adf93e..e459b2d2a0 100644 --- a/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/AdminServerConfig.java +++ b/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/AdminServerConfig.java @@ -16,7 +16,7 @@ */ package io.cloudbeaver.service.admin; -import io.cloudbeaver.server.CBAppConfig; +import io.cloudbeaver.model.config.CBAppConfig; import io.cloudbeaver.server.CBApplication; import org.jkiss.dbeaver.model.data.json.JSONUtils; diff --git a/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/ConnectionSearcher.java b/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/ConnectionSearcher.java index 711acc19b1..8292df8c2c 100644 --- a/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/ConnectionSearcher.java +++ b/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/ConnectionSearcher.java @@ -16,9 +16,9 @@ */ package io.cloudbeaver.service.admin.impl; +import io.cloudbeaver.model.config.CBAppConfig; import io.cloudbeaver.model.session.WebSession; import io.cloudbeaver.model.utils.ConfigurationUtils; -import io.cloudbeaver.server.CBAppConfig; import io.cloudbeaver.server.CBApplication; import io.cloudbeaver.server.CBPlatform; import io.cloudbeaver.service.admin.AdminConnectionSearchInfo; 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 d79e472aa5..48e78992a3 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 @@ -22,11 +22,15 @@ import io.cloudbeaver.WebServiceUtils; import io.cloudbeaver.auth.provider.local.LocalAuthProvider; import io.cloudbeaver.model.WebPropertyInfo; +import io.cloudbeaver.model.config.CBAppConfig; +import io.cloudbeaver.model.config.CBServerConfig; import io.cloudbeaver.model.session.WebAuthInfo; import io.cloudbeaver.model.session.WebSession; import io.cloudbeaver.model.user.WebUser; import io.cloudbeaver.registry.*; -import io.cloudbeaver.server.*; +import io.cloudbeaver.server.CBApplication; +import io.cloudbeaver.server.CBConstants; +import io.cloudbeaver.server.CBPlatform; import io.cloudbeaver.service.DBWServiceServerConfigurator; import io.cloudbeaver.service.admin.*; import io.cloudbeaver.service.security.SMUtils; @@ -39,6 +43,7 @@ import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry; import org.jkiss.dbeaver.model.app.DBPProject; import org.jkiss.dbeaver.model.auth.AuthInfo; +import org.jkiss.dbeaver.model.connection.DBPDriver; import org.jkiss.dbeaver.model.navigator.DBNBrowseSettings; import org.jkiss.dbeaver.model.preferences.DBPPropertyDescriptor; import org.jkiss.dbeaver.model.rm.RMProjectType; @@ -543,7 +548,7 @@ public boolean configureServer(WebSession webSession, Map params appConfig.setAdminCredentialsSaveEnabled(config.isAdminCredentialsSaveEnabled()); appConfig.setEnabledFeatures(config.getEnabledFeatures().toArray(new String[0])); // custom logic for enabling embedded drivers - appConfig.updateDisabledDriversConfig(config.getDisabledDrivers()); + updateDisabledDriversConfig(appConfig, config.getDisabledDrivers()); appConfig.setResourceManagerEnabled(config.isResourceManagerEnabled()); if (CommonUtils.isEmpty(config.getEnabledAuthProviders())) { @@ -621,6 +626,36 @@ public boolean configureServer(WebSession webSession, Map params return true; } + // we disable embedded drivers by default and enable it in enabled drivers list + // that's why we need so complicated logic for disabling drivers + private void updateDisabledDriversConfig(CBAppConfig appConfig, String[] disabledDriversConfig) { + Set disabledIds = new LinkedHashSet<>(Arrays.asList(disabledDriversConfig)); + Set enabledIds = new LinkedHashSet<>(Arrays.asList(appConfig.getEnabledDrivers())); + + // remove all disabled embedded drivers from enabled drivers list + enabledIds.removeAll(disabledIds); + + // enable embedded driver if it is not in disabled drivers list + for (String driverId : appConfig.getDisabledDrivers()) { + if (disabledIds.contains(driverId)) { + // driver is also disabled + continue; + } + // driver is removed from disabled list + // we need to enable if it is embedded + try { + DBPDriver driver = WebServiceUtils.getDriverById(driverId); + if (driver.isEmbedded()) { + enabledIds.add(driverId); + } + } catch (DBWebException e) { + log.error("Failed to find driver by id", e); + } + } + appConfig.setDisabledDrivers(disabledDriversConfig); + appConfig.setEnabledDrivers(enabledIds.toArray(String[]::new)); + } + @Override public boolean setDefaultNavigatorSettings(WebSession webSession, DBNBrowseSettings settings) throws DBWebException { CBApplication.getInstance().getAppConfiguration().setDefaultNavigatorSettings(settings); diff --git a/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/impl/WebDataTransferImportServlet.java b/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/impl/WebDataTransferImportServlet.java index 5aad6558cc..c0f575abb5 100644 --- a/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/impl/WebDataTransferImportServlet.java +++ b/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/impl/WebDataTransferImportServlet.java @@ -42,7 +42,9 @@ import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; -import java.util.*; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.UUID; @MultipartConfig public class WebDataTransferImportServlet extends WebServiceServletBase { 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 c8887edeed..806dbd4e6b 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 @@ -21,9 +21,9 @@ import com.google.gson.reflect.TypeToken; import io.cloudbeaver.DBWConstants; import io.cloudbeaver.auth.*; -import io.cloudbeaver.model.app.WebAppConfiguration; import io.cloudbeaver.model.app.WebAuthApplication; import io.cloudbeaver.model.app.WebAuthConfiguration; +import io.cloudbeaver.model.config.SMControllerConfiguration; import io.cloudbeaver.registry.WebAuthProviderDescriptor; import io.cloudbeaver.registry.WebAuthProviderRegistry; import io.cloudbeaver.registry.WebMetaParametersRegistry; @@ -1040,15 +1040,13 @@ public SMPropertyDescriptor[] getMetaParametersBySubjectType(SMSubjectType subje WebMetaParametersRegistry.getInstance().getMetaParameters(subjectType)); // Add metas from enabled auth providers - WebAppConfiguration appConfiguration = application.getAppConfiguration(); - if (appConfiguration instanceof WebAuthConfiguration) { - for (String apId : ((WebAuthConfiguration) appConfiguration).getEnabledAuthProviders()) { - WebAuthProviderDescriptor ap = WebAuthProviderRegistry.getInstance().getAuthProvider(apId); - if (ap != null) { - List metaProps = ap.getMetaParameters(SMSubjectType.team); - if (!CommonUtils.isEmpty(metaProps)) { - props.addAll(metaProps); - } + WebAuthConfiguration authConfiguration = application.getAuthConfiguration(); + for (String apId : authConfiguration.getEnabledAuthProviders()) { + WebAuthProviderDescriptor ap = WebAuthProviderRegistry.getInstance().getAuthProvider(apId); + if (ap != null) { + List metaProps = ap.getMetaParameters(SMSubjectType.team); + if (!CommonUtils.isEmpty(metaProps)) { + props.addAll(metaProps); } } } @@ -1068,9 +1066,10 @@ public SMTeam[] readAllTeams() throws DBCException { String defaultUserTeam = getDefaultUserTeam(); Map teams = new LinkedHashMap<>(); String query = database.normalizeTableNames( - "SELECT T.*, S.IS_SECRET_STORAGE FROM {table_prefix}CB_TEAM T, " + - "{table_prefix}CB_AUTH_SUBJECT S " + - "WHERE T.TEAM_ID IN (S.SUBJECT_ID, ?) ORDER BY TEAM_ID"); + """ + SELECT T.*, S.IS_SECRET_STORAGE FROM {table_prefix}CB_TEAM T, \ + {table_prefix}CB_AUTH_SUBJECT S \ + WHERE T.TEAM_ID IN (S.SUBJECT_ID, ?) ORDER BY TEAM_ID"""); try (PreparedStatement dbPreparedStatement = dbCon.prepareStatement(query)) { dbPreparedStatement.setString(1, defaultUserTeam); try (ResultSet dbResult = dbPreparedStatement.executeQuery()) { @@ -2107,7 +2106,7 @@ private SMAuthInfo finishAuthentication( String activeUserId = null; if (!isMainAuthSession) { var accessToken = findTokenBySmSession(authAttemptSessionInfo.getSmSessionId()).getSmAccessToken(); - //this is an additional authorization and we should to return the original permissions and userId + //this is an additional authorization, and we should to return the original permissions and userId permissions = getTokenPermissions(accessToken); activeUserId = permissions.getUserId(); } @@ -2575,8 +2574,9 @@ private SMAuthPermissions getTokenPermissions(@NotNull String token) throws DBEx String authRole; try (Connection dbCon = database.openConnection(); PreparedStatement dbStat = dbCon.prepareStatement( - database.normalizeTableNames("SELECT USER_ID, EXPIRATION_TIME, SESSION_ID, AUTH_ROLE FROM {table_prefix}CB_AUTH_TOKEN " + - "WHERE TOKEN_ID=?")) + database.normalizeTableNames(""" + SELECT USER_ID, EXPIRATION_TIME, SESSION_ID, AUTH_ROLE FROM {table_prefix}CB_AUTH_TOKEN \ + WHERE TOKEN_ID=?""")) ) { dbStat.setString(1, token); try (var dbResult = dbStat.executeQuery()) { @@ -2600,9 +2600,7 @@ private SMAuthPermissions getTokenPermissions(@NotNull String token) throws DBEx @Override public SMAuthProviderDescriptor[] getAvailableAuthProviders() throws DBException { - if (!(application.getAppConfiguration() instanceof WebAuthConfiguration appConfiguration)) { - throw new DBException("Web application doesn't support external authentication"); - } + WebAuthConfiguration appConfiguration = application.getAuthConfiguration(); Set customConfigurations = appConfiguration.getAuthCustomConfigurations(); List providers = WebAuthProviderRegistry.getInstance().getAuthProviders().stream() .filter(ap -> @@ -3054,7 +3052,7 @@ public List getSubjectObjectPermissionGrants(@NotNull } return grantedPermissionsByObjectId.values().stream() .map(SMObjectPermissionsGrant.Builder::build) - .collect(Collectors.toList()); + .toList(); } } catch (SQLException e) { diff --git a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/EmbeddedSecurityControllerFactory.java b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/EmbeddedSecurityControllerFactory.java index 6c7b581b13..1b1a7405fa 100644 --- a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/EmbeddedSecurityControllerFactory.java +++ b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/EmbeddedSecurityControllerFactory.java @@ -18,8 +18,9 @@ import io.cloudbeaver.auth.NoAuthCredentialsProvider; import io.cloudbeaver.model.app.WebAuthApplication; +import io.cloudbeaver.model.config.SMControllerConfiguration; +import io.cloudbeaver.model.config.WebDatabaseConfig; import io.cloudbeaver.service.security.db.CBDatabase; -import io.cloudbeaver.service.security.db.WebDatabaseConfig; import io.cloudbeaver.service.security.internal.ClearAuthAttemptInfoJob; import org.jkiss.code.NotNull; import org.jkiss.dbeaver.DBException; diff --git a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/bruteforce/BruteForceUtils.java b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/bruteforce/BruteForceUtils.java index fecf508ec6..9a0bb08e27 100644 --- a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/bruteforce/BruteForceUtils.java +++ b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/bruteforce/BruteForceUtils.java @@ -16,7 +16,7 @@ */ package io.cloudbeaver.service.security.bruteforce; -import io.cloudbeaver.service.security.SMControllerConfiguration; +import io.cloudbeaver.model.config.SMControllerConfiguration; import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.model.auth.SMAuthStatus; diff --git a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/db/CBDatabase.java b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/db/CBDatabase.java index 0c373781e4..75ebda6796 100644 --- a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/db/CBDatabase.java +++ b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/db/CBDatabase.java @@ -20,6 +20,7 @@ import com.google.gson.GsonBuilder; import io.cloudbeaver.auth.provider.local.LocalAuthProviderConstants; import io.cloudbeaver.model.app.WebApplication; +import io.cloudbeaver.model.config.WebDatabaseConfig; import io.cloudbeaver.registry.WebAuthProviderDescriptor; import io.cloudbeaver.registry.WebAuthProviderRegistry; import io.cloudbeaver.utils.WebAppUtils; diff --git a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/internal/utils/DBConfigurationUtils.java b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/internal/utils/DBConfigurationUtils.java index 8d1ac5d980..d025c18221 100644 --- a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/internal/utils/DBConfigurationUtils.java +++ b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/internal/utils/DBConfigurationUtils.java @@ -16,7 +16,7 @@ */ package io.cloudbeaver.service.security.internal.utils; -import io.cloudbeaver.service.security.db.WebDatabaseConfig; +import io.cloudbeaver.model.config.WebDatabaseConfig; import org.jkiss.code.Nullable; import org.jkiss.utils.CommonUtils;