Grant each group access to the corresponding Wallix target group.

This commit is contained in:
2025-11-10 17:51:49 +01:00
parent e1f6f93e02
commit 9465b853db
5 changed files with 111 additions and 5 deletions

View File

@@ -11,6 +11,7 @@ import java.security.cert.X509Certificate;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
@@ -258,6 +259,25 @@ public class Wallix {
return buffer.toString(); return buffer.toString();
} }
public Map<String, Set<String>> getAuthorizations() throws Exception {
String output = get("/authorizations?fields=user_group,target_group");
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(output);
Map<String, Set<String>> result = new HashMap<>();
jsonNode.elements().forEachRemaining((e) -> {
String targetName = e.findValue("target_group").asText();
if (! result.containsKey(targetName)) {
result.put(targetName, new HashSet<>());
}
Set<String> groups = result.get(targetName);
groups.add(e.findValue("user_group").asText());
});
return result;
}
public final class API { public final class API {
public static final String ATTRIBUTE_USER_DISABLED = "is_disabled"; public static final String ATTRIBUTE_USER_DISABLED = "is_disabled";

View File

@@ -11,6 +11,7 @@ import org.apache.guacamole.environment.LocalEnvironment;
import cm.soungui.guacamole.ext.wallix.sync.db.Connection; import cm.soungui.guacamole.ext.wallix.sync.db.Connection;
import cm.soungui.guacamole.ext.wallix.sync.db.DB; import cm.soungui.guacamole.ext.wallix.sync.db.DB;
import cm.soungui.guacamole.ext.wallix.sync.db.Entity.EntityType;
import cm.soungui.guacamole.ext.wallix.sync.db.TargetGroup; import cm.soungui.guacamole.ext.wallix.sync.db.TargetGroup;
import cm.soungui.guacamole.ext.wallix.sync.db.User; import cm.soungui.guacamole.ext.wallix.sync.db.User;
import cm.soungui.guacamole.ext.wallix.sync.db.UserGroup; import cm.soungui.guacamole.ext.wallix.sync.db.UserGroup;
@@ -31,7 +32,6 @@ public class WallixConfigSynchronizer implements Runnable {
public void run() { public void run() {
while (true) { while (true) {
try { try {
System.out.println("Fetching config");
synchronizeUsers(); synchronizeUsers();
synchronizeUserGroups(); synchronizeUserGroups();
synchronizeTargetGroups(); synchronizeTargetGroups();
@@ -116,6 +116,7 @@ public class WallixConfigSynchronizer implements Runnable {
DB db = DB.getInstance(); DB db = DB.getInstance();
Set<TargetGroup> wallixTargetGroups = Wallix.getInstance().getTargetGroups(); Set<TargetGroup> wallixTargetGroups = Wallix.getInstance().getTargetGroups();
Map<String, Set<String>> members = Wallix.getInstance().getAuthorizations();
// Fetch targets from Wallix // Fetch targets from Wallix
for (TargetGroup wallixGroup : wallixTargetGroups) { for (TargetGroup wallixGroup : wallixTargetGroups) {
@@ -176,10 +177,25 @@ public class WallixConfigSynchronizer implements Runnable {
} }
} }
} }
Set<String> membersNames = members.get(wallixGroup.getName());
synchronizeAuthorizations(dbTargetGroup, membersNames);
} }
} }
private void synchronizeAuthorizations(TargetGroup targetGroup, Set<String> members) throws GuacamoleException, Exception {
DB db = DB.getInstance();
Set<Integer> newMembersIds = db.getEntitiesId(members, EntityType.USER_GROUP);
Set<Integer> currentMembersIds = db.getTargetGroupMembersIds(targetGroup.getId());
for (int memberId : newMembersIds.stream().filter(memberId -> ! currentMembersIds.contains(memberId)).toList()) {
db.addTargetGroupMember(targetGroup.getId(), memberId);
}
for (int memberId : currentMembersIds.stream().filter(id -> ! newMembersIds.contains(id)).toList()) {
db.removeTargetGroupMember(targetGroup.getId(), memberId);
}
}
private void printWallixVersion() throws Exception { private void printWallixVersion() throws Exception {
Wallix wallix = Wallix.getInstance(); Wallix wallix = Wallix.getInstance();
System.out.println(wallix.getVersion()); System.out.println(wallix.getVersion());

View File

@@ -181,7 +181,7 @@ public class DB {
entity.setId(rs.getInt("entity_id")); entity.setId(rs.getInt("entity_id"));
entity.setName(rs.getString("name")); entity.setName(rs.getString("name"));
if (entity.getType()==EntityType.GROUP) { if (entity.getType()==EntityType.USER_GROUP) {
UserGroup group = (UserGroup) entity; UserGroup group = (UserGroup) entity;
group.getMembers().addAll(getGroupMembers(entity.getName())); group.getMembers().addAll(getGroupMembers(entity.getName()));
} }
@@ -254,7 +254,7 @@ public class DB {
} }
stmt.close(); stmt.close();
stmt = connection.prepareStatement("delete from guacamole_user_group_member values (?, ?)"); stmt = connection.prepareStatement("delete from guacamole_user_group_member where user_group_id=? and member_entity_id=?");
for (int id : toDelete) { for (int id : toDelete) {
stmt.setInt(1, group.getGroupId()); stmt.setInt(1, group.getGroupId());
stmt.setInt(2, id); stmt.setInt(2, id);
@@ -581,4 +581,74 @@ public class DB {
}); });
} }
public void addTargetGroupMember(int targetGroupId, int memberEntityId) throws SQLException, GuacamoleException {
DB db = DB.getInstance();
Connection connection = db.getMySQLConnection();
PreparedStatement stmt = connection
.prepareStatement("insert into guacamole_connection_group_permission values (?, ?, 'READ')");
stmt.setInt(1, memberEntityId);
stmt.setInt(2, targetGroupId);
stmt.executeUpdate();
}
public int getUserGroupsId(String name) throws GuacamoleException, SQLException {
DB db = DB.getInstance();
Connection connection = db.getMySQLConnection();
PreparedStatement stmt = connection
.prepareStatement("select entity_id from guacamole_entity where type='USER_GROUP' and name=?");
stmt.setString(1, name);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
return rs.getInt(1);
}
throw new GuacamoleException("User group not found");
}
public Set<Integer> getEntitiesId(Set<String> memberNames, Entity.EntityType type) throws GuacamoleException, SQLException {
DB db = DB.getInstance();
Connection connection = db.getMySQLConnection();
PreparedStatement stmt = connection
.prepareStatement("select entity_id from guacamole_entity where type=? and name in (?)");
StringBuffer formattedNamesList = new StringBuffer()
.append(String.join("','", memberNames));
Set<Integer> result = new HashSet<>();
stmt.setString(1, type.toString());
stmt.setString(2, formattedNamesList.toString());
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
result.add(rs.getInt(1));
}
return result;
}
public Set<Integer> getTargetGroupMembersIds(int id) throws SQLException, GuacamoleException {
DB db = DB.getInstance();
Connection connection = db.getMySQLConnection();
PreparedStatement stmt = connection
.prepareStatement("select entity_id from guacamole_connection_group_permission where connection_group_id=?");
Set<Integer> result = new HashSet<>();
stmt.setInt(1, id);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
result.add(rs.getInt(1));
}
return result;
}
public void removeTargetGroupMember(int id, int memberId) throws GuacamoleException, SQLException {
DB db = DB.getInstance();
Connection connection = db.getMySQLConnection();
PreparedStatement stmt = connection
.prepareStatement("delete from guacamole_connection_group_permission where connection_group_id=? and entity_id=?");
stmt.setInt(1, id);
stmt.setInt(2, memberId);
stmt.executeUpdate();
}
} }

View File

@@ -2,7 +2,7 @@ package cm.soungui.guacamole.ext.wallix.sync.db;
public class Entity { public class Entity {
public static enum EntityType { USER, GROUP }; public static enum EntityType { USER, USER_GROUP };
private int id; private int id;

View File

@@ -11,7 +11,7 @@ public class UserGroup extends Entity {
@Override @Override
public EntityType getType() { public EntityType getType() {
return EntityType.GROUP; return EntityType.USER_GROUP;
} }
@Override @Override