diff --git a/server/bundles/io.cloudbeaver.model/plugin.xml b/server/bundles/io.cloudbeaver.model/plugin.xml index ec0dd5a019..69dc8712a8 100644 --- a/server/bundles/io.cloudbeaver.model/plugin.xml +++ b/server/bundles/io.cloudbeaver.model/plugin.xml @@ -9,4 +9,13 @@ + + + + + + + + + diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebSessionAuthProcessor.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebSessionAuthProcessor.java index 2878925b5d..30ac07e8d2 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebSessionAuthProcessor.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebSessionAuthProcessor.java @@ -127,7 +127,7 @@ public class WebSessionAuthProcessor { if (authProviderExternal != null && !configMode && !alreadyLoggedIn) { // We may need to associate new credentials with active user if (linkWithActiveUser) { - securityController.setUserCredentials(authProviderDescriptor.getId(), authAttrs); + securityController.setCurrentUserCredentials(authProviderDescriptor.getId(), authAttrs); } } diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebMetaParametersRegistry.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebMetaParametersRegistry.java index c8f11f6211..969df76824 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebMetaParametersRegistry.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebMetaParametersRegistry.java @@ -22,6 +22,7 @@ import org.eclipse.core.runtime.Platform; import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.model.impl.PropertyDescriptor; import org.jkiss.dbeaver.model.preferences.DBPPropertyDescriptor; +import org.jkiss.dbeaver.model.security.SMSubjectType; import org.jkiss.utils.ArrayUtils; import java.util.ArrayList; @@ -56,6 +57,10 @@ public class WebMetaParametersRegistry { return teamParameters; } + public List getMetaParameters(SMSubjectType subjectType) { + return subjectType == SMSubjectType.user ? userParameters : teamParameters; + } + private void loadExtensions(IExtensionRegistry registry) { IConfigurationElement[] extConfigs = registry.getConfigurationElementsFor(EXTENSION_ID); for (IConfigurationElement ext : extConfigs) { diff --git a/server/bundles/io.cloudbeaver.service.auth/plugin.xml b/server/bundles/io.cloudbeaver.service.auth/plugin.xml index 36baf6d3c9..01901218ac 100644 --- a/server/bundles/io.cloudbeaver.service.auth/plugin.xml +++ b/server/bundles/io.cloudbeaver.service.auth/plugin.xml @@ -8,14 +8,6 @@ - - - - - - - - diff --git a/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/WebUserInfo.java b/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/WebUserInfo.java index dd2d72482b..37c7576898 100644 --- a/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/WebUserInfo.java +++ b/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/WebUserInfo.java @@ -70,7 +70,7 @@ public class WebUserInfo { public List getLinkedAuthProviders() throws DBWebException { if (linkedProviders == null) { try { - linkedProviders = session.getSecurityController().getUserLinkedProviders(); + linkedProviders = session.getSecurityController().getCurrentUserLinkedProviders(); } catch (DBException e) { throw new DBWebException("Error reading user linked providers", e); } @@ -86,7 +86,7 @@ public class WebUserInfo { @Property public Map getConfigurationParameters() throws DBWebException { try { - return session.getSecurityController().getUserParameters(); + return session.getSecurityController().getCurrentUserParameters(); } catch (DBException e) { throw new DBWebException("Error reading user parameters", e); } 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 949ba5fb1e..c3ad3a9d05 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 @@ -216,7 +216,7 @@ public class WebServiceAuthImpl implements DBWServiceAuth { ) throws DBWebException { webSession.addInfoMessage("Set user parameter - " + name); try { - webSession.getSecurityController().setUserParameter(name, value); + webSession.getSecurityController().setCurrentUserParameter(name, value); return true; } catch (DBException e) { throw new DBWebException("Error setting user parameter", e); diff --git a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/auth/provider/local/LocalAuthProvider.java b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/auth/provider/local/LocalAuthProvider.java index c42e0cf928..f64e374ede 100644 --- a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/auth/provider/local/LocalAuthProvider.java +++ b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/auth/provider/local/LocalAuthProvider.java @@ -115,7 +115,7 @@ public class LocalAuthProvider implements SMAuthProvider { //String newPasswordHash = WebAuthProviderPropertyEncryption.hash.encrypt(userName, newPassword); storedCredentials.put(CRED_PASSWORD, newPassword); - webSession.getSecurityController().setUserCredentials(authProvider.getId(), storedCredentials); + webSession.getSecurityController().setCurrentUserCredentials(authProvider.getId(), storedCredentials); return true; } 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 9e5701850b..a916ccba2d 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 @@ -24,12 +24,14 @@ import io.cloudbeaver.auth.SMAuthProviderAssigner; import io.cloudbeaver.auth.SMAuthProviderExternal; import io.cloudbeaver.auth.SMAuthProviderFederated; import io.cloudbeaver.auth.SMAutoAssign; +import io.cloudbeaver.model.app.WebAppConfiguration; import io.cloudbeaver.model.app.WebApplication; import io.cloudbeaver.model.app.WebAuthApplication; import io.cloudbeaver.model.app.WebAuthConfiguration; import io.cloudbeaver.model.session.WebAuthInfo; import io.cloudbeaver.registry.WebAuthProviderDescriptor; import io.cloudbeaver.registry.WebAuthProviderRegistry; +import io.cloudbeaver.registry.WebMetaParametersRegistry; import io.cloudbeaver.service.security.db.CBDatabase; import io.cloudbeaver.service.security.internal.AuthAttemptSessionInfo; import io.cloudbeaver.service.security.internal.SMTokenInfo; @@ -42,6 +44,7 @@ import org.jkiss.dbeaver.model.auth.*; import org.jkiss.dbeaver.model.exec.DBCException; import org.jkiss.dbeaver.model.impl.jdbc.JDBCUtils; import org.jkiss.dbeaver.model.impl.jdbc.exec.JDBCTransaction; +import org.jkiss.dbeaver.model.preferences.DBPPropertyDescriptor; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; import org.jkiss.dbeaver.model.runtime.LoggingProgressMonitor; import org.jkiss.dbeaver.model.security.*; @@ -118,6 +121,9 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen boolean enabled, @Nullable String defaultAuthRole ) throws DBException { + if (CommonUtils.isEmpty(userId)) { + throw new DBCException("Empty user name is not allowed"); + } if (isSubjectExists(userId)) { throw new DBCException("User or team '" + userId + "' already exists"); } @@ -203,9 +209,23 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen } } + private static Set getAllLinkedSubjects(Connection dbCon, String subjectId) throws SQLException { + Set allSubjects = new HashSet<>(); + allSubjects.add(subjectId); + try (PreparedStatement dbStat = dbCon.prepareStatement("SELECT TEAM_ID FROM CB_USER_TEAM UR WHERE USER_ID=?")) { + dbStat.setString(1, subjectId); + try (ResultSet dbResult = dbStat.executeQuery()) { + while (dbResult.next()) { + allSubjects.add(dbResult.getString(1)); + } + } + } + return allSubjects; + } + @NotNull @Override - public SMTeam[] getUserTeams() throws DBException { + public SMTeam[] getCurrentUserTeams() throws DBException { return getUserTeams(getUserIdOrThrow()); } @@ -363,7 +383,7 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen } @Override - public Map getUserParameters() throws DBCException { + public Map getCurrentUserParameters() throws DBCException { String userId = getUserIdOrThrow(); try (Connection dbCon = database.openConnection()) { Map result = new LinkedHashMap<>(); @@ -385,7 +405,7 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen } @Override - public void setUserParameter(String name, Object value) throws DBException { + public void setCurrentUserParameter(String name, Object value) throws DBException { String userId = getUserIdOrThrow(); try (Connection dbCon = database.openConnection()) { try (JDBCTransaction txn = new JDBCTransaction(dbCon)) { @@ -478,7 +498,7 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen } @Override - public void setUserCredentials( + public void setCurrentUserCredentials( @NotNull String authProviderId, @NotNull Map credentials ) throws DBException { @@ -639,12 +659,12 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen @NotNull @Override - public Map getUserCredentials(@NotNull String authProviderId) throws DBException { + public Map getCurrentUserCredentials(@NotNull String authProviderId) throws DBException { return getUserCredentials(getUserIdOrThrow(), authProviderId); } @Override - public String[] getUserLinkedProviders() throws DBException { + public String[] getCurrentUserLinkedProviders() throws DBException { return getUserLinkedProviders(getUserIdOrThrow()); } @@ -671,6 +691,32 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen } } + @NotNull + @Override + public SMPropertyDescriptor[] getMetaParametersBySubjectType(SMSubjectType subjectType) throws DBException { + // First add global metas + List props = new ArrayList<>( + WebMetaParametersRegistry.getInstance().getMetaParameters(subjectType)); + + // Add metas from enabled auth providers + WebAppConfiguration appConfiguration = WebAppUtils.getWebApplication().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); + } + } + } + } + + return props.stream() + .map(SMPropertyDescriptor::new) + .toArray(SMPropertyDescriptor[]::new); + } + /////////////////////////////////////////// // Teams @@ -742,6 +788,9 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen @Override public void createTeam(String teamId, String name, String description, String grantor) throws DBCException { + if (CommonUtils.isEmpty(teamId)) { + throw new DBCException("Empty team name is not allowed"); + } if (isSubjectExists(teamId)) { throw new DBCException("User or team '" + teamId + "' already exists"); } @@ -831,12 +880,12 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen // Subject functions @Override - public void setSubjectMetas(String userId, Map metaParameters) throws DBCException { + public void setSubjectMetas(@NotNull String subjectId, @NotNull Map metaParameters) throws DBCException { try (Connection dbCon = database.openConnection()) { try (JDBCTransaction txn = new JDBCTransaction(dbCon)) { - cleanupSubjectMeta(dbCon, userId); + cleanupSubjectMeta(dbCon, subjectId); if (!metaParameters.isEmpty()) { - saveSubjectMetas(dbCon, userId, metaParameters); + saveSubjectMetas(dbCon, subjectId, metaParameters); } txn.commit(); } @@ -1943,10 +1992,10 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen try (Connection dbCon = database.openConnection()) { try (JDBCTransaction txn = new JDBCTransaction(dbCon)) { var sqlBuilder = new StringBuilder("DELETE FROM CB_OBJECT_PERMISSIONS WHERE SUBJECT_ID IN ("); - appendStringParameters(sqlBuilder, subjectIds.toArray(String[]::new)); + appendStringParameters(sqlBuilder, subjectIds); sqlBuilder.append(") AND OBJECT_TYPE=? ") .append("AND OBJECT_ID IN ("); - appendStringParameters(sqlBuilder, objectIds.toArray(String[]::new)); + appendStringParameters(sqlBuilder, objectIds); sqlBuilder.append(")"); JDBCUtils.executeStatement(dbCon, sqlBuilder.toString(), objectType.getObjectType()); if (!CommonUtils.isEmpty(permissions)) { @@ -2019,12 +2068,12 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen public List getAllAvailableObjectsPermissions(@NotNull SMObjectType objectType) throws DBException { String subjectId = getSubjectId(); - Set allSubjects = getAllLinkedSubjects(subjectId); try (Connection dbCon = database.openConnection()) { + Set allSubjects = getAllLinkedSubjects(dbCon, subjectId); { var sqlBuilder = new StringBuilder("SELECT OBJECT_ID,PERMISSION FROM CB_OBJECT_PERMISSIONS "); sqlBuilder.append("WHERE SUBJECT_ID IN ("); - appendStringParameters(sqlBuilder, allSubjects.toArray(String[]::new)); + appendStringParameters(sqlBuilder, allSubjects); sqlBuilder.append(") AND OBJECT_TYPE=?"); try (PreparedStatement dbStat = dbCon.prepareStatement(sqlBuilder.toString())) { dbStat.setString(1, objectType.getObjectType()); @@ -2047,16 +2096,6 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen } } - private Set getAllLinkedSubjects(String subjectId) throws DBException { - Set allSubjects = new HashSet<>(); - allSubjects.add(subjectId); - var userTeamIds = Arrays.stream(getUserTeams(subjectId)) - .map(SMTeam::getTeamId) - .collect(Collectors.toSet()); - allSubjects.addAll(userTeamIds); - return allSubjects; - } - @NotNull @Override public SMObjectPermissions getObjectPermissions( @@ -2064,12 +2103,12 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen @NotNull String objectId, @NotNull SMObjectType objectType ) throws DBException { - Set allSubjects = getAllLinkedSubjects(subjectId); try (Connection dbCon = database.openConnection()) { + Set allSubjects = getAllLinkedSubjects(dbCon, subjectId); { var sqlBuilder = new StringBuilder("SELECT PERMISSION FROM CB_OBJECT_PERMISSIONS "); sqlBuilder.append("WHERE SUBJECT_ID IN ("); - appendStringParameters(sqlBuilder, allSubjects.toArray(String[]::new)); + appendStringParameters(sqlBuilder, allSubjects); sqlBuilder.append(") AND OBJECT_TYPE=? AND OBJECT_ID=?"); try (PreparedStatement dbStat = dbCon.prepareStatement(sqlBuilder.toString())) { @@ -2128,14 +2167,14 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen @Override public List getSubjectObjectPermissionGrants(@NotNull String subjectId, @NotNull SMObjectType smObjectType) throws DBException { - var allLinkedSubjects = getAllLinkedSubjects(subjectId); var grantedPermissionsByObjectId = new HashMap(); try (Connection dbCon = database.openConnection()) { + var allLinkedSubjects = getAllLinkedSubjects(dbCon, subjectId); var sqlBuilder = new StringBuilder("SELECT OP.OBJECT_ID,S.SUBJECT_TYPE,S.SUBJECT_ID,OP.PERMISSION\n") .append("FROM CB_OBJECT_PERMISSIONS OP,CB_AUTH_SUBJECT S\n") .append("WHERE S.SUBJECT_ID = OP.SUBJECT_ID AND OP.SUBJECT_ID IN ("); - appendStringParameters(sqlBuilder, allLinkedSubjects.toArray(String[]::new)); + appendStringParameters(sqlBuilder, allLinkedSubjects); sqlBuilder.append(") AND OP.OBJECT_TYPE=?"); try (PreparedStatement dbStat = dbCon.prepareStatement(sqlBuilder.toString())) { dbStat.setString(1, smObjectType.getObjectType()); @@ -2161,10 +2200,11 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen } } - private void appendStringParameters(StringBuilder sql, @NotNull String[] subjectIds) { - for (int i = 0; i < subjectIds.length; i++) { - String id = subjectIds[i]; - if (i > 0) sql.append(","); + private static void appendStringParameters(StringBuilder sql, @NotNull Collection subjectIds) { + boolean first = true; + for (String id : subjectIds) { + if (!first) sql.append(","); + first = false; sql.append("'").append(id.replace("'", "''")).append("'"); } }