add contact dialog: warn on suspicious addresses
This commit is contained in:
		
							parent
							
								
									c4348e92e8
								
							
						
					
					
						commit
						76fb17c972
					
				| @ -73,7 +73,8 @@ public class BlocklistActivity extends AbstractSearchableListItemActivity implem | |||||||
| 				getString(R.string.block), | 				getString(R.string.block), | ||||||
| 				null, | 				null, | ||||||
| 				account.getJid().asBareJid().toString(), | 				account.getJid().asBareJid().toString(), | ||||||
| 				true | 				true, | ||||||
|  | 				false | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		dialog.setOnEnterJidDialogPositiveListener((accountJid, contactJid) -> { | 		dialog.setOnEnterJidDialogPositiveListener((accountJid, contactJid) -> { | ||||||
|  | |||||||
| @ -313,7 +313,8 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity im | |||||||
|                 getString(R.string.select), |                 getString(R.string.select), | ||||||
|                 jid == null ? null : jid.asBareJid().toString(), |                 jid == null ? null : jid.asBareJid().toString(), | ||||||
|                 getIntent().getStringExtra(EXTRA_ACCOUNT), |                 getIntent().getStringExtra(EXTRA_ACCOUNT), | ||||||
|                 true |                 true, | ||||||
|  |                 false | ||||||
|         ); |         ); | ||||||
| 
 | 
 | ||||||
|         dialog.setOnEnterJidDialogPositiveListener((accountJid, contactJid) -> { |         dialog.setOnEnterJidDialogPositiveListener((accountJid, contactJid) -> { | ||||||
|  | |||||||
| @ -1,24 +1,20 @@ | |||||||
| package eu.siacs.conversations.ui; | package eu.siacs.conversations.ui; | ||||||
| 
 | 
 | ||||||
| import android.app.Activity; | import android.app.Activity; | ||||||
|  | import android.app.Dialog; | ||||||
| import android.databinding.DataBindingUtil; | import android.databinding.DataBindingUtil; | ||||||
|  | import android.os.Bundle; | ||||||
| import android.support.annotation.NonNull; | import android.support.annotation.NonNull; | ||||||
| import android.support.v4.app.DialogFragment; | import android.support.v4.app.DialogFragment; | ||||||
| import android.os.Bundle; |  | ||||||
| import android.support.v7.app.AlertDialog; | import android.support.v7.app.AlertDialog; | ||||||
| import android.app.Dialog; | import android.text.Editable; | ||||||
| import android.util.Log; | import android.text.TextWatcher; | ||||||
| import android.view.KeyEvent; |  | ||||||
| import android.view.View; | import android.view.View; | ||||||
| import android.widget.ArrayAdapter; | import android.widget.ArrayAdapter; | ||||||
| import android.widget.AutoCompleteTextView; |  | ||||||
| import android.widget.Spinner; |  | ||||||
| import android.widget.TextView; |  | ||||||
| 
 | 
 | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
|  | import java.util.Arrays; | ||||||
| import java.util.Collection; | import java.util.Collection; | ||||||
| import java.util.Collections; |  | ||||||
| import java.util.HashSet; |  | ||||||
| import java.util.List; | import java.util.List; | ||||||
| 
 | 
 | ||||||
| import eu.siacs.conversations.Config; | import eu.siacs.conversations.Config; | ||||||
| @ -29,7 +25,10 @@ import eu.siacs.conversations.ui.interfaces.OnBackendConnected; | |||||||
| import eu.siacs.conversations.ui.util.DelayedHintHelper; | import eu.siacs.conversations.ui.util.DelayedHintHelper; | ||||||
| import rocks.xmpp.addr.Jid; | import rocks.xmpp.addr.Jid; | ||||||
| 
 | 
 | ||||||
| public class EnterJidDialog extends DialogFragment implements OnBackendConnected { | public class EnterJidDialog extends DialogFragment implements OnBackendConnected, TextWatcher { | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	private static final List<String> SUSPICIOUS_DOMAINS = Arrays.asList("conference","muc","room","rooms","chat"); | ||||||
| 
 | 
 | ||||||
| 	private OnEnterJidDialogPositiveListener mListener = null; | 	private OnEnterJidDialogPositiveListener mListener = null; | ||||||
| 
 | 
 | ||||||
| @ -39,12 +38,21 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected | |||||||
| 	private static final String ACCOUNT_KEY = "account"; | 	private static final String ACCOUNT_KEY = "account"; | ||||||
| 	private static final String ALLOW_EDIT_JID_KEY = "allow_edit_jid"; | 	private static final String ALLOW_EDIT_JID_KEY = "allow_edit_jid"; | ||||||
| 	private static final String ACCOUNTS_LIST_KEY = "activated_accounts_list"; | 	private static final String ACCOUNTS_LIST_KEY = "activated_accounts_list"; | ||||||
|  | 	private static final String SANITY_CHECK_JID = "sanity_check_jid"; | ||||||
| 
 | 
 | ||||||
| 	private KnownHostsAdapter knownHostsAdapter; | 	private KnownHostsAdapter knownHostsAdapter; | ||||||
| 
 | 
 | ||||||
|  | 	private EnterJidDialogBinding binding; | ||||||
|  | 	private AlertDialog dialog; | ||||||
|  | 	private boolean sanityCheckJid = false; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	private boolean issuedWarning = false; | ||||||
|  | 
 | ||||||
| 	public static EnterJidDialog newInstance(final List<String> activatedAccounts, | 	public static EnterJidDialog newInstance(final List<String> activatedAccounts, | ||||||
| 	                                         final String title, final String positiveButton, | 	                                         final String title, final String positiveButton, | ||||||
| 	                                         final String prefilledJid, final String account, boolean allowEditJid) { | 	                                         final String prefilledJid, final String account, | ||||||
|  | 											 boolean allowEditJid, final boolean sanity_check_jid) { | ||||||
| 		EnterJidDialog dialog = new EnterJidDialog(); | 		EnterJidDialog dialog = new EnterJidDialog(); | ||||||
| 		Bundle bundle = new Bundle(); | 		Bundle bundle = new Bundle(); | ||||||
| 		bundle.putString(TITLE_KEY, title); | 		bundle.putString(TITLE_KEY, title); | ||||||
| @ -53,6 +61,7 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected | |||||||
| 		bundle.putString(ACCOUNT_KEY, account); | 		bundle.putString(ACCOUNT_KEY, account); | ||||||
| 		bundle.putBoolean(ALLOW_EDIT_JID_KEY, allowEditJid); | 		bundle.putBoolean(ALLOW_EDIT_JID_KEY, allowEditJid); | ||||||
| 		bundle.putStringArrayList(ACCOUNTS_LIST_KEY, (ArrayList<String>) activatedAccounts); | 		bundle.putStringArrayList(ACCOUNTS_LIST_KEY, (ArrayList<String>) activatedAccounts); | ||||||
|  | 		bundle.putBoolean(SANITY_CHECK_JID, sanity_check_jid); | ||||||
| 		dialog.setArguments(bundle); | 		dialog.setArguments(bundle); | ||||||
| 		return dialog; | 		return dialog; | ||||||
| 	} | 	} | ||||||
| @ -77,9 +86,10 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected | |||||||
| 	public Dialog onCreateDialog(Bundle savedInstanceState) { | 	public Dialog onCreateDialog(Bundle savedInstanceState) { | ||||||
| 		final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); | 		final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); | ||||||
| 		builder.setTitle(getArguments().getString(TITLE_KEY)); | 		builder.setTitle(getArguments().getString(TITLE_KEY)); | ||||||
| 		EnterJidDialogBinding binding = DataBindingUtil.inflate(getActivity().getLayoutInflater(), R.layout.enter_jid_dialog, null, false); | 		binding = DataBindingUtil.inflate(getActivity().getLayoutInflater(), R.layout.enter_jid_dialog, null, false); | ||||||
| 		this.knownHostsAdapter = new KnownHostsAdapter(getActivity(), R.layout.simple_list_item); | 		this.knownHostsAdapter = new KnownHostsAdapter(getActivity(), R.layout.simple_list_item); | ||||||
| 		binding.jid.setAdapter(this.knownHostsAdapter); | 		binding.jid.setAdapter(this.knownHostsAdapter); | ||||||
|  | 		binding.jid.addTextChangedListener(this); | ||||||
| 		String prefilledJid = getArguments().getString(PREFILLED_JID_KEY); | 		String prefilledJid = getArguments().getString(PREFILLED_JID_KEY); | ||||||
| 		if (prefilledJid != null) { | 		if (prefilledJid != null) { | ||||||
| 			binding.jid.append(prefilledJid); | 			binding.jid.append(prefilledJid); | ||||||
| @ -90,6 +100,7 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected | |||||||
| 				binding.jid.setCursorVisible(false); | 				binding.jid.setCursorVisible(false); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | 		sanityCheckJid = getArguments().getBoolean(SANITY_CHECK_JID, false); | ||||||
| 
 | 
 | ||||||
| 		DelayedHintHelper.setHint(R.string.account_settings_example_jabber_id, binding.jid); | 		DelayedHintHelper.setHint(R.string.account_settings_example_jabber_id, binding.jid); | ||||||
| 
 | 
 | ||||||
| @ -110,14 +121,14 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected | |||||||
| 		builder.setView(binding.getRoot()); | 		builder.setView(binding.getRoot()); | ||||||
| 		builder.setNegativeButton(R.string.cancel, null); | 		builder.setNegativeButton(R.string.cancel, null); | ||||||
| 		builder.setPositiveButton(getArguments().getString(POSITIVE_BUTTON_KEY), null); | 		builder.setPositiveButton(getArguments().getString(POSITIVE_BUTTON_KEY), null); | ||||||
| 		AlertDialog dialog = builder.create(); | 		this.dialog = builder.create(); | ||||||
| 
 | 
 | ||||||
| 		View.OnClickListener dialogOnClick = v -> { | 		View.OnClickListener dialogOnClick = v -> { | ||||||
| 			handleEnter(binding, account, dialog); | 			handleEnter(binding, account); | ||||||
| 		}; | 		}; | ||||||
| 
 | 
 | ||||||
| 		binding.jid.setOnEditorActionListener((v, actionId, event) -> { | 		binding.jid.setOnEditorActionListener((v, actionId, event) -> { | ||||||
| 			handleEnter(binding, account, dialog); | 			handleEnter(binding, account); | ||||||
| 			return true; | 			return true; | ||||||
| 		}); | 		}); | ||||||
| 
 | 
 | ||||||
| @ -126,7 +137,7 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected | |||||||
| 		return dialog; | 		return dialog; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private void handleEnter(EnterJidDialogBinding binding, String account, Dialog dialog) { | 	private void handleEnter(EnterJidDialogBinding binding, String account) { | ||||||
| 		final Jid accountJid; | 		final Jid accountJid; | ||||||
| 		if (!binding.account.isEnabled() && account == null) { | 		if (!binding.account.isEnabled() && account == null) { | ||||||
| 			return; | 			return; | ||||||
| @ -148,6 +159,21 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected | |||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		if (!issuedWarning && sanityCheckJid) { | ||||||
|  | 			if (contactJid.isDomainJid()) { | ||||||
|  | 				binding.jid.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())) { | ||||||
|  | 				binding.jid.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) { | 		if (mListener != null) { | ||||||
| 			try { | 			try { | ||||||
| 				if (mListener.onEnterJidDialogPositive(accountJid, contactJid)) { | 				if (mListener.onEnterJidDialogPositive(accountJid, contactJid)) { | ||||||
| @ -176,6 +202,24 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	@Override | ||||||
|  | 	public void beforeTextChanged(CharSequence s, int start, int count, int after) { | ||||||
|  | 
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Override | ||||||
|  | 	public void onTextChanged(CharSequence s, int start, int before, int count) { | ||||||
|  | 
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Override | ||||||
|  | 	public void afterTextChanged(Editable s) { | ||||||
|  | 		if (issuedWarning) { | ||||||
|  | 			dialog.getButton(AlertDialog.BUTTON_POSITIVE).setText(R.string.add); | ||||||
|  | 			issuedWarning = false; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	public interface OnEnterJidDialogPositiveListener { | 	public interface OnEnterJidDialogPositiveListener { | ||||||
| 		boolean onEnterJidDialogPositive(Jid account, Jid contact) throws EnterJidDialog.JidError; | 		boolean onEnterJidDialogPositive(Jid account, Jid contact) throws EnterJidDialog.JidError; | ||||||
| 	} | 	} | ||||||
| @ -200,4 +244,9 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected | |||||||
| 		} | 		} | ||||||
| 		super.onDestroyView(); | 		super.onDestroyView(); | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	private static boolean suspiciousSubDomain(String domain) { | ||||||
|  | 		final String[] parts = domain.split("\\."); | ||||||
|  | 		return parts.length >= 3 && SUSPICIOUS_DOMAINS.contains(parts[0]); | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  | |||||||
| @ -495,7 +495,8 @@ public class StartConversationActivity extends XmppActivity implements XmppConne | |||||||
| 				getString(R.string.add), | 				getString(R.string.add), | ||||||
| 				prefilledJid, | 				prefilledJid, | ||||||
| 				null, | 				null, | ||||||
| 				invite == null || !invite.hasFingerprints() | 				invite == null || !invite.hasFingerprints(), | ||||||
|  | 				true | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		dialog.setOnEnterJidDialogPositiveListener((accountJid, contactJid) -> { | 		dialog.setOnEnterJidDialogPositiveListener((accountJid, contactJid) -> { | ||||||
|  | |||||||
| @ -863,4 +863,7 @@ | |||||||
|     <string name="i_already_have_an_account">I already have an account</string> |     <string name="i_already_have_an_account">I already have an account</string> | ||||||
|     <string name="add_existing_account">Add existing account</string> |     <string name="add_existing_account">Add existing account</string> | ||||||
|     <string name="register_new_account">Register new account</string> |     <string name="register_new_account">Register new account</string> | ||||||
|  |     <string name="this_looks_like_a_domain">This looks like a domain address</string> | ||||||
|  |     <string name="add_anway">Add anyway</string> | ||||||
|  |     <string name="this_looks_like_channel">This looks like a channel address</string> | ||||||
| </resources> | </resources> | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Daniel Gultsch
						Daniel Gultsch