From 7845ded2d3f8ee679f2d349a235c01ba80a37962 Mon Sep 17 00:00:00 2001 From: Stephen Paul Weber Date: Mon, 7 Mar 2022 15:08:07 -0500 Subject: [PATCH] Try all gateway translations options Send jabber:iq:gateway if we're responding to that and fetch translated response as the JID. Otherwise use JID escaping if supported. Otherwise fall back to the dumb ancient % escaping. --- .../services/XmppConnectionService.java | 27 ++--- .../conversations/ui/EnterJidDialog.java | 98 ++++++++++++------- ...PromptResult.java => OnGatewayResult.java} | 4 +- 3 files changed, 78 insertions(+), 51 deletions(-) rename src/main/java/eu/siacs/conversations/xmpp/{OnGatewayPromptResult.java => OnGatewayResult.java} (52%) diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 9c177f23a..6c976bf53 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -145,7 +145,7 @@ import eu.siacs.conversations.xml.Namespace; import eu.siacs.conversations.xmpp.Jid; import eu.siacs.conversations.xmpp.OnBindListener; import eu.siacs.conversations.xmpp.OnContactStatusChanged; -import eu.siacs.conversations.xmpp.OnGatewayPromptResult; +import eu.siacs.conversations.xmpp.OnGatewayResult; import eu.siacs.conversations.xmpp.OnIqPacketReceived; import eu.siacs.conversations.xmpp.OnKeyStatusUpdated; import eu.siacs.conversations.xmpp.OnMessageAcknowledged; @@ -4656,19 +4656,20 @@ public class XmppConnectionService extends Service { } } - public void fetchGatewayPrompt(Account account, final Jid jid, final OnGatewayPromptResult callback) { - IqPacket request = new IqPacket(IqPacket.TYPE.GET); + public void fetchFromGateway(Account account, final Jid jid, final String input, final OnGatewayResult callback) { + IqPacket request = new IqPacket(input == null ? IqPacket.TYPE.GET : IqPacket.TYPE.SET); request.setTo(jid); - request.query("jabber:iq:gateway"); - sendIqPacket(account, request, new OnIqPacketReceived() { - @Override - public void onIqPacketReceived(Account account, IqPacket packet) { - if (packet.getType() == IqPacket.TYPE.RESULT) { - callback.onGatewayPromptResult(packet.query().findChildContent("prompt"), null); - } else { - Element error = packet.findChild("error"); - callback.onGatewayPromptResult(null, error == null ? null : error.findChildContent("text")); - } + Element query = request.query("jabber:iq:gateway"); + if (input != null) { + Element prompt = query.addChild("prompt"); + prompt.setContent(input); + } + sendIqPacket(account, request, (Account acct, IqPacket packet) -> { + if (packet.getType() == IqPacket.TYPE.RESULT) { + callback.onGatewayResult(packet.query().findChildContent(input == null ? "prompt" : "jid"), null); + } else { + Element error = packet.findChild("error"); + callback.onGatewayResult(null, error == null ? null : error.findChildContent("text")); } }); } diff --git a/src/main/java/eu/siacs/conversations/ui/EnterJidDialog.java b/src/main/java/eu/siacs/conversations/ui/EnterJidDialog.java index 83229453a..e0cb5cd48 100644 --- a/src/main/java/eu/siacs/conversations/ui/EnterJidDialog.java +++ b/src/main/java/eu/siacs/conversations/ui/EnterJidDialog.java @@ -43,7 +43,7 @@ import eu.siacs.conversations.ui.adapter.KnownHostsAdapter; import eu.siacs.conversations.ui.interfaces.OnBackendConnected; import eu.siacs.conversations.ui.util.DelayedHintHelper; import eu.siacs.conversations.xmpp.Jid; -import eu.siacs.conversations.xmpp.OnGatewayPromptResult; +import eu.siacs.conversations.xmpp.OnGatewayResult; public class EnterJidDialog extends DialogFragment implements OnBackendConnected, TextWatcher { @@ -161,7 +161,7 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected for (final Contact contact : account.getRoster().getContacts()) { if (contact.showInRoster() && (contact.getPresences().anyIdentity("gateway", null) || contact.getPresences().anySupport("jabber:iq:gateway"))) { - context.xmppConnectionService.fetchGatewayPrompt(account, contact.getJid(), (final String prompt, String errorMessage) -> { + context.xmppConnectionService.fetchFromGateway(account, contact.getJid(), null, (final String prompt, String errorMessage) -> { if (prompt == null) return; context.runOnUiThread(() -> { @@ -216,41 +216,67 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected return; } final Jid accountJid = accountJid(); - final Jid contactJid; - try { - contactJid = Jid.ofEscaped(binding.jid.getText().toString()); - } catch (final IllegalArgumentException e) { - binding.jidLayout.setError(getActivity().getString(R.string.invalid_jid)); - return; - } - - if (!issuedWarning && sanityCheckJid) { - if (contactJid.isDomainJid()) { - binding.jidLayout.setError( - getActivity().getString(R.string.this_looks_like_a_domain)); - dialog.getButton(AlertDialog.BUTTON_POSITIVE).setText(R.string.add_anway); - issuedWarning = true; - return; - } - if (suspiciousSubDomain(contactJid.getDomain().toEscapedString())) { - binding.jidLayout.setError( - getActivity().getString(R.string.this_looks_like_channel)); - dialog.getButton(AlertDialog.BUTTON_POSITIVE).setText(R.string.add_anway); - issuedWarning = true; - return; - } - } - - if (mListener != null) { - try { - if (mListener.onEnterJidDialogPositive(accountJid, contactJid)) { - dialog.dismiss(); + final OnGatewayResult finish = (final String jidString, final String errorMessage) -> { + getActivity().runOnUiThread(() -> { + if (errorMessage != null) { + binding.jidLayout.setError(errorMessage); + return; } - } catch (JidError error) { - binding.jidLayout.setError(error.toString()); - dialog.getButton(AlertDialog.BUTTON_POSITIVE).setText(R.string.add); - issuedWarning = false; - } + if (jidString == null) { + binding.jidLayout.setError(getActivity().getString(R.string.invalid_jid)); + return; + } + + final Jid contactJid; + try { + contactJid = Jid.ofEscaped(jidString); + } catch (final IllegalArgumentException e) { + binding.jidLayout.setError(getActivity().getString(R.string.invalid_jid)); + return; + } + + if (!issuedWarning && sanityCheckJid) { + if (contactJid.isDomainJid()) { + binding.jidLayout.setError(getActivity().getString(R.string.this_looks_like_a_domain)); + dialog.getButton(AlertDialog.BUTTON_POSITIVE).setText(R.string.add_anway); + issuedWarning = true; + return; + } + if (suspiciousSubDomain(contactJid.getDomain().toEscapedString())) { + binding.jidLayout.setError(getActivity().getString(R.string.this_looks_like_channel)); + dialog.getButton(AlertDialog.BUTTON_POSITIVE).setText(R.string.add_anway); + issuedWarning = true; + return; + } + } + + if (mListener != null) { + try { + if (mListener.onEnterJidDialogPositive(accountJid, contactJid)) { + dialog.dismiss(); + } + } catch (JidError error) { + binding.jidLayout.setError(error.toString()); + dialog.getButton(AlertDialog.BUTTON_POSITIVE).setText(R.string.add); + issuedWarning = false; + } + } + }); + }; + + Pair> p = gatewayListAdapter.getSelected(); + + if (p == null) { + finish.onGatewayResult(binding.jid.getText().toString(), null); + } else if (p.first != null) { // Gateway already responsed to jabber:iq:gateway once + final Account acct = ((XmppActivity) getActivity()).xmppConnectionService.findAccountByJid(accountJid); + ((XmppActivity) getActivity()).xmppConnectionService.fetchFromGateway(acct, p.second.first, binding.jid.getText().toString(), finish); + } else if (p.second.first.isDomainJid() && p.second.second.getServiceDiscoveryResult().getFeatures().contains("jid\\20escaping")) { + finish.onGatewayResult(Jid.ofLocalAndDomain(binding.jid.getText().toString(), p.second.first.getDomain().toString()).toString(), null); + } else if (p.second.first.isDomainJid()) { + finish.onGatewayResult(Jid.ofLocalAndDomain(binding.jid.getText().toString().replace("@", "%"), p.second.first.getDomain().toString()).toString(), null); + } else { + finish.onGatewayResult(null, null); } } diff --git a/src/main/java/eu/siacs/conversations/xmpp/OnGatewayPromptResult.java b/src/main/java/eu/siacs/conversations/xmpp/OnGatewayResult.java similarity index 52% rename from src/main/java/eu/siacs/conversations/xmpp/OnGatewayPromptResult.java rename to src/main/java/eu/siacs/conversations/xmpp/OnGatewayResult.java index 7c903021c..fd95d0761 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/OnGatewayPromptResult.java +++ b/src/main/java/eu/siacs/conversations/xmpp/OnGatewayResult.java @@ -1,7 +1,7 @@ package eu.siacs.conversations.xmpp; -public interface OnGatewayPromptResult { +public interface OnGatewayResult { // if prompt is null, there was an error // errorText may or may not be set - public void onGatewayPromptResult(String prompt, String errorText); + public void onGatewayResult(String prompt, String errorText); }