From 43e29d32e895d9f2ae29e2b4a167a37681fd7c94 Mon Sep 17 00:00:00 2001 From: Stephen Paul Weber Date: Thu, 16 Feb 2023 22:17:42 -0500 Subject: [PATCH] If a MUC address is entered as a contact, join it --- .../services/XmppConnectionService.java | 12 +++++++ .../conversations/ui/BlocklistActivity.java | 2 +- .../ui/ChooseContactActivity.java | 2 +- .../conversations/ui/EnterJidDialog.java | 20 +++++++---- .../ui/StartConversationActivity.java | 33 +++++++++++-------- .../conversations/ui/widget/DialpadView.java | 6 +--- .../siacs/conversations/utils/Consumer.java | 6 ++++ 7 files changed, 54 insertions(+), 27 deletions(-) create mode 100644 src/main/java/eu/siacs/conversations/utils/Consumer.java diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 028b6b8168d0f14147fb56cb6e8ab4de2cd0eb90..3a92a3c81e696dfcbc12fc6197c9a862c277b626 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -134,6 +134,7 @@ import eu.siacs.conversations.ui.interfaces.OnMediaLoaded; import eu.siacs.conversations.ui.interfaces.OnSearchResultsAvailable; import eu.siacs.conversations.utils.AccountUtils; import eu.siacs.conversations.utils.Compatibility; +import eu.siacs.conversations.utils.Consumer; import eu.siacs.conversations.utils.ConversationsFileObserver; import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.EasyOnboardingInvite; @@ -3399,6 +3400,17 @@ public class XmppConnectionService extends Service { } } + public void checkIfMuc(final Account account, final Jid jid, Consumer cb) { + IqPacket request = mIqGenerator.queryDiscoInfo(jid.asBareJid()); + sendIqPacket(account, request, (acct, reply) -> { + ServiceDiscoveryResult result = new ServiceDiscoveryResult(reply); + cb.accept( + result.getFeatures().contains("http://jabber.org/protocol/muc") && + result.hasIdentity("conference", null) + ); + }); + } + public void fetchConferenceConfiguration(final Conversation conversation) { fetchConferenceConfiguration(conversation, null); } diff --git a/src/main/java/eu/siacs/conversations/ui/BlocklistActivity.java b/src/main/java/eu/siacs/conversations/ui/BlocklistActivity.java index 55cf9ba0360cad1c315fb3adb7ee30556ca7622a..5115d508312627d6c0dbacb63c066cc47bc6668d 100644 --- a/src/main/java/eu/siacs/conversations/ui/BlocklistActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/BlocklistActivity.java @@ -82,7 +82,7 @@ public class BlocklistActivity extends AbstractSearchableListItemActivity implem null, account.getJid().asBareJid().toEscapedString(), true, - false + EnterJidDialog.SanityCheck.NO ); dialog.setOnEnterJidDialogPositiveListener((accountJid, contactJid) -> { diff --git a/src/main/java/eu/siacs/conversations/ui/ChooseContactActivity.java b/src/main/java/eu/siacs/conversations/ui/ChooseContactActivity.java index 6fe57a0cda475284aba4ffac33b113835dc40a2a..706c7755fdee42abab4086dfe9bbd7a872ab451a 100644 --- a/src/main/java/eu/siacs/conversations/ui/ChooseContactActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ChooseContactActivity.java @@ -329,7 +329,7 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity im jid == null ? null : jid.asBareJid().toString(), getIntent().getStringExtra(EXTRA_ACCOUNT), true, - false + EnterJidDialog.SanityCheck.NO ); dialog.setOnEnterJidDialogPositiveListener((accountJid, contactJid) -> { diff --git a/src/main/java/eu/siacs/conversations/ui/EnterJidDialog.java b/src/main/java/eu/siacs/conversations/ui/EnterJidDialog.java index 88f4ec3ffd54aeb2632edd43c455a2ec386b2b22..68f8f342c0881880eb9b5b2783d1eb1e9a549142 100644 --- a/src/main/java/eu/siacs/conversations/ui/EnterJidDialog.java +++ b/src/main/java/eu/siacs/conversations/ui/EnterJidDialog.java @@ -68,11 +68,17 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected private EnterJidDialogBinding binding; private AlertDialog dialog; - private boolean sanityCheckJid = false; + private SanityCheck sanityCheckJid = SanityCheck.NO; private boolean issuedWarning = false; private GatewayListAdapter gatewayListAdapter = new GatewayListAdapter(); + public static enum SanityCheck { + NO, + YES, + ALLOW_MUC + } + public static EnterJidDialog newInstance( final List activatedAccounts, final String title, @@ -80,7 +86,7 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected final String prefilledJid, final String account, boolean allowEditJid, - final boolean sanity_check_jid) { + final SanityCheck sanity_check_jid) { EnterJidDialog dialog = new EnterJidDialog(); Bundle bundle = new Bundle(); bundle.putString(TITLE_KEY, title); @@ -89,7 +95,7 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected bundle.putString(ACCOUNT_KEY, account); bundle.putBoolean(ALLOW_EDIT_JID_KEY, allowEditJid); bundle.putStringArrayList(ACCOUNTS_LIST_KEY, (ArrayList) activatedAccounts); - bundle.putBoolean(SANITY_CHECK_JID, sanity_check_jid); + bundle.putInt(SANITY_CHECK_JID, sanity_check_jid.ordinal()); dialog.setArguments(bundle); return dialog; } @@ -131,7 +137,7 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected binding.jid.setCursorVisible(false); } } - sanityCheckJid = getArguments().getBoolean(SANITY_CHECK_JID, false); + sanityCheckJid = SanityCheck.values()[getArguments().getInt(SANITY_CHECK_JID, SanityCheck.NO.ordinal())]; DelayedHintHelper.setHint(R.string.account_settings_example_jabber_id, binding.jid); @@ -236,7 +242,7 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected return; } - final Jid contactJid; + Jid contactJid = null; try { contactJid = Jid.ofEscaped(jidString); } catch (final IllegalArgumentException e) { @@ -244,14 +250,14 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected return; } - if (!issuedWarning && sanityCheckJid) { + if (!issuedWarning && sanityCheckJid != SanityCheck.NO) { 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())) { + if (sanityCheckJid != SanityCheck.ALLOW_MUC && 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; diff --git a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java index 1f6305760de821e1c60934db38491bdd406ae290..62004862d569689c1f73e6b79b79bbe59b9ecc1c 100644 --- a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java @@ -536,7 +536,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne prefilledJid, invite == null ? null : invite.account, invite == null || !invite.hasFingerprints(), - true + EnterJidDialog.SanityCheck.ALLOW_MUC ); dialog.setOnEnterJidDialogPositiveListener((accountJid, contactJid) -> { @@ -548,25 +548,32 @@ public class StartConversationActivity extends XmppActivity implements XmppConne if (account == null) { return true; } - final Contact contact = account.getRoster().getContact(contactJid); + if (invite != null && invite.getName() != null) { contact.setServerName(invite.getName()); } - if (contact.isSelf()) { - switchToConversation(contact); - return true; - } else if (contact.showInRoster()) { - throw new EnterJidDialog.JidError(getString(R.string.contact_already_exists)); - } else { - final String preAuth = invite == null ? null : invite.getParameter(XmppUri.PARAMETER_PRE_AUTH); - xmppConnectionService.createContact(contact, true, preAuth); - if (invite != null && invite.hasFingerprints()) { - xmppConnectionService.verifyFingerprints(contact, invite.getFingerprints()); - } + + if (contact.isSelf() || contact.showInRoster()) { switchToConversationDoNotAppend(contact, invite == null ? null : invite.getBody()); return true; } + + xmppConnectionService.checkIfMuc(account, contactJid, (isMuc) -> { + if (isMuc) { + final Conversation conversation = xmppConnectionService.findOrCreateConversation(account, contactJid, true, true, true); + switchToConversationDoNotAppend(conversation, invite == null ? null : invite.getBody()); + } else { + final String preAuth = invite == null ? null : invite.getParameter(XmppUri.PARAMETER_PRE_AUTH); + xmppConnectionService.createContact(contact, true, preAuth); + if (invite != null && invite.hasFingerprints()) { + xmppConnectionService.verifyFingerprints(contact, invite.getFingerprints()); + } + switchToConversationDoNotAppend(contact, invite == null ? null : invite.getBody()); + } + }); + + return true; }); dialog.show(ft, FRAGMENT_TAG_DIALOG); } diff --git a/src/main/java/eu/siacs/conversations/ui/widget/DialpadView.java b/src/main/java/eu/siacs/conversations/ui/widget/DialpadView.java index ccf91cad4bfc76b7a533a2ded7a29041b84f29bc..2a2846d35a2d93c664dee9eb6edaf7cf0915c5bd 100644 --- a/src/main/java/eu/siacs/conversations/ui/widget/DialpadView.java +++ b/src/main/java/eu/siacs/conversations/ui/widget/DialpadView.java @@ -26,6 +26,7 @@ import androidx.constraintlayout.widget.ConstraintLayout; import androidx.databinding.DataBindingUtil; import eu.siacs.conversations.databinding.DialpadBinding; import eu.siacs.conversations.R; +import eu.siacs.conversations.utils.Consumer; public class DialpadView extends ConstraintLayout implements View.OnClickListener { @@ -64,9 +65,4 @@ public class DialpadView extends ConstraintLayout implements View.OnClickListene public void onClick(View v) { clickConsumer.accept(v.getTag().toString()); } - - // Based on java.util.function.Consumer to avoid Android 24 dependency - public interface Consumer { - void accept(T t); - } } diff --git a/src/main/java/eu/siacs/conversations/utils/Consumer.java b/src/main/java/eu/siacs/conversations/utils/Consumer.java new file mode 100644 index 0000000000000000000000000000000000000000..8f6d2d89939164ad869ce9d86e49489e808b75f9 --- /dev/null +++ b/src/main/java/eu/siacs/conversations/utils/Consumer.java @@ -0,0 +1,6 @@ +package eu.siacs.conversations.utils; + +// Based on java.util.function.Consumer to avoid Android 24 dependency +public interface Consumer { + void accept(T t); +}