Process MUC password from XMPP URI

Stephen Paul Weber created

Change summary

src/main/java/eu/siacs/conversations/services/XmppConnectionService.java |  8 
src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java       |  3 
src/main/java/eu/siacs/conversations/ui/JoinConferenceDialog.java        | 10 
src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java   | 16 
4 files changed, 26 insertions(+), 11 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/services/XmppConnectionService.java 🔗

@@ -2679,10 +2679,14 @@ public class XmppConnectionService extends Service {
     }
 
     public Conversation findOrCreateConversation(final Account account, final Jid jid, final boolean muc, final boolean joinAfterCreate, final boolean async) {
-        return this.findOrCreateConversation(account, jid, muc, joinAfterCreate, null, async);
+        return this.findOrCreateConversation(account, jid, muc, joinAfterCreate, null, async, null);
     }
 
     public Conversation findOrCreateConversation(final Account account, final Jid jid, final boolean muc, final boolean joinAfterCreate, final MessageArchiveService.Query query, final boolean async) {
+        return this.findOrCreateConversation(account, jid, muc, joinAfterCreate, query, async, null);
+    }
+
+    public Conversation findOrCreateConversation(final Account account, final Jid jid, final boolean muc, final boolean joinAfterCreate, final MessageArchiveService.Query query, final boolean async, final String password) {
         synchronized (this.conversations) {
             Conversation conversation = find(account, jid);
             if (conversation != null) {
@@ -2696,6 +2700,7 @@ public class XmppConnectionService extends Service {
                 if (muc) {
                     conversation.setMode(Conversation.MODE_MULTI);
                     conversation.setContactJid(jid);
+                    if (password != null) conversation.getMucOptions().setPassword(password);
                 } else {
                     conversation.setMode(Conversation.MODE_SINGLE);
                     conversation.setContactJid(jid.asBareJid());
@@ -2713,6 +2718,7 @@ public class XmppConnectionService extends Service {
                 if (muc) {
                     conversation = new Conversation(conversationName, account, jid,
                             Conversation.MODE_MULTI);
+                    if (password != null) conversation.getMucOptions().setPassword(password);
                 } else {
                     conversation = new Conversation(conversationName, account, jid.asBareJid(),
                             Conversation.MODE_SINGLE);

src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java 🔗

@@ -612,6 +612,9 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
         if (xmppUri.isValidJid() && !xmppUri.hasFingerprints()) {
             final Conversation conversation = xmppConnectionService.findUniqueConversationByJid(xmppUri);
             if (conversation != null) {
+                if (xmppUri.getParameter("password") != null) {
+                    xmppConnectionService.providePasswordForMuc(conversation, xmppUri.getParameter("password"));
+                }
                 if (xmppUri.isAction("command")) {
                     startCommand(conversation.getAccount(), xmppUri.getJid(), xmppUri.getParameter("node"));
                 } else {

src/main/java/eu/siacs/conversations/ui/JoinConferenceDialog.java 🔗

@@ -28,14 +28,16 @@ import eu.siacs.conversations.ui.util.DelayedHintHelper;
 public class JoinConferenceDialog extends DialogFragment implements OnBackendConnected {
 
 	private static final String PREFILLED_JID_KEY = "prefilled_jid";
+	private static final String PREFILLED_PASSWORD_KEY = "prefilled_password";
 	private static final String ACCOUNTS_LIST_KEY = "activated_accounts_list";
 	private JoinConferenceDialogListener mListener;
 	private KnownHostsAdapter knownHostsAdapter;
 
-	public static JoinConferenceDialog newInstance(String prefilledJid, List<String> accounts) {
+	public static JoinConferenceDialog newInstance(String prefilledJid, String password, List<String> accounts) {
 		JoinConferenceDialog dialog = new JoinConferenceDialog();
 		Bundle bundle = new Bundle();
 		bundle.putString(PREFILLED_JID_KEY, prefilledJid);
+		bundle.putString(PREFILLED_PASSWORD_KEY, password);
 		bundle.putStringArrayList(ACCOUNTS_LIST_KEY, (ArrayList<String>) accounts);
 		dialog.setArguments(bundle);
 		return dialog;
@@ -66,9 +68,9 @@ public class JoinConferenceDialog extends DialogFragment implements OnBackendCon
 		builder.setNegativeButton(R.string.cancel, null);
 		AlertDialog dialog = builder.create();
 		dialog.show();
-		dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(view -> mListener.onJoinDialogPositiveClick(dialog, binding.account, binding.accountJidLayout, binding.jid, binding.bookmark.isChecked()));
+		dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(view -> mListener.onJoinDialogPositiveClick(dialog, binding.account, binding.accountJidLayout, binding.jid, binding.jid.getText().toString().equals(getArguments().getString(PREFILLED_JID_KEY)) ? getArguments().getString(PREFILLED_PASSWORD_KEY) : null, binding.bookmark.isChecked()));
 		binding.jid.setOnEditorActionListener((v, actionId, event) -> {
-			mListener.onJoinDialogPositiveClick(dialog, binding.account, binding.accountJidLayout, binding.jid, binding.bookmark.isChecked());
+			mListener.onJoinDialogPositiveClick(dialog, binding.account, binding.accountJidLayout, binding.jid, binding.jid.getText().toString().equals(getArguments().getString(PREFILLED_JID_KEY)) ? getArguments().getString(PREFILLED_PASSWORD_KEY) : null, binding.bookmark.isChecked());
 			return true;
 		});
 		return dialog;
@@ -117,6 +119,6 @@ public class JoinConferenceDialog extends DialogFragment implements OnBackendCon
 	}
 
 	public interface JoinConferenceDialogListener {
-		void onJoinDialogPositiveClick(Dialog dialog, Spinner spinner, TextInputLayout jidLayout, AutoCompleteTextView jid, boolean isBookmarkChecked);
+		void onJoinDialogPositiveClick(Dialog dialog, Spinner spinner, TextInputLayout jidLayout, AutoCompleteTextView jid, String password, boolean isBookmarkChecked);
 	}
 }

src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java 🔗

@@ -621,14 +621,14 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
     }
 
     @SuppressLint("InflateParams")
-    protected void showJoinConferenceDialog(final String prefilledJid) {
+    protected void showJoinConferenceDialog(final String prefilledJid, final Invite invite) {
         FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
         Fragment prev = getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG_DIALOG);
         if (prev != null) {
             ft.remove(prev);
         }
         ft.addToBackStack(null);
-        JoinConferenceDialog joinConferenceFragment = JoinConferenceDialog.newInstance(prefilledJid, mActivatedAccounts);
+        JoinConferenceDialog joinConferenceFragment = JoinConferenceDialog.newInstance(prefilledJid, invite.getParameter("password"), mActivatedAccounts);
         joinConferenceFragment.show(ft, FRAGMENT_TAG_DIALOG);
     }
 
@@ -1032,10 +1032,13 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
         final Conversation muc = xmppConnectionService.findFirstMuc(invite.getJid(), invite.account);
         if (invite.isAction(XmppUri.ACTION_JOIN) || (contacts.isEmpty() && muc != null)) {
             if (muc != null && !invite.forceDialog) {
+                if (invite.getParameter("password") != null) {
+                    xmppConnectionService.providePasswordForMuc(muc, invite.getParameter("password"));
+                }
                 switchToConversationDoNotAppend(muc, invite.getBody());
                 return true;
             } else {
-                showJoinConferenceDialog(invite.getJid().asBareJid().toEscapedString());
+                showJoinConferenceDialog(invite.getJid().asBareJid().toEscapedString(), invite);
                 return false;
             }
         } else if (contacts.size() == 0) {
@@ -1229,7 +1232,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
     }
 
     @Override
-    public void onJoinDialogPositiveClick(Dialog dialog, Spinner spinner, TextInputLayout layout, AutoCompleteTextView jid, boolean isBookmarkChecked) {
+    public void onJoinDialogPositiveClick(Dialog dialog, Spinner spinner, TextInputLayout layout, AutoCompleteTextView jid, String password, boolean isBookmarkChecked) {
         if (!xmppConnectionServiceBound) {
             return;
         }
@@ -1262,20 +1265,21 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
             } else {
                 bookmark = new Bookmark(account, conferenceJid.asBareJid());
                 bookmark.setAutojoin(getBooleanPreference("autojoin", R.bool.autojoin));
+                if (password != null) bookmark.setPassword(password);
                 final String nick = conferenceJid.getResource();
                 if (nick != null && !nick.isEmpty() && !nick.equals(MucOptions.defaultNick(account))) {
                     bookmark.setNick(nick);
                 }
                 xmppConnectionService.createBookmark(account, bookmark);
                 final Conversation conversation = xmppConnectionService
-                        .findOrCreateConversation(account, conferenceJid, true, true, true);
+                        .findOrCreateConversation(account, conferenceJid, true, true, null, true, password);
                 bookmark.setConversation(conversation);
                 dialog.dismiss();
                 switchToConversation(conversation);
             }
         } else {
             final Conversation conversation = xmppConnectionService
-                    .findOrCreateConversation(account, conferenceJid, true, true, true);
+                    .findOrCreateConversation(account, conferenceJid, true, true, null, true, password);
             dialog.dismiss();
             switchToConversation(conversation);
         }