From 9fce0c897b03d484da15427164ea892491d57f46 Mon Sep 17 00:00:00 2001 From: Alexander Skoblikov Date: Tue, 7 Nov 2023 15:33:15 +0100 Subject: [PATCH 1/3] CB-3971 validate main session (#2106) Co-authored-by: Daria Marutkina <125263541+dariamarutkina@users.noreply.github.com> --- .../db/cb_schema_create.sql | 2 +- .../db/cb_schema_update_14.sql | 2 + .../CBEmbeddedSecurityController.java | 70 ++++++++++++------- .../service/security/db/CBDatabase.java | 2 +- .../internal/AuthAttemptSessionInfo.java | 9 ++- 5 files changed, 57 insertions(+), 28 deletions(-) create mode 100644 server/bundles/io.cloudbeaver.service.security/db/cb_schema_update_14.sql diff --git a/server/bundles/io.cloudbeaver.service.security/db/cb_schema_create.sql b/server/bundles/io.cloudbeaver.service.security/db/cb_schema_create.sql index febb3482c3..300af38bdb 100644 --- a/server/bundles/io.cloudbeaver.service.security/db/cb_schema_create.sql +++ b/server/bundles/io.cloudbeaver.service.security/db/cb_schema_create.sql @@ -276,7 +276,7 @@ CREATE TABLE {table_prefix}CB_AUTH_ATTEMPT SESSION_ID VARCHAR(64), SESSION_TYPE VARCHAR(64) NOT NULL, APP_SESSION_STATE TEXT NOT NULL, - + IS_MAIN_AUTH CHAR(1) DEFAULT 'Y' NOT NULL, CREATE_TIME TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, PRIMARY KEY (AUTH_ID), diff --git a/server/bundles/io.cloudbeaver.service.security/db/cb_schema_update_14.sql b/server/bundles/io.cloudbeaver.service.security/db/cb_schema_update_14.sql new file mode 100644 index 0000000000..39927e4dd4 --- /dev/null +++ b/server/bundles/io.cloudbeaver.service.security/db/cb_schema_update_14.sql @@ -0,0 +1,2 @@ +ALTER TABLE {table_prefix}CB_AUTH_ATTEMPT + ADD COLUMN IS_MAIN_AUTH CHAR(1) DEFAULT 'Y' NOT NULL; \ No newline at end of file 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 b96cb165e3..47dd7cf7c5 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 @@ -1289,9 +1289,9 @@ public SMAuthInfo authenticate( throw new SMException("Unsupported authentication provider: " + authProviderId); } var authProgressMonitor = new LoggingProgressMonitor(log); + boolean isMainSession = previousSmSessionId == null; try (Connection dbCon = database.openConnection()) { try (JDBCTransaction txn = new JDBCTransaction(dbCon)) { - boolean isMainSession = previousSmSessionId == null; Map securedUserIdentifyingCredentials = userCredentials; WebAuthProviderDescriptor authProviderDescriptor = getAuthProvider(authProviderId); var authProviderInstance = authProviderDescriptor.getInstance(); @@ -1334,7 +1334,7 @@ public SMAuthInfo authenticate( String signOutLink = authProviderFederated.getSignOutLink(authProviderConfigurationId, Map.of()); Map authData = Map.of(new SMAuthConfigurationReference(authProviderId, authProviderConfigurationId), filteredUserCreds); - return SMAuthInfo.inProgress(authAttemptId, signInLink, signOutLink, authData); + return SMAuthInfo.inProgress(authAttemptId, signInLink, signOutLink, authData, isMainSession); } txn.commit(); return finishAuthentication( @@ -1342,7 +1342,9 @@ public SMAuthInfo authenticate( authAttemptId, null, null, - Map.of(new SMAuthConfigurationReference(authProviderId, authProviderConfigurationId), securedUserIdentifyingCredentials) + Map.of(new SMAuthConfigurationReference(authProviderId, authProviderConfigurationId), + securedUserIdentifyingCredentials), + isMainSession ), true, false @@ -1385,8 +1387,9 @@ private String createNewAuthAttempt( try (PreparedStatement dbStat = dbCon.prepareStatement( database.normalizeTableNames( "INSERT INTO {table_prefix}CB_AUTH_ATTEMPT" + - "(AUTH_ID,AUTH_STATUS,APP_SESSION_ID,SESSION_TYPE,APP_SESSION_STATE,SESSION_ID) " + - "VALUES(?,?,?,?,?,?)" + "(AUTH_ID,AUTH_STATUS,APP_SESSION_ID,SESSION_TYPE,APP_SESSION_STATE," + + "SESSION_ID,IS_MAIN_AUTH) " + + "VALUES(?,?,?,?,?,?,?)" ) )) { dbStat.setString(1, authAttemptId); @@ -1399,6 +1402,7 @@ private String createNewAuthAttempt( } else { dbStat.setNull(6, Types.VARCHAR); } + dbStat.setString(7, isMainSession ? CHAR_BOOL_TRUE : CHAR_BOOL_FALSE); dbStat.execute(); } @@ -1518,9 +1522,11 @@ private SMAuthInfo getAuthStatus(@NotNull String authId, boolean readExpiredData SMAuthStatus smAuthStatus; String authError; String smSessionId; + boolean isMainAuth; try (PreparedStatement dbStat = dbCon.prepareStatement( database.normalizeTableNames( - "SELECT AUTH_STATUS,AUTH_ERROR,SESSION_ID FROM {table_prefix}CB_AUTH_ATTEMPT WHERE AUTH_ID=?" + "SELECT AUTH_STATUS,AUTH_ERROR,SESSION_ID,IS_MAIN_AUTH FROM {table_prefix}CB_AUTH_ATTEMPT WHERE " + + "AUTH_ID=?" ) )) { dbStat.setString(1, authId); @@ -1531,6 +1537,7 @@ private SMAuthInfo getAuthStatus(@NotNull String authId, boolean readExpiredData smAuthStatus = SMAuthStatus.valueOf(dbResult.getString(1)); authError = dbResult.getString(2); smSessionId = dbResult.getString(3); + isMainAuth = CHAR_BOOL_TRUE.equals(dbResult.getString(4)); } } Map authData = new LinkedHashMap<>(); @@ -1571,11 +1578,11 @@ private SMAuthInfo getAuthStatus(@NotNull String authId, boolean readExpiredData if (smAuthStatus != SMAuthStatus.SUCCESS) { switch (smAuthStatus) { case IN_PROGRESS: - return SMAuthInfo.inProgress(authId, signInLink, signOutLink, authData); + return SMAuthInfo.inProgress(authId, signInLink, signOutLink, authData, isMainAuth); case ERROR: - return SMAuthInfo.error(authId, authError); + return SMAuthInfo.error(authId, authError, isMainAuth); case EXPIRED: - return SMAuthInfo.expired(authId, readExpiredData ? authData : Map.of()); + return SMAuthInfo.expired(authId, readExpiredData ? authData : Map.of(), isMainAuth); default: throw new SMException("Unknown auth status:" + smAuthStatus); } @@ -1583,16 +1590,21 @@ private SMAuthInfo getAuthStatus(@NotNull String authId, boolean readExpiredData SMTokens smTokens = findTokenBySmSession(smSessionId); SMAuthPermissions authPermissions = getTokenPermissions(smTokens.getSmAccessToken()); - String authRole = readTokenAuthRole(smTokens.getSmAccessToken()); - var successAuthStatus = SMAuthInfo.successMainSession( - authId, - smTokens.getSmAccessToken(), - smTokens.getSmRefreshToken(), - authPermissions, - authData, - authRole - ); - return successAuthStatus; + + if (isMainAuth) { + String authRole = readTokenAuthRole(smTokens.getSmAccessToken()); + return SMAuthInfo.successMainSession( + authId, + smTokens.getSmAccessToken(), + smTokens.getSmRefreshToken(), + authPermissions, + authData, + authRole + ); + } else { + //TODO remove permissions from child session + return SMAuthInfo.successChildSession(authId, authPermissions, authData); + } } catch (SQLException e) { throw new DBException("Error while read auth info", e); } @@ -1792,7 +1804,7 @@ private SMAuthInfo finishAuthentication( DBRProgressMonitor finishAuthMonitor = new LoggingProgressMonitor(log); AuthAttemptSessionInfo authAttemptSessionInfo = readAuthAttemptSessionInfo(authId); - boolean isMainAuthSession = authAttemptSessionInfo.getSmSessionId() == null; + boolean isMainAuthSession = authAttemptSessionInfo.isMainAuth(); SMTokens smTokens = null; SMAuthPermissions permissions = null; @@ -1850,7 +1862,7 @@ private SMAuthInfo finishAuthentication( if (userIdFromCreds == null) { var error = "Invalid user credentials"; updateAuthStatus(authId, SMAuthStatus.ERROR, storedUserData, error); - return SMAuthInfo.error(authId, error); + return SMAuthInfo.error(authId, error, isMainAuthSession); } if (autoAssign != null && !CommonUtils.isEmpty(autoAssign.getExternalTeamIds())) { @@ -2036,8 +2048,9 @@ protected String updateUserAuthRoleIfNeeded(@Nullable String userId, @Nullable S private AuthAttemptSessionInfo readAuthAttemptSessionInfo(@NotNull String authId) throws DBException { try (Connection dbCon = database.openConnection()) { try (PreparedStatement dbStat = dbCon.prepareStatement( - database.normalizeTableNames("SELECT APP_SESSION_ID,SESSION_TYPE,APP_SESSION_STATE,SESSION_ID FROM " + - "{table_prefix}CB_AUTH_ATTEMPT WHERE AUTH_ID=?") + database.normalizeTableNames( + "SELECT APP_SESSION_ID,SESSION_TYPE,APP_SESSION_STATE,SESSION_ID,IS_MAIN_AUTH " + + "FROM {table_prefix}CB_AUTH_ATTEMPT WHERE AUTH_ID=?") )) { dbStat.setString(1, authId); try (ResultSet dbResult = dbStat.executeQuery()) { @@ -2050,8 +2063,15 @@ private AuthAttemptSessionInfo readAuthAttemptSessionInfo(@NotNull String authId dbResult.getString(3), MAP_STRING_OBJECT_TYPE ); String smSessionId = dbResult.getString(4); - - return new AuthAttemptSessionInfo(appSessionId, smSessionId, sessionType, sessionParams); + boolean isMainAuth = CHAR_BOOL_TRUE.equals(dbResult.getString(5)); + + return new AuthAttemptSessionInfo( + appSessionId, + smSessionId, + sessionType, + sessionParams, + isMainAuth + ); } } } catch (SQLException e) { 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 5ce47a1c59..ff14ecb78a 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 @@ -72,7 +72,7 @@ public class CBDatabase { public static final String SCHEMA_UPDATE_SQL_PATH = "db/cb_schema_update_"; private static final int LEGACY_SCHEMA_VERSION = 1; - private static final int CURRENT_SCHEMA_VERSION = 13; + private static final int CURRENT_SCHEMA_VERSION = 14; private static final String DEFAULT_DB_USER_NAME = "cb-data"; private static final String DEFAULT_DB_PWD_FILE = ".database-credentials.dat"; diff --git a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/internal/AuthAttemptSessionInfo.java b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/internal/AuthAttemptSessionInfo.java index 24c7803483..7354896a78 100644 --- a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/internal/AuthAttemptSessionInfo.java +++ b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/internal/AuthAttemptSessionInfo.java @@ -33,17 +33,20 @@ public class AuthAttemptSessionInfo { private final SMSessionType sessionType; @NotNull private final Map sessionParams; + private final boolean mainAuth; public AuthAttemptSessionInfo( @NotNull String appSessionId, @Nullable String smSessionId, @NotNull SMSessionType sessionType, - @NotNull Map sessionParams + @NotNull Map sessionParams, + boolean mainAuth ) { this.appSessionId = appSessionId; this.smSessionId = smSessionId; this.sessionType = sessionType; this.sessionParams = sessionParams; + this.mainAuth = mainAuth; } @NotNull @@ -65,4 +68,8 @@ public Map getSessionParams() { public String getSmSessionId() { return smSessionId; } + + public boolean isMainAuth() { + return mainAuth; + } } From 067f79dca4d5d54b417547800e7833a4a266bcf6 Mon Sep 17 00:00:00 2001 From: DenisSinelnikov <142215442+DenisSinelnikov@users.noreply.github.com> Date: Wed, 8 Nov 2023 18:50:27 +0400 Subject: [PATCH 2/3] CB-4181. Remove default login password for admin (#2107) * CB-4181. Remove default login password for admin * CB-4181. Revert logic for delete old admin --------- Co-authored-by: Evgenia Bezborodova <139753579+EvgeniaBzzz@users.noreply.github.com> --- .../service/security/db/CBDatabaseInitialData.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/db/CBDatabaseInitialData.java b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/db/CBDatabaseInitialData.java index 366526767d..3967c750e9 100644 --- a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/db/CBDatabaseInitialData.java +++ b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/db/CBDatabaseInitialData.java @@ -21,8 +21,8 @@ import java.util.List; class CBDatabaseInitialData { - private String adminName = "cbadmin"; - private String adminPassword = "cbadmin20"; + private String adminName; + private String adminPassword; private List teams; public String getAdminName() { From 792b2725e0dd1491a198517629842215c2a7c502 Mon Sep 17 00:00:00 2001 From: Alexander Skoblikov Date: Thu, 9 Nov 2023 16:55:10 +0100 Subject: [PATCH 3/3] fix logging in tests (#2118) --- server/test/pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server/test/pom.xml b/server/test/pom.xml index ab27553b55..50428010b9 100644 --- a/server/test/pom.xml +++ b/server/test/pom.xml @@ -31,6 +31,11 @@ ch.qos.logback.classic 0.0.0 + + eclipse-feature + io.cloudbeaver.ws.feature + 0.0.0 +