package im.rosetta.executors; import java.util.List; import im.rosetta.Failures; import im.rosetta.client.tags.ECIAuthentificate; import im.rosetta.database.entity.Group; import im.rosetta.database.repository.GroupRepository; import im.rosetta.packet.Packet18GroupInfo; import im.rosetta.packet.Packet22GroupBan; import io.orprotocol.ProtocolException; import io.orprotocol.client.Client; import io.orprotocol.packet.PacketExecutor; public class Executor22GroupBan extends PacketExecutor { private final GroupRepository groupRepository = new GroupRepository(); @Override public void onPacketReceived(Packet22GroupBan packet, Client client) throws Exception, ProtocolException { ECIAuthentificate eciAuthentificate = client.getTag(ECIAuthentificate.class); if(eciAuthentificate == null || !eciAuthentificate.hasAuthorized()){ /** * Клиент не авторизован, он не может банить участников групп */ client.disconnect(Failures.HANDSHAKE_NOT_COMPLETED); return; } String groupId = packet.getGroupId(); String publicKeyToBan = packet.getPublicKey(); Group group = this.groupRepository.getGroup(groupId); if(group == null){ /** * Группы не существует, но так как клиент вызывает бан участника, предполагается что он админ, * а значит точно должен знать что группы не существует, значит это какое-то атипичное поведение */ client.disconnect(Failures.DATA_MISSMATCH); return; } if(!group.getMembersPublicKeys().get(0).equals(eciAuthentificate.getPublicKey())){ /** * Администратор группы - первый участник в списке участников, * если публичный ключ клиента не совпадает с публичным ключом первого участника, * значит он не админ и не может банить участников */ client.disconnect(Failures.DATA_MISSMATCH); return; } if(!group.getMembersPublicKeys().contains(publicKeyToBan)){ /** * Пользователя которого пытаются забанить нет в группе */ return; } /** * Баним пользователя в группе - удаляем его из участников и добавляем в бан */ this.groupRepository.banMemberInGroup(groupId, publicKeyToBan); /** * Удаляем пользователя из списка участников (сверху мы уже удаляем его в базе, * а здесь просто удаляем из объекта, чтобы отправить * клиенту обновленную информацию о группе) */ List membersPKs = group.getMembersPublicKeys(); membersPKs.remove(publicKeyToBan); group.setBannedPublicKeys(membersPKs); /** * Отправляем клиенту новый Packet18GroupInfo, чтобы он обновил информацию о группе, * например, удалил участника из списка участников */ Packet18GroupInfo groupInfoPacket = new Packet18GroupInfo(); groupInfoPacket.setGroupId(groupId); groupInfoPacket.setMembersPKs(group.getMembersPublicKeys()); client.send(groupInfoPacket); } }