diff options
Diffstat (limited to 'src/main/java/eu/siacs/conversations/parser/IqParser.java')
-rw-r--r-- | src/main/java/eu/siacs/conversations/parser/IqParser.java | 137 |
1 files changed, 96 insertions, 41 deletions
diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index aeec56d0..e84545fc 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -2,36 +2,40 @@ package eu.siacs.conversations.parser; import android.util.Log; +import java.util.ArrayList; +import java.util.Collection; + import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.utils.Xmlns; import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xmpp.OnIqPacketReceived; -import eu.siacs.conversations.xmpp.jid.InvalidJidException; +import eu.siacs.conversations.xmpp.OnUpdateBlocklist; import eu.siacs.conversations.xmpp.jid.Jid; import eu.siacs.conversations.xmpp.stanzas.IqPacket; public class IqParser extends AbstractParser implements OnIqPacketReceived { - public IqParser(XmppConnectionService service) { + public IqParser(final XmppConnectionService service) { super(service); } - public void rosterItems(Account account, Element query) { - String version = query.getAttribute("ver"); + private void rosterItems(final Account account, final Element query) { + final String version = query.getAttribute("ver"); if (version != null) { account.getRoster().setVersion(version); } - for (Element item : query.getChildren()) { + for (final Element item : query.getChildren()) { if (item.getName().equals("item")) { final Jid jid = item.getAttributeAsJid("jid"); if (jid == null) { - break; + continue; } - String name = item.getAttribute("name"); - String subscription = item.getAttribute("subscription"); - Contact contact = account.getRoster().getContact(jid); + final String name = item.getAttribute("name"); + final String subscription = item.getAttribute("subscription"); + final Contact contact = account.getRoster().getContact(jid); if (!contact.getOption(Contact.Options.DIRTY_PUSH)) { contact.setServerName(name); contact.parseGroupsFromElement(item); @@ -54,53 +58,104 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { mXmppConnectionService.updateRosterUi(); } - public String avatarData(IqPacket packet) { - Element pubsub = packet.findChild("pubsub", + public String avatarData(final IqPacket packet) { + final Element pubsub = packet.findChild("pubsub", "http://jabber.org/protocol/pubsub"); if (pubsub == null) { return null; } - Element items = pubsub.findChild("items"); + final Element items = pubsub.findChild("items"); if (items == null) { return null; } return super.avatarData(items); } + public static boolean fromServer(final Account account, final IqPacket packet) { + return packet.getFrom() == null + || packet.getFrom().equals(account.getServer()) + || packet.getFrom().equals(account.getJid().toBareJid()) + || packet.getFrom().equals(account.getJid()); + } + @Override - public void onIqPacketReceived(Account account, IqPacket packet) { - if (packet.hasChild("query", "jabber:iq:roster")) { - final Jid from = packet.getFrom(); - if ((from == null) || (from.equals(account.getJid().toBareJid()))) { - Element query = packet.findChild("query"); - this.rosterItems(account, query); + public void onIqPacketReceived(final Account account, final IqPacket packet) { + if (packet.hasChild("query", Xmlns.ROSTER) && fromServer(account, packet)) { + final Element query = packet.findChild("query"); + // If this is in response to a query for the whole roster: + if (packet.getType() == IqPacket.TYPE_RESULT) { + account.getRoster().markAllAsNotInRoster(); } - } else { - if (packet.getFrom() == null) { - Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": received iq with invalid from "+packet.toString()); - return; - } else if (packet.hasChild("open", "http://jabber.org/protocol/ibb") - || packet.hasChild("data", "http://jabber.org/protocol/ibb")) { - mXmppConnectionService.getJingleConnectionManager() - .deliverIbbPacket(account, packet); - } else if (packet.hasChild("query", "http://jabber.org/protocol/disco#info")) { - IqPacket response = mXmppConnectionService.getIqGenerator() - .discoResponse(packet); - account.getXmppConnection().sendIqPacket(response, null); - } else if (packet.hasChild("ping", "urn:xmpp:ping")) { - IqPacket response = packet.generateRespone(IqPacket.TYPE_RESULT); - mXmppConnectionService.sendIqPacket(account, response, null); + this.rosterItems(account, query); + } else if ((packet.hasChild("block", Xmlns.BLOCKING) || packet.hasChild("blocklist", Xmlns.BLOCKING)) && + fromServer(account, packet)) { + // Block list or block push. + Log.d(Config.LOGTAG, "Received blocklist update from server"); + final Element blocklist = packet.findChild("blocklist", Xmlns.BLOCKING); + final Element block = packet.findChild("block", Xmlns.BLOCKING); + final Collection<Element> items = blocklist != null ? blocklist.getChildren() : + (block != null ? block.getChildren() : null); + // If this is a response to a blocklist query, clear the block list and replace with the new one. + // Otherwise, just update the existing blocklist. + if (packet.getType() == IqPacket.TYPE_RESULT) { + account.clearBlocklist(); + } + if (items != null) { + final Collection<Jid> jids = new ArrayList<>(items.size()); + // Create a collection of Jids from the packet + for (final Element item : items) { + if (item.getName().equals("item")) { + final Jid jid = item.getAttributeAsJid("jid"); + if (jid != null) { + jids.add(jid); + } + } + } + account.getBlocklist().addAll(jids); + } + // Update the UI + mXmppConnectionService.updateBlocklistUi(OnUpdateBlocklist.Status.BLOCKED); + } else if (packet.hasChild("unblock", Xmlns.BLOCKING) && + fromServer(account, packet) && packet.getType() == IqPacket.TYPE_SET) { + Log.d(Config.LOGTAG, "Received unblock update from server"); + final Collection<Element> items = packet.findChild("unblock", Xmlns.BLOCKING).getChildren(); + if (items.size() == 0) { + // No children to unblock == unblock all + account.getBlocklist().clear(); } else { - if ((packet.getType() == IqPacket.TYPE_GET) - || (packet.getType() == IqPacket.TYPE_SET)) { - IqPacket response = packet.generateRespone(IqPacket.TYPE_ERROR); - Element error = response.addChild("error"); - error.setAttribute("type", "cancel"); - error.addChild("feature-not-implemented", - "urn:ietf:params:xml:ns:xmpp-stanzas"); - account.getXmppConnection().sendIqPacket(response, null); + final Collection<Jid> jids = new ArrayList<>(items.size()); + for (final Element item : items) { + if (item.getName().equals("item")) { + final Jid jid = item.getAttributeAsJid("jid"); + if (jid != null) { + jids.add(jid); + } + } } + account.getBlocklist().removeAll(jids); } + mXmppConnectionService.updateBlocklistUi(OnUpdateBlocklist.Status.UNBLOCKED); + } else if (packet.hasChild("open", "http://jabber.org/protocol/ibb") + || packet.hasChild("data", "http://jabber.org/protocol/ibb")) { + mXmppConnectionService.getJingleConnectionManager() + .deliverIbbPacket(account, packet); + } else if (packet.hasChild("query", "http://jabber.org/protocol/disco#info")) { + final IqPacket response = mXmppConnectionService.getIqGenerator() + .discoResponse(packet); + account.getXmppConnection().sendIqPacket(response, null); + } else if (packet.hasChild("ping", "urn:xmpp:ping")) { + final IqPacket response = packet.generateResponse(IqPacket.TYPE_RESULT); + mXmppConnectionService.sendIqPacket(account, response, null); + } else { + if ((packet.getType() == IqPacket.TYPE_GET) + || (packet.getType() == IqPacket.TYPE_SET)) { + final IqPacket response = packet.generateResponse(IqPacket.TYPE_ERROR); + final Element error = response.addChild("error"); + error.setAttribute("type", "cancel"); + error.addChild("feature-not-implemented", + "urn:ietf:params:xml:ns:xmpp-stanzas"); + account.getXmppConnection().sendIqPacket(response, null); + } } } |