added support for password protected muc - fixed #203 and fixed #395

iNPUTmice created

Change summary

res/values/strings.xml                                         |  2 
src/eu/siacs/conversations/entities/MucOptions.java            | 12 
src/eu/siacs/conversations/services/XmppConnectionService.java | 11 
src/eu/siacs/conversations/ui/ConversationFragment.java        | 64 ++-
4 files changed, 72 insertions(+), 17 deletions(-)

Detailed changes

res/values/strings.xml 🔗

@@ -239,5 +239,7 @@
     <string name="disable_notifications_for_this_conversation">Disable notifications for this conversation</string>
     <string name="notifications_disabled">Notifications are disabled</string>
     <string name="enable">Enable</string>
+    <string name="conference_requires_password">Conference requires password</string>
+    <string name="enter_password">Enter password</string>
 
 </resources>

src/eu/siacs/conversations/entities/MucOptions.java 🔗

@@ -14,6 +14,7 @@ public class MucOptions {
 	public static final int ERROR_NO_ERROR = 0;
 	public static final int ERROR_NICK_IN_USE = 1;
 	public static final int ERROR_ROOM_NOT_FOUND = 2;
+	public static final int ERROR_PASSWORD_REQUIRED = 3;
 
 	public interface OnRenameListener {
 		public void onRename(boolean success);
@@ -106,6 +107,7 @@ public class MucOptions {
 	private User self = new User();
 	private String subject = null;
 	private String joinnick;
+	private String password = null;
 
 	public MucOptions(Account account) {
 		this.account = account;
@@ -186,6 +188,8 @@ public class MucOptions {
 					} else {
 						this.error = ERROR_NICK_IN_USE;
 					}
+				} else if (error.hasChild("not-authorized")) {
+					this.error = ERROR_PASSWORD_REQUIRED;
 				}
 			}
 		}
@@ -308,4 +312,12 @@ public class MucOptions {
 		}
 		return null;
 	}
+
+	public String getPassword() {
+		return this.password;
+	}
+	
+	public void setPassword(String password) {
+		this.password = password;
+	}
 }

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

@@ -1059,6 +1059,10 @@ public class XmppConnectionService extends Service {
 			packet.setAttribute("to", conversation.getMucOptions().getJoinJid());
 			Element x = new Element("x");
 			x.setAttribute("xmlns", "http://jabber.org/protocol/muc");
+			if (conversation.getMucOptions().getPassword() != null) {
+				Element password = x.addChild("password");
+				password.setContent(conversation.getMucOptions().getPassword());
+			}
 			String sig = account.getPgpSignature();
 			if (sig != null) {
 				packet.addChild("status").setContent("online");
@@ -1090,6 +1094,13 @@ public class XmppConnectionService extends Service {
 	public void setOnRenameListener(OnRenameListener listener) {
 		this.renameListener = listener;
 	}
+	
+	public void providePasswordForMuc(Conversation conversation, String password) {
+		if (conversation.getMode() == Conversation.MODE_MULTI) {
+			conversation.getMucOptions().setPassword(password);
+			joinMuc(conversation);
+		}
+	}
 
 	public void renameInMuc(final Conversation conversation, final String nick) {
 		final MucOptions options = conversation.getMucOptions();

src/eu/siacs/conversations/ui/ConversationFragment.java 🔗

@@ -15,6 +15,7 @@ import eu.siacs.conversations.entities.MucOptions;
 import eu.siacs.conversations.services.XmppConnectionService;
 import eu.siacs.conversations.ui.EditMessage.OnEnterPressed;
 import eu.siacs.conversations.ui.XmppActivity.OnPresenceSelected;
+import eu.siacs.conversations.ui.XmppActivity.OnValueEdited;
 import eu.siacs.conversations.ui.adapter.MessageAdapter;
 import eu.siacs.conversations.ui.adapter.MessageAdapter.OnContactPictureClicked;
 import eu.siacs.conversations.ui.adapter.MessageAdapter.OnContactPictureLongClicked;
@@ -128,6 +129,25 @@ public class ConversationFragment extends Fragment {
 		}
 	};
 
+	private OnClickListener enterPassword = new OnClickListener() {
+
+		@Override
+		public void onClick(View v) {
+			MucOptions muc = conversation.getMucOptions();
+			String password = muc.getPassword();
+			if (password==null) {
+				password = "";
+			}
+			activity.quickEdit(password, new OnValueEdited() {
+				
+				@Override
+				public void onValueEdited(String value) {
+					activity.xmppConnectionService.providePasswordForMuc(conversation,value);
+				}
+			});
+		}
+	};
+
 	private OnScrollListener mOnScrollListener = new OnScrollListener() {
 
 		@Override
@@ -287,10 +307,12 @@ public class ConversationFragment extends Fragment {
 		if (oldString.isEmpty() || mEditMessage.getSelectionStart() == 0) {
 			mEditMessage.getText().insert(0, nick + ": ");
 		} else {
-			if (mEditMessage.getText().charAt(mEditMessage.getSelectionStart()-1)!=' ') {
-				nick = " "+nick;
+			if (mEditMessage.getText().charAt(
+					mEditMessage.getSelectionStart() - 1) != ' ') {
+				nick = " " + nick;
 			}
-			mEditMessage.getText().insert(mEditMessage.getSelectionStart(), nick + " ");
+			mEditMessage.getText().insert(mEditMessage.getSelectionStart(),
+					nick + " ");
 		}
 	}
 
@@ -337,8 +359,7 @@ public class ConversationFragment extends Fragment {
 				activity.getSlidingPaneLayout().closePane();
 				activity.getActionBar().setDisplayHomeAsUpEnabled(true);
 				activity.getActionBar().setHomeButtonEnabled(true);
-				activity.getActionBar().setTitle(
-						conversation.getName());
+				activity.getActionBar().setTitle(conversation.getName());
 				activity.invalidateOptionsMenu();
 			}
 		}
@@ -385,14 +406,15 @@ public class ConversationFragment extends Fragment {
 		if (this.conversation != null) {
 			final Contact contact = this.conversation.getContact();
 			if (this.conversation.isMuted()) {
-				showSnackbar(R.string.notifications_disabled, R.string.enable, new OnClickListener() {
-					
-					@Override
-					public void onClick(View v) {
-						conversation.setMutedTill(0);
-						updateMessages();
-					}
-				});
+				showSnackbar(R.string.notifications_disabled, R.string.enable,
+						new OnClickListener() {
+
+							@Override
+							public void onClick(View v) {
+								conversation.setMutedTill(0);
+								updateMessages();
+							}
+						});
 			} else if (!contact.showInRoster()
 					&& contact
 							.getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) {
@@ -435,12 +457,20 @@ public class ConversationFragment extends Fragment {
 			} else {
 				if (!conversation.getMucOptions().online()
 						&& conversation.getAccount().getStatus() == Account.STATUS_ONLINE) {
-					if (conversation.getMucOptions().getError() == MucOptions.ERROR_NICK_IN_USE) {
+					int error = conversation.getMucOptions().getError();
+					switch (error) {
+					case MucOptions.ERROR_NICK_IN_USE:
 						showSnackbar(R.string.nick_in_use, R.string.edit,
 								clickToMuc);
-					} else if (conversation.getMucOptions().getError() == MucOptions.ERROR_ROOM_NOT_FOUND) {
+						break;
+					case MucOptions.ERROR_ROOM_NOT_FOUND:
 						showSnackbar(R.string.conference_not_found,
 								R.string.leave, leaveMuc);
+					case MucOptions.ERROR_PASSWORD_REQUIRED:
+						showSnackbar(R.string.conference_requires_password,
+								R.string.enter_password, enterPassword);
+					default:
+						break;
 					}
 				}
 			}
@@ -448,7 +478,6 @@ public class ConversationFragment extends Fragment {
 			updateChatMsgHint();
 			if (!activity.shouldPaneBeOpen()) {
 				activity.xmppConnectionService.markRead(conversation);
-				// TODO update notifications
 				UIHelper.updateNotification(getActivity(),
 						activity.getConversationList(), null, false);
 				activity.updateConversationList();
@@ -493,7 +522,8 @@ public class ConversationFragment extends Fragment {
 		Set<String> knownFingerprints = conversation.getContact()
 				.getOtrFingerprints();
 		if ((latestEncryption == Message.ENCRYPTION_OTR)
-				&& (conversation.hasValidOtrSession() && (!conversation.isMuted())
+				&& (conversation.hasValidOtrSession()
+						&& (!conversation.isMuted())
 						&& (conversation.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) && (!knownFingerprints
 							.contains(conversation.getOtrFingerprint())))) {
 			showSnackbar(R.string.unknown_otr_fingerprint, R.string.verify,