diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/service/security/SMUtils.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/service/security/SMUtils.java index 253da6abc0..508d3f61be 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/service/security/SMUtils.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/service/security/SMUtils.java @@ -15,16 +15,25 @@ import java.util.ArrayList; import java.util.Comparator; import java.util.List; +import java.util.Set; public class SMUtils { public static boolean isAdmin(SMCredentialsProvider webSession) { return webSession.hasPermission(DBWConstants.PERMISSION_ADMIN); } + public static boolean isAdmin(@NotNull Set permissions) { + return permissions.contains(DBWConstants.PERMISSION_ADMIN); + } + public static boolean isRMAdmin(SMCredentialsProvider webSession) { return isAdmin(webSession) || webSession.hasPermission(RMConstants.PERMISSION_RM_ADMIN); } + public static boolean isRMAdmin(@NotNull Set permissions) { + return isAdmin(permissions) || permissions.contains(RMConstants.PERMISSION_RM_ADMIN); + } + public static boolean hasProjectPermission( SMCredentialsProvider credentialsProvider, RMProject project, diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/WSSubjectPermissionUpdatedEventHandler.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/WSSubjectPermissionUpdatedEventHandler.java index c5946411fb..d71b7131ae 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/WSSubjectPermissionUpdatedEventHandler.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/WSSubjectPermissionUpdatedEventHandler.java @@ -17,6 +17,7 @@ package io.cloudbeaver.server.events; import io.cloudbeaver.model.session.BaseWebSession; +import io.cloudbeaver.service.security.SMUtils; import org.jkiss.code.NotNull; import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.Log; @@ -24,11 +25,14 @@ import org.jkiss.utils.ArrayUtils; import org.jkiss.utils.CommonUtils; +import java.util.HashSet; + public class WSSubjectPermissionUpdatedEventHandler extends WSDefaultEventHandler { private static final Log log = Log.getLog(WSSubjectPermissionUpdatedEventHandler.class); @Override protected void updateSessionData(@NotNull BaseWebSession activeUserSession, @NotNull WSSubjectPermissionEvent event) { + var oldUserPermissions = new HashSet<>(activeUserSession.getUserContext().getUserPermissions()); try { activeUserSession.getUserContext().refreshSMSession(); } catch (DBException e) { @@ -36,7 +40,11 @@ protected void updateSessionData(@NotNull BaseWebSession activeUserSession, @Not log.error("Error refreshing session", e); } activeUserSession.refreshUserData(); - super.updateSessionData(activeUserSession, event); + var newUserPermissions = activeUserSession.getUserContext().getUserPermissions(); + boolean shouldUpdateData = !(SMUtils.isRMAdmin(oldUserPermissions) && SMUtils.isRMAdmin(newUserPermissions)); + if (shouldUpdateData) { + super.updateSessionData(activeUserSession, event); + } } @Override 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 15cf7769e7..875de6b57d 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 @@ -216,13 +216,7 @@ public void setUserTeams(String userId, String[] teamIds, String grantorId) thro } catch (SQLException e) { throw new DBCException("Error saving user teams in database", e); } - var event = WSSubjectPermissionEvent.update( - getSmSessionId(), - getUserId(), - SMSubjectType.user, - userId - ); - application.getEventController().addEvent(event); + addSubjectPermissionsUpdateEvent(userId, SMSubjectType.user); } @@ -599,13 +593,7 @@ public void setUserAuthRole(@NotNull String userId, @Nullable String authRole) t } catch (SQLException e) { throw new DBCException("Error while updating user authentication role", e); } - var event = WSSubjectPermissionEvent.update( - getSmSessionId(), - getUserId(), - SMSubjectType.user, - userId - ); - application.getEventController().addEvent(event); + addSubjectPermissionsUpdateEvent(userId, SMSubjectType.user); } @@ -1040,13 +1028,7 @@ public void deleteTeam(String teamId, boolean force) throws DBCException { throw new DBCException("Error deleting team from database", e); } if (force) { - var event = WSSubjectPermissionEvent.update( - getSmSessionId(), - getUserId(), - SMSubjectType.team, - teamId - ); - application.getEventController().addEvent(event); + addSubjectPermissionsUpdateEvent(teamId, SMSubjectType.team); } } @@ -1082,6 +1064,7 @@ public void setSubjectPermissions(String subjectId, List permissionIds, } catch (SQLException e) { throw new DBCException("Error saving subject permissions in database", e); } + addSubjectPermissionsUpdateEvent(subjectId, null); } private void insertPermissions(Connection dbCon, String subjectId, String[] permissionIds, String grantorId) throws SQLException { @@ -2231,6 +2214,7 @@ public void setObjectPermissions( @NotNull String grantor ) throws DBException { if (CommonUtils.isEmpty(objectIds)) { + subjectIds.forEach(id -> addSubjectPermissionsUpdateEvent(id, null)); return; } else if (CommonUtils.isEmpty(subjectIds)) { addObjectPermissionsUpdateEvent(objectIds, objectType); @@ -2280,6 +2264,25 @@ public void setObjectPermissions( } } + + + private void addSubjectPermissionsUpdateEvent(@NotNull String subjectId, @Nullable SMSubjectType subjectType) { + if (subjectType == null) { + subjectType = getSubjectType(subjectId); + } + if (subjectType == null) { + log.error("Subject type is not found for subject '" + subjectId + "'"); + return; + } + var event = WSSubjectPermissionEvent.update( + getSmSessionId(), + getUserId(), + subjectType, + subjectId + ); + application.getEventController().addEvent(event); + } + private void addObjectPermissionsUpdateEvent(@NotNull Set objectIds, @NotNull SMObjectType objectType) { for (var objectId : objectIds) { var event = WSObjectPermissionEvent.update( @@ -2625,7 +2628,7 @@ public Set getFilteredSubjects(Set allSubjects) { result.add(dbResult.getString(1)); } } - }; + } return result; } catch (SQLException e) { log.error("Error getting all subject ids from database", e); @@ -2633,6 +2636,25 @@ 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); + try (ResultSet dbResult = dbStat.executeQuery()) { + if (dbResult.next()) { + return SMSubjectType.fromCode(dbResult.getString(1)); + } + } + } + return null; + } catch (SQLException e) { + log.error("Error getting all subject ids from database", e); + return null; + } + } + @Nullable private String getSmSessionId() { var credentials = credentialsProvider.getActiveUserCredentials();