From 6c95897f091655d64ea5805ebaebd00306c530ff Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 28 Jun 2017 09:49:24 +0200 Subject: [PATCH] fetch device ids for muc members w/o known devices --- .../crypto/axolotl/AxolotlService.java | 23 ++++++++++++++++++- .../conversations/entities/MucOptions.java | 10 ++++++-- .../conversations/parser/MessageParser.java | 4 +++- .../conversations/parser/PresenceParser.java | 7 +++++- .../services/XmppConnectionService.java | 6 ++++- 5 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java index 045795c08d0b32b4fd9e84e2943645f43bd07987..0852c34af682aabe1ebfd33c282f60a3b682ec87 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java @@ -211,7 +211,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { putDevicesForJid(account.getJid().toBareJid().toPreppedString(), deviceIds, store); for (Contact contact : account.getRoster().getContacts()) { Jid bareJid = contact.getJid().toBareJid(); - String address = bareJid.toString(); + String address = bareJid.toPreppedString(); deviceIds = store.getSubDeviceSessions(address); putDevicesForJid(address, deviceIds, store); } @@ -842,6 +842,27 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { } } + public boolean hasEmptyDeviceList(Jid jid) { + return !hasAny(jid) && (!deviceIds.containsKey(jid) || deviceIds.get(jid).isEmpty()); + } + + public void fetchDeviceIds(final Jid jid) { + Log.d(Config.LOGTAG,"fetching device ids for "+jid); + IqPacket packet = mXmppConnectionService.getIqGenerator().retrieveDeviceIds(jid); + mXmppConnectionService.sendIqPacket(account, packet, new OnIqPacketReceived() { + @Override + public void onIqPacketReceived(Account account, IqPacket packet) { + if (packet.getType() == IqPacket.TYPE.RESULT) { + Element item = mXmppConnectionService.getIqParser().getItem(packet); + Set deviceIds = mXmppConnectionService.getIqParser().deviceIds(item); + registerDevices(jid,deviceIds); + } else { + Log.d(Config.LOGTAG,packet.toString()); + } + } + }); + } + private void buildSessionFromPEP(final SignalProtocolAddress address) { Log.i(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Building new session for " + address.toString()); if (address.equals(getOwnAxolotlAddress())) { diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java index 6272b469b3b5cb293b429884740f6c35ea62a22b..2ce1830542c890bef21a36f6b9f7b186e3ad5fbf 100644 --- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java +++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java @@ -450,13 +450,16 @@ public class MucOptions { return user; } - public void updateUser(User user) { + //returns true if real jid was new; + public boolean updateUser(User user) { User old; + boolean realJidFound = false; if (user.fullJid == null && user.realJid != null) { old = findUserByRealJid(user.realJid); + realJidFound = old != null; if (old != null) { if (old.fullJid != null) { - return; //don't add. user already exists + return false; //don't add. user already exists } else { synchronized (users) { users.remove(old); @@ -465,6 +468,7 @@ public class MucOptions { } } else if (user.realJid != null) { old = findUserByRealJid(user.realJid); + realJidFound = old != null; synchronized (users) { if (old != null && old.fullJid == null) { users.remove(old); @@ -481,8 +485,10 @@ public class MucOptions { && user.getAffiliation().outranks(Affiliation.OUTCAST) && !fullJidIsSelf){ this.users.add(user); + return !realJidFound && user.realJid != null; } } + return false; } public User findUserByFullJid(Jid jid) { diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index ef93faf59488f5ed1a37e41c7b38f94439bc7c33..28cabc756e12df534e9f3877da79961476248ca1 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -667,7 +667,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece +user.getRealJid()+" to "+user.getAffiliation()+" in " +conversation.getJid().toBareJid()); if (!user.realJidMatchesAccount()) { - conversation.getMucOptions().updateUser(user); + boolean isNew =conversation.getMucOptions().updateUser(user); mXmppConnectionService.getAvatarService().clear(conversation); mXmppConnectionService.updateMucRosterUi(); mXmppConnectionService.updateConversationUi(); @@ -679,6 +679,8 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece conversation.setAcceptedCryptoTargets(cryptoTargets); mXmppConnectionService.updateConversation(conversation); } + } else if (isNew && user.getRealJid() != null && account.getAxolotlService().hasEmptyDeviceList(user.getRealJid())) { + account.getAxolotlService().fetchDeviceIds(user.getRealJid()); } } } diff --git a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java index 2508cf7a7c66af957134ebd84ef059e4ebb36df5..3c123e00fb303520bb6a5e19c1c5eed638b3a0b5 100644 --- a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java +++ b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java @@ -9,6 +9,7 @@ import java.util.List; import eu.siacs.conversations.Config; import eu.siacs.conversations.crypto.PgpEngine; +import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; @@ -76,7 +77,11 @@ public class PresenceParser extends AbstractParser implements mucOptions.onRenameListener = null; } } - mucOptions.updateUser(user); + boolean isNew = mucOptions.updateUser(user); + final AxolotlService axolotlService = conversation.getAccount().getAxolotlService(); + if (isNew && user.getRealJid() != null && mucOptions.membersOnly() && mucOptions.nonanonymous() && axolotlService.hasEmptyDeviceList(user.getRealJid())) { + axolotlService.fetchDeviceIds(user.getRealJid()); + } if (codes.contains(MucOptions.STATUS_CODE_ROOM_CREATED) && mucOptions.autoPushConfiguration()) { Log.d(Config.LOGTAG,mucOptions.getAccount().getJid().toBareJid() +": room '" diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 8d455b03327daa4b6bdc4773e35a48a903813cd4..d5baa05f8982e50502e5fea717b96daae5181c03 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -2313,6 +2313,7 @@ public class XmppConnectionService extends Service { private void fetchConferenceMembers(final Conversation conversation) { final Account account = conversation.getAccount(); + final AxolotlService axolotlService = account.getAxolotlService(); final String[] affiliations = {"member","admin","owner"}; OnIqPacketReceived callback = new OnIqPacketReceived() { @@ -2328,7 +2329,10 @@ public class XmppConnectionService extends Service { if ("item".equals(child.getName())) { MucOptions.User user = AbstractParser.parseItem(conversation,child); if (!user.realJidMatchesAccount()) { - conversation.getMucOptions().updateUser(user); + boolean isNew = conversation.getMucOptions().updateUser(user); + if (isNew && user.getRealJid() != null && axolotlService.hasEmptyDeviceList(user.getRealJid())) { + axolotlService.fetchDeviceIds(user.getRealJid()); + } } } }