diff --git a/src/main/java/cm/soungui/guacamole/ext/wallix/sync/Wallix.java b/src/main/java/cm/soungui/guacamole/ext/wallix/sync/Wallix.java index 8c10a5d..250108b 100644 --- a/src/main/java/cm/soungui/guacamole/ext/wallix/sync/Wallix.java +++ b/src/main/java/cm/soungui/guacamole/ext/wallix/sync/Wallix.java @@ -11,6 +11,7 @@ import java.security.cert.X509Certificate; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import javax.net.ssl.SSLContext; @@ -258,6 +259,25 @@ public class Wallix { return buffer.toString(); } + public Map> getAuthorizations() throws Exception { + String output = get("/authorizations?fields=user_group,target_group"); + + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode jsonNode = objectMapper.readTree(output); + Map> result = new HashMap<>(); + + jsonNode.elements().forEachRemaining((e) -> { + String targetName = e.findValue("target_group").asText(); + if (! result.containsKey(targetName)) { + result.put(targetName, new HashSet<>()); + } + Set groups = result.get(targetName); + groups.add(e.findValue("user_group").asText()); + }); + + return result; + } + public final class API { public static final String ATTRIBUTE_USER_DISABLED = "is_disabled"; diff --git a/src/main/java/cm/soungui/guacamole/ext/wallix/sync/WallixConfigSynchronizer.java b/src/main/java/cm/soungui/guacamole/ext/wallix/sync/WallixConfigSynchronizer.java index 3d5b0b0..a75da3d 100644 --- a/src/main/java/cm/soungui/guacamole/ext/wallix/sync/WallixConfigSynchronizer.java +++ b/src/main/java/cm/soungui/guacamole/ext/wallix/sync/WallixConfigSynchronizer.java @@ -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.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.User; import cm.soungui.guacamole.ext.wallix.sync.db.UserGroup; @@ -31,7 +32,6 @@ public class WallixConfigSynchronizer implements Runnable { public void run() { while (true) { try { - System.out.println("Fetching config"); synchronizeUsers(); synchronizeUserGroups(); synchronizeTargetGroups(); @@ -116,6 +116,7 @@ public class WallixConfigSynchronizer implements Runnable { DB db = DB.getInstance(); Set wallixTargetGroups = Wallix.getInstance().getTargetGroups(); + Map> members = Wallix.getInstance().getAuthorizations(); // Fetch targets from Wallix for (TargetGroup wallixGroup : wallixTargetGroups) { @@ -176,10 +177,25 @@ public class WallixConfigSynchronizer implements Runnable { } } } + + Set membersNames = members.get(wallixGroup.getName()); + synchronizeAuthorizations(dbTargetGroup, membersNames); } } + private void synchronizeAuthorizations(TargetGroup targetGroup, Set members) throws GuacamoleException, Exception { + DB db = DB.getInstance(); + Set newMembersIds = db.getEntitiesId(members, EntityType.USER_GROUP); + Set 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 { Wallix wallix = Wallix.getInstance(); System.out.println(wallix.getVersion()); diff --git a/src/main/java/cm/soungui/guacamole/ext/wallix/sync/db/DB.java b/src/main/java/cm/soungui/guacamole/ext/wallix/sync/db/DB.java index 7cea6cb..584cdbe 100644 --- a/src/main/java/cm/soungui/guacamole/ext/wallix/sync/db/DB.java +++ b/src/main/java/cm/soungui/guacamole/ext/wallix/sync/db/DB.java @@ -181,7 +181,7 @@ public class DB { entity.setId(rs.getInt("entity_id")); entity.setName(rs.getString("name")); - if (entity.getType()==EntityType.GROUP) { + if (entity.getType()==EntityType.USER_GROUP) { UserGroup group = (UserGroup) entity; group.getMembers().addAll(getGroupMembers(entity.getName())); } @@ -254,7 +254,7 @@ public class DB { } 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) { stmt.setInt(1, group.getGroupId()); 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 getEntitiesId(Set 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 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 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 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(); + } + } diff --git a/src/main/java/cm/soungui/guacamole/ext/wallix/sync/db/Entity.java b/src/main/java/cm/soungui/guacamole/ext/wallix/sync/db/Entity.java index 603f577..6185900 100644 --- a/src/main/java/cm/soungui/guacamole/ext/wallix/sync/db/Entity.java +++ b/src/main/java/cm/soungui/guacamole/ext/wallix/sync/db/Entity.java @@ -2,7 +2,7 @@ package cm.soungui.guacamole.ext.wallix.sync.db; public class Entity { - public static enum EntityType { USER, GROUP }; + public static enum EntityType { USER, USER_GROUP }; private int id; diff --git a/src/main/java/cm/soungui/guacamole/ext/wallix/sync/db/UserGroup.java b/src/main/java/cm/soungui/guacamole/ext/wallix/sync/db/UserGroup.java index 13b3141..20b9ed5 100644 --- a/src/main/java/cm/soungui/guacamole/ext/wallix/sync/db/UserGroup.java +++ b/src/main/java/cm/soungui/guacamole/ext/wallix/sync/db/UserGroup.java @@ -11,7 +11,7 @@ public class UserGroup extends Entity { @Override public EntityType getType() { - return EntityType.GROUP; + return EntityType.USER_GROUP; } @Override