CB-3945 add subject permissions changed events (#1974)

* CB-3945 add subject permissions changed events

* CB-3945 remove parameter from subject event

* CB-3945 code style fix

* CB-3945 check rm admin permission

---------

Co-authored-by: EvgeniaBzzz <139753579+EvgeniaBzzz@users.noreply.github.com>
This commit is contained in:
Ainur
2023-09-20 19:45:10 +03:00
committed by GitHub
co-authored by EvgeniaBzzz
parent 8a685ef47e
commit 1a434adb3d
3 changed files with 62 additions and 23 deletions
@@ -15,16 +15,25 @@ import org.jkiss.dbeaver.model.security.exception.SMRefreshTokenExpiredException
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<String> 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<String> permissions) {
return isAdmin(permissions) || permissions.contains(RMConstants.PERMISSION_RM_ADMIN);
}
public static boolean hasProjectPermission(
SMCredentialsProvider credentialsProvider,
RMProject project,
@@ -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.dbeaver.model.websocket.event.permissions.WSSubjectPermissionEv
import org.jkiss.utils.ArrayUtils;
import org.jkiss.utils.CommonUtils;
import java.util.HashSet;
public class WSSubjectPermissionUpdatedEventHandler extends WSDefaultEventHandler<WSSubjectPermissionEvent> {
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 @@ public class WSSubjectPermissionUpdatedEventHandler extends WSDefaultEventHandle
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
@@ -216,13 +216,7 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
} 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 class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
} 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 class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
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 class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
} 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 class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
@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 class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
}
}
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<String> objectIds, @NotNull SMObjectType objectType) {
for (var objectId : objectIds) {
var event = WSObjectPermissionEvent.update(
@@ -2625,7 +2628,7 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
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 class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
}
}
private SMSubjectType getSubjectType(@NotNull String subjectId) {
try (Connection dbCon = database.openConnection()) {
Set<String> 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();