diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/DBWSecurityController.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/DBWSecurityController.java index 37c2f60b4b..8240e93406 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/DBWSecurityController.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/DBWSecurityController.java @@ -21,6 +21,7 @@ import io.cloudbeaver.model.user.WebRole; import io.cloudbeaver.model.user.WebUser; import io.cloudbeaver.registry.WebAuthProviderDescriptor; import io.cloudbeaver.server.CBPlatform; +import org.jkiss.code.NotNull; import org.jkiss.dbeaver.model.exec.DBCException; import java.util.Map; @@ -52,7 +53,8 @@ public interface DBWSecurityController { * Find user with matching credentials. * It doesn't check credentials like passwords, just searches user id by identifying credentials. */ - String findUserByCredentials(WebAuthProviderDescriptor authProvider, Map authParameters) throws DBCException; + @NotNull + String getUserByCredentials(WebAuthProviderDescriptor authProvider, Map authParameters) throws DBCException; /** * Get user credentials for specified provider diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBSecurityController.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBSecurityController.java index 189007cbab..61f1195db8 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBSecurityController.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBSecurityController.java @@ -17,12 +17,14 @@ package io.cloudbeaver.server; import io.cloudbeaver.DBWSecurityController; +import io.cloudbeaver.DBWebException; import io.cloudbeaver.model.session.WebSession; import io.cloudbeaver.model.user.WebRole; import io.cloudbeaver.model.user.WebUser; import io.cloudbeaver.registry.WebAuthProviderDescriptor; import io.cloudbeaver.registry.WebAuthProviderPropertyDescriptor; import io.cloudbeaver.registry.WebAuthProviderPropertyEncryption; +import org.jkiss.code.NotNull; import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.model.exec.DBCException; import org.jkiss.dbeaver.model.impl.jdbc.JDBCUtils; @@ -40,6 +42,9 @@ class CBSecurityController implements DBWSecurityController { private static final Log log = Log.getLog(CBSecurityController.class); + public static final String CHAR_BOOL_TRUE = "Y"; + public static final String CHAR_BOOL_FALSE = "N"; + private final CBDatabase database; CBSecurityController(CBDatabase database) { @@ -54,7 +59,7 @@ class CBSecurityController implements DBWSecurityController { try (Connection dbCon = database.openConnection()) { try (PreparedStatement dbStat = dbCon.prepareStatement("INSERT INTO CB_USER(USER_ID,IS_ACTIVE,CREATE_TIME) VALUES(?,?,?)")) { dbStat.setString(1, user.getUserId()); - dbStat.setString(2, "Y"); + dbStat.setString(2, CHAR_BOOL_TRUE); dbStat.setTimestamp(3, new Timestamp(System.currentTimeMillis())); dbStat.execute(); } @@ -130,8 +135,9 @@ class CBSecurityController implements DBWSecurityController { } } + @NotNull @Override - public String findUserByCredentials(WebAuthProviderDescriptor authProvider, Map authParameters) throws DBCException { + public String getUserByCredentials(WebAuthProviderDescriptor authProvider, Map authParameters) throws DBCException { Map identCredentials = new LinkedHashMap<>(); for (WebAuthProviderPropertyDescriptor prop : authProvider.getProperties()) { if (prop.isIdentifying()) { @@ -150,35 +156,49 @@ class CBSecurityController implements DBWSecurityController { throw new DBCException("No identifying credentials in provider '" + authProvider.getId() + "'"); } StringBuilder sql = new StringBuilder(); - sql.append("SELECT UC.USER_ID FROM CB_USER_CREDENTIALS UC\n"); + sql.append("SELECT U.USER_ID,U.IS_ACTIVE FROM CB_USER U,CB_USER_CREDENTIALS UC\n"); + for (int joinNum = 0; joinNum < identCredentials.size() - 1; joinNum++) { + sql.append(",CB_USER_CREDENTIALS UC").append(joinNum + 2); + } + sql.append("WHERE U.USER_ID=UC.USER_ID AND UC.PROVIDER_ID=? AND UC.CRED_ID=? AND UC.CRED_VALUE=?"); for (int joinNum = 0; joinNum < identCredentials.size() - 1; joinNum++) { String joinAlias = "UC" + (joinNum + 2); - sql.append(",CB_USER_CREDENTIALS ").append(joinAlias).append(" ON ") + sql.append(" AND ") .append(joinAlias).append(".USER_ID=UC.USER_ID") .append(joinAlias).append(".PROVIDER_ID=UC.PROVIDER_ID AND ") .append(joinAlias).append("CRED_ID=? AND ") .append(joinAlias).append("CRED_VALUE=?"); } - sql.append("WHERE UC.CRED_ID=? AND UC.CRED_VALUE=? AND UC.PROVIDER_ID=?"); try (Connection dbCon = database.openConnection()) { try (PreparedStatement dbStat = dbCon.prepareStatement(sql.toString())) { - int param = 1; + dbStat.setString(1, authProvider.getId()); + int param = 2; for (Map.Entry credEntry : identCredentials.entrySet()) { dbStat.setString(param++, credEntry.getKey()); dbStat.setString(param++, CommonUtils.toString(credEntry.getValue())); } - dbStat.setString(param, authProvider.getId()); try (ResultSet dbResult = dbStat.executeQuery()) { String userId = null; + boolean isActive = false; while (dbResult.next()) { String credUserId = dbResult.getString(1); + isActive = CHAR_BOOL_TRUE.equals(dbResult.getString(2)); if (userId == null) { userId = credUserId; } else if (!userId.equals(credUserId)) { log.error("Multiple users associated with the same credentials! " + credUserId + ", " + userId); } } + + if (userId == null) { + // User doesn't exist. We can create new user automatically if auth provider supports this + throw new DBCException("Invalid user credentials"); + } + if (!isActive) { + throw new DBCException("User account is locked"); + } + return userId; } } diff --git a/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/impl/WebServiceAuthImpl.java b/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/impl/WebServiceAuthImpl.java index bb21727fb4..f879d65d17 100644 --- a/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/impl/WebServiceAuthImpl.java +++ b/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/impl/WebServiceAuthImpl.java @@ -48,11 +48,7 @@ public class WebServiceAuthImpl implements DBWServiceAuth { } DBWSecurityController serverController = CBPlatform.getInstance().getApplication().getSecurityController(); try { - String userId = serverController.findUserByCredentials(authProvider, authParameters); - if (userId == null) { - // User doesn't exist. We can create new user automatically if auth provider supports this - throw new DBWebException("Invalid user credentials"); - } + String userId = serverController.getUserByCredentials(authProvider, authParameters); Map userCredentials = serverController.getUserCredentials(userId, authProvider); Object authToken = authProvider.getInstance().openSession( Collections.emptyMap(),