Add error message for invalid links

This commit is contained in:
Torsten Grote
2018-10-23 13:37:59 -03:00
parent b0b233d3dd
commit 6985f2d31a
3 changed files with 80 additions and 37 deletions

View File

@@ -17,6 +17,7 @@ import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener
import org.briarproject.briar.api.messaging.MessagingManager; import org.briarproject.briar.api.messaging.MessagingManager;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.regex.Pattern;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
@@ -41,7 +42,10 @@ public class ContactLinkExchangeActivity extends BriarActivity implements
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(ContactLinkExchangeActivity.class.getName()); Logger.getLogger(ContactLinkExchangeActivity.class.getName());
static final String OUR_LINK = "briar://" + getRandomBase32String(128); static final int LINK_LENGTH = 128;
static final Pattern LINK_REGEX =
Pattern.compile("(briar://)?([a-z2-7]{" + LINK_LENGTH + "})");
static final String OUR_LINK = "briar://" + getRandomBase32String(LINK_LENGTH);;
@Inject @Inject
LifecycleManager lifecycleManager; LifecycleManager lifecycleManager;
@@ -104,9 +108,8 @@ public class ContactLinkExchangeActivity extends BriarActivity implements
} }
} }
boolean isBriarLink(CharSequence s) { boolean isBriarLink(@Nullable CharSequence s) {
String link = s.toString().trim(); return s != null && LINK_REGEX.matcher(s).matches();
return link.matches("^(briar://)?[a-z2-7]{64}$");
} }
void scanCode() { void scanCode() {
@@ -132,7 +135,7 @@ public class ContactLinkExchangeActivity extends BriarActivity implements
AlarmManager alarmManager = AlarmManager alarmManager =
(AlarmManager) requireNonNull(getSystemService(ALARM_SERVICE)); (AlarmManager) requireNonNull(getSystemService(ALARM_SERVICE));
double random = getPseudoRandom(link, OUR_LINK); double random = getPseudoRandom(link, OUR_LINK.replace("briar://", ""));
long m = MINUTES.toMillis(1); long m = MINUTES.toMillis(1);
long fromNow = (long) (-m * Math.log(random)); long fromNow = (long) (-m * Math.log(random));
LOG.info("Delay " + fromNow + " ms based on seed " + random); LOG.info("Delay " + fromNow + " ms based on seed " + random);

View File

@@ -6,6 +6,8 @@ import android.content.Intent;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.design.widget.TextInputEditText;
import android.support.design.widget.TextInputLayout;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.text.Editable; import android.text.Editable;
import android.text.TextWatcher; import android.text.TextWatcher;
@@ -13,7 +15,6 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
@@ -21,6 +22,8 @@ import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent; import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.fragment.BaseFragment; import org.briarproject.briar.android.fragment.BaseFragment;
import java.util.regex.Matcher;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static android.content.Context.CLIPBOARD_SERVICE; import static android.content.Context.CLIPBOARD_SERVICE;
@@ -31,6 +34,7 @@ import static android.support.v4.graphics.drawable.DrawableCompat.setTint;
import static android.support.v4.graphics.drawable.DrawableCompat.wrap; import static android.support.v4.graphics.drawable.DrawableCompat.wrap;
import static android.widget.Toast.LENGTH_SHORT; import static android.widget.Toast.LENGTH_SHORT;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import static org.briarproject.briar.android.contact.ContactLinkExchangeActivity.LINK_REGEX;
import static org.briarproject.briar.android.contact.ContactLinkExchangeActivity.OUR_LINK; import static org.briarproject.briar.android.contact.ContactLinkExchangeActivity.OUR_LINK;
import static org.briarproject.briar.android.util.UiUtils.resolveColorAttribute; import static org.briarproject.briar.android.util.UiUtils.resolveColorAttribute;
@@ -48,8 +52,8 @@ public class ContactLinkExchangeFragment extends BaseFragment
} }
private ClipboardManager clipboard; private ClipboardManager clipboard;
private EditText linkInput; private TextInputLayout linkInputLayout;
private EditText contactNameInput; private TextInputEditText linkInput, contactNameInput;
private Button addButton; private Button addButton;
@Override @Override
@@ -92,6 +96,7 @@ public class ContactLinkExchangeFragment extends BaseFragment
contactNameInput.setCompoundDrawables(drawable, null, null, null); contactNameInput.setCompoundDrawables(drawable, null, null, null);
} }
linkInputLayout = v.findViewById(R.id.linkInputLayout);
linkInput = v.findViewById(R.id.linkInput); linkInput = v.findViewById(R.id.linkInput);
if (SDK_INT < 23) { if (SDK_INT < 23) {
Drawable drawable = wrap(linkInput.getCompoundDrawables()[0]); Drawable drawable = wrap(linkInput.getCompoundDrawables()[0]);
@@ -166,21 +171,38 @@ public class ContactLinkExchangeFragment extends BaseFragment
} }
private void updateAddButtonState() { private void updateAddButtonState() {
addButton.setEnabled(contactNameInput.getText().length() > 0 && boolean validContactName = contactNameInput.getText() != null &&
isBriarLink(linkInput.getText().toString())); contactNameInput.getText().length() > 0;
boolean briarLink = isBriarLink(linkInput.getText());
if (briarLink) {
linkInputLayout.setErrorEnabled(false);
} else {
linkInputLayout.setError("Invalid link");
}
addButton.setEnabled(validContactName && briarLink);
} }
private boolean isBriarLink(CharSequence s) { private boolean isBriarLink(@Nullable CharSequence s) {
ContactLinkExchangeActivity activity = getCastActivity(); ContactLinkExchangeActivity activity = getCastActivity();
return activity != null && activity.isBriarLink(s); return activity != null && activity.isBriarLink(s);
} }
@Nullable
private String getLink() {
Matcher matcher = LINK_REGEX.matcher(linkInput.getText());
if (matcher.matches()) // needs to be called before groups become available
return matcher.group(2);
else
return null;
}
private void onAddButtonClicked() { private void onAddButtonClicked() {
ContactLinkExchangeActivity activity = getCastActivity(); ContactLinkExchangeActivity activity = getCastActivity();
if (activity == null) return; if (activity == null) return;
String linkText = linkInput.getText().toString(); String linkText = getLink();
if (linkText.equals(OUR_LINK)) { if (linkText == null) throw new AssertionError();
if (OUR_LINK.equals("briar://" + linkText)) {
new AlertDialog.Builder(activity, R.style.BriarDialogTheme_Neutral) new AlertDialog.Builder(activity, R.style.BriarDialogTheme_Neutral)
.setMessage( .setMessage(
"Add the link you get from your contact, not your own link.") "Add the link you get from your contact, not your own link.")

View File

@@ -11,37 +11,55 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="@dimen/margin_large"> android:padding="@dimen/margin_large">
<EditText <android.support.design.widget.TextInputLayout
android:id="@+id/contactNameInput" android:id="@+id/contactNameLayout"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:drawableLeft="@drawable/ic_person" app:errorEnabled="true"
android:drawablePadding="8dp" app:hintEnabled="false"
android:drawableStart="@drawable/ic_person"
android:drawableTint="?attr/colorControlNormal"
android:hint="@string/contact_name_hint"
android:importantForAutofill="no"
android:inputType="text|textCapWords"
app:layout_constraintBottom_toTopOf="@+id/addButton" app:layout_constraintBottom_toTopOf="@+id/addButton"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/pasteButton"/> app:layout_constraintTop_toBottomOf="@+id/pasteButton">
<EditText <android.support.design.widget.TextInputEditText
android:id="@+id/linkInput" android:id="@+id/contactNameInput"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawableLeft="@drawable/ic_person"
android:drawablePadding="8dp"
android:drawableStart="@drawable/ic_person"
android:drawableTint="?attr/colorControlNormal"
android:hint="@string/contact_name_hint"
android:importantForAutofill="no"
android:inputType="text|textCapWords"/>
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/linkInputLayout"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:drawableLeft="@drawable/ic_link" app:errorEnabled="true"
android:drawablePadding="8dp" app:hintEnabled="false"
android:drawableStart="@drawable/ic_link"
android:drawableTint="?attr/colorControlNormal"
android:hint="@string/contact_link_hint"
android:importantForAutofill="no"
android:inputType="textUri"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/copyButton"/> app:layout_constraintTop_toBottomOf="@+id/copyButton">
<android.support.design.widget.TextInputEditText
android:id="@+id/linkInput"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawableLeft="@drawable/ic_link"
android:drawablePadding="8dp"
android:drawableStart="@drawable/ic_link"
android:drawableTint="?attr/colorControlNormal"
android:hint="@string/contact_link_hint"
android:importantForAutofill="no"
android:inputType="textUri"/>
</android.support.design.widget.TextInputLayout>
<Button <Button
android:id="@+id/pasteButton" android:id="@+id/pasteButton"
@@ -54,10 +72,10 @@
android:drawablePadding="8dp" android:drawablePadding="8dp"
android:drawableStart="@drawable/ic_content_paste" android:drawableStart="@drawable/ic_content_paste"
android:text="@string/paste_button" android:text="@string/paste_button"
app:layout_constraintBottom_toTopOf="@+id/contactNameInput" app:layout_constraintBottom_toTopOf="@+id/contactNameLayout"
app:layout_constraintEnd_toStartOf="@id/scanCodeButton" app:layout_constraintEnd_toStartOf="@id/scanCodeButton"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linkInput"/> app:layout_constraintTop_toBottomOf="@+id/linkInputLayout"/>
<Button <Button
android:id="@+id/scanCodeButton" android:id="@+id/scanCodeButton"
@@ -116,7 +134,7 @@
android:drawablePadding="8dp" android:drawablePadding="8dp"
android:drawableStart="@drawable/ic_content_copy" android:drawableStart="@drawable/ic_content_copy"
android:text="@string/copy_button" android:text="@string/copy_button"
app:layout_constraintBottom_toTopOf="@+id/linkInput" app:layout_constraintBottom_toTopOf="@+id/linkInputLayout"
app:layout_constraintEnd_toStartOf="@id/shareButton" app:layout_constraintEnd_toStartOf="@id/shareButton"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linkView"/> app:layout_constraintTop_toBottomOf="@+id/linkView"/>
@@ -164,7 +182,7 @@
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/contactNameInput" app:layout_constraintTop_toBottomOf="@+id/contactNameLayout"
tools:enabled="true"/> tools:enabled="true"/>
</android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout>