Handle user input on key creation more generously
Allow empty name and do not regex-check email fixes #1825
This commit is contained in:
parent
88ba5688d8
commit
249b8d7d78
|
@ -78,18 +78,20 @@ public abstract class KeyRing {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a composed user id. Returns null if name is null!
|
* Returns a composed user id. Returns null if name, email and comment are empty.
|
||||||
*/
|
*/
|
||||||
public static String createUserId(UserId userId) {
|
public static String createUserId(UserId userId) {
|
||||||
String userIdString = userId.name; // consider name a required value
|
StringBuilder userIdBuilder = new StringBuilder();
|
||||||
if (userIdString != null && !TextUtils.isEmpty(userId.comment)) {
|
if (!TextUtils.isEmpty(userId.name)) {
|
||||||
userIdString += " (" + userId.comment + ")";
|
userIdBuilder.append(userId.comment);
|
||||||
}
|
}
|
||||||
if (userIdString != null && !TextUtils.isEmpty(userId.email)) {
|
if (!TextUtils.isEmpty(userId.comment)) {
|
||||||
userIdString += " <" + userId.email + ">";
|
userIdBuilder.append(" (" + userId.comment + ")");
|
||||||
}
|
}
|
||||||
|
if (!TextUtils.isEmpty(userId.email)) {
|
||||||
return userIdString;
|
userIdBuilder.append(" <" + userId.email + ">");
|
||||||
|
}
|
||||||
|
return userIdBuilder.length() == 0 ? null : userIdBuilder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class UserId implements Serializable {
|
public static class UserId implements Serializable {
|
||||||
|
|
|
@ -44,7 +44,6 @@ import org.sufficientlysecure.keychain.ui.widget.EmailEditText;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
public class CreateKeyEmailFragment extends Fragment {
|
public class CreateKeyEmailFragment extends Fragment {
|
||||||
private CreateKeyActivity mCreateKeyActivity;
|
private CreateKeyActivity mCreateKeyActivity;
|
||||||
|
@ -52,10 +51,6 @@ public class CreateKeyEmailFragment extends Fragment {
|
||||||
private ArrayList<EmailAdapter.ViewModel> mAdditionalEmailModels = new ArrayList<>();
|
private ArrayList<EmailAdapter.ViewModel> mAdditionalEmailModels = new ArrayList<>();
|
||||||
private EmailAdapter mEmailAdapter;
|
private EmailAdapter mEmailAdapter;
|
||||||
|
|
||||||
// NOTE: Do not use more complicated pattern like defined in android.util.Patterns.EMAIL_ADDRESS
|
|
||||||
// EMAIL_ADDRESS fails for mails with umlauts for example
|
|
||||||
private static final Pattern EMAIL_PATTERN = Pattern.compile("^[\\S]+@[\\S]+\\.[a-z]+$");
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new instance of this fragment
|
* Creates new instance of this fragment
|
||||||
*/
|
*/
|
||||||
|
@ -76,16 +71,15 @@ public class CreateKeyEmailFragment extends Fragment {
|
||||||
* @return true if EditText is not empty
|
* @return true if EditText is not empty
|
||||||
*/
|
*/
|
||||||
private boolean isMainEmailValid(EditText editText) {
|
private boolean isMainEmailValid(EditText editText) {
|
||||||
boolean output = true;
|
if (editText.getText().length() == 0) {
|
||||||
if (!checkEmail(editText.getText().toString(), false)) {
|
|
||||||
editText.setError(getString(R.string.create_key_empty));
|
editText.setError(getString(R.string.create_key_empty));
|
||||||
editText.requestFocus();
|
editText.requestFocus();
|
||||||
output = false;
|
return false;
|
||||||
} else {
|
} else if (!checkEmail(editText.getText().toString(), false)){
|
||||||
editText.setError(null);
|
return false;
|
||||||
}
|
}
|
||||||
|
editText.setError(null);
|
||||||
return output;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -146,10 +140,9 @@ public class CreateKeyEmailFragment extends Fragment {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private boolean checkEmail(String email, boolean additionalEmail) {
|
private boolean checkEmail(String email, boolean additionalEmail) {
|
||||||
// check for email format or if the user did any input
|
if (email.isEmpty()) {
|
||||||
if (!isEmailFormatValid(email)) {
|
|
||||||
Notify.create(getActivity(),
|
Notify.create(getActivity(),
|
||||||
getString(R.string.create_key_email_invalid_email),
|
getString(R.string.create_key_email_empty_email),
|
||||||
Notify.LENGTH_LONG, Notify.Style.ERROR).show(CreateKeyEmailFragment.this);
|
Notify.LENGTH_LONG, Notify.Style.ERROR).show(CreateKeyEmailFragment.this);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -166,18 +159,6 @@ public class CreateKeyEmailFragment extends Fragment {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks the email format
|
|
||||||
* Uses the default Android Email Pattern
|
|
||||||
*
|
|
||||||
* @param email
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private boolean isEmailFormatValid(String email) {
|
|
||||||
// check for email format or if the user did any input
|
|
||||||
return !(email.length() == 0 || !EMAIL_PATTERN.matcher(email).matches());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks for duplicated emails inside the additional email adapter.
|
* Checks for duplicated emails inside the additional email adapter.
|
||||||
*
|
*
|
||||||
|
|
|
@ -57,6 +57,7 @@ import org.sufficientlysecure.keychain.util.Preferences;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class CreateKeyFinalFragment extends Fragment {
|
public class CreateKeyFinalFragment extends Fragment {
|
||||||
|
|
||||||
|
@ -81,6 +82,10 @@ public class CreateKeyFinalFragment extends Fragment {
|
||||||
private OperationResult mQueuedFinishResult;
|
private OperationResult mQueuedFinishResult;
|
||||||
private EditKeyResult mQueuedDisplayResult;
|
private EditKeyResult mQueuedDisplayResult;
|
||||||
|
|
||||||
|
// NOTE: Do not use more complicated pattern like defined in android.util.Patterns.EMAIL_ADDRESS
|
||||||
|
// EMAIL_ADDRESS fails for mails with umlauts for example
|
||||||
|
private static final Pattern EMAIL_PATTERN = Pattern.compile("^[\\S]+@[\\S]+\\.[a-z]+$");
|
||||||
|
|
||||||
public static CreateKeyFinalFragment newInstance() {
|
public static CreateKeyFinalFragment newInstance() {
|
||||||
CreateKeyFinalFragment frag = new CreateKeyFinalFragment();
|
CreateKeyFinalFragment frag = new CreateKeyFinalFragment();
|
||||||
frag.setRetainInstance(true);
|
frag.setRetainInstance(true);
|
||||||
|
@ -106,7 +111,11 @@ public class CreateKeyFinalFragment extends Fragment {
|
||||||
CreateKeyActivity createKeyActivity = (CreateKeyActivity) getActivity();
|
CreateKeyActivity createKeyActivity = (CreateKeyActivity) getActivity();
|
||||||
|
|
||||||
// set values
|
// set values
|
||||||
mNameEdit.setText(createKeyActivity.mName);
|
if (createKeyActivity.mName != null) {
|
||||||
|
mNameEdit.setText(createKeyActivity.mName);
|
||||||
|
} else {
|
||||||
|
mNameEdit.setText(getString(R.string.user_id_no_name));
|
||||||
|
}
|
||||||
if (createKeyActivity.mAdditionalEmails != null && createKeyActivity.mAdditionalEmails.size() > 0) {
|
if (createKeyActivity.mAdditionalEmails != null && createKeyActivity.mAdditionalEmails.size() > 0) {
|
||||||
String emailText = createKeyActivity.mEmail + ", ";
|
String emailText = createKeyActivity.mEmail + ", ";
|
||||||
Iterator<?> it = createKeyActivity.mAdditionalEmails.iterator();
|
Iterator<?> it = createKeyActivity.mAdditionalEmails.iterator();
|
||||||
|
@ -122,6 +131,8 @@ public class CreateKeyFinalFragment extends Fragment {
|
||||||
mEmailEdit.setText(createKeyActivity.mEmail);
|
mEmailEdit.setText(createKeyActivity.mEmail);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkEmailValidity();
|
||||||
|
|
||||||
mCreateButton.setOnClickListener(new View.OnClickListener() {
|
mCreateButton.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
|
@ -309,6 +320,31 @@ public class CreateKeyFinalFragment extends Fragment {
|
||||||
return saveKeyringParcel;
|
return saveKeyringParcel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkEmailValidity() {
|
||||||
|
CreateKeyActivity createKeyActivity = (CreateKeyActivity) getActivity();
|
||||||
|
|
||||||
|
boolean emailsValid = true;
|
||||||
|
if (!EMAIL_PATTERN.matcher(createKeyActivity.mEmail).matches()) {
|
||||||
|
emailsValid = false;
|
||||||
|
}
|
||||||
|
if (createKeyActivity.mAdditionalEmails != null && createKeyActivity.mAdditionalEmails.size() > 0) {
|
||||||
|
for (Iterator<?> it = createKeyActivity.mAdditionalEmails.iterator(); it.hasNext(); ) {
|
||||||
|
if (!EMAIL_PATTERN.matcher(it.next().toString()).matches()) {
|
||||||
|
emailsValid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!emailsValid) {
|
||||||
|
mEmailEdit.setError(getString(R.string.create_key_final_email_valid_warning));
|
||||||
|
mEmailEdit.setOnClickListener(new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
mNameEdit.requestFocus(); // Workaround to remove focus from email
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void createKey() {
|
private void createKey() {
|
||||||
CreateKeyActivity activity = (CreateKeyActivity) getActivity();
|
CreateKeyActivity activity = (CreateKeyActivity) getActivity();
|
||||||
if (activity == null) {
|
if (activity == null) {
|
||||||
|
|
|
@ -18,13 +18,11 @@
|
||||||
package org.sufficientlysecure.keychain.ui;
|
package org.sufficientlysecure.keychain.ui;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.EditText;
|
|
||||||
|
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction;
|
import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction;
|
||||||
|
@ -50,27 +48,6 @@ public class CreateKeyNameFragment extends Fragment {
|
||||||
return frag;
|
return frag;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if text of given EditText is not empty. If it is empty an error is
|
|
||||||
* set and the EditText gets the focus.
|
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param editText
|
|
||||||
* @return true if EditText is not empty
|
|
||||||
*/
|
|
||||||
private static boolean isEditTextNotEmpty(Context context, EditText editText) {
|
|
||||||
boolean output = true;
|
|
||||||
if (editText.getText().length() == 0) {
|
|
||||||
editText.setError(context.getString(R.string.create_key_empty));
|
|
||||||
editText.requestFocus();
|
|
||||||
output = false;
|
|
||||||
} else {
|
|
||||||
editText.setError(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.create_key_name_fragment, container, false);
|
View view = inflater.inflate(R.layout.create_key_name_fragment, container, false);
|
||||||
|
@ -109,13 +86,11 @@ public class CreateKeyNameFragment extends Fragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void nextClicked() {
|
private void nextClicked() {
|
||||||
if (isEditTextNotEmpty(getActivity(), mNameEdit)) {
|
// save state
|
||||||
// save state
|
mCreateKeyActivity.mName = mNameEdit.getText().length() == 0 ? null : mNameEdit.getText().toString();
|
||||||
mCreateKeyActivity.mName = mNameEdit.getText().toString();
|
|
||||||
|
|
||||||
CreateKeyEmailFragment frag = CreateKeyEmailFragment.newInstance();
|
CreateKeyEmailFragment frag = CreateKeyEmailFragment.newInstance();
|
||||||
mCreateKeyActivity.loadFragment(frag, FragAction.TO_RIGHT);
|
mCreateKeyActivity.loadFragment(frag, FragAction.TO_RIGHT);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,15 +23,11 @@ import android.text.Editable;
|
||||||
import android.text.InputType;
|
import android.text.InputType;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Patterns;
|
|
||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
|
|
||||||
import org.sufficientlysecure.keychain.R;
|
|
||||||
import org.sufficientlysecure.keychain.util.ContactHelper;
|
import org.sufficientlysecure.keychain.util.ContactHelper;
|
||||||
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
|
|
||||||
public class EmailEditText extends AppCompatAutoCompleteTextView {
|
public class EmailEditText extends AppCompatAutoCompleteTextView {
|
||||||
|
|
||||||
public EmailEditText(Context context) {
|
public EmailEditText(Context context) {
|
||||||
|
@ -70,20 +66,7 @@ public class EmailEditText extends AppCompatAutoCompleteTextView {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterTextChanged(Editable editable) {
|
public void afterTextChanged(Editable editable) {
|
||||||
String email = editable.toString();
|
|
||||||
if (email.length() > 0) {
|
|
||||||
Matcher emailMatcher = Patterns.EMAIL_ADDRESS.matcher(email);
|
|
||||||
if (emailMatcher.matches()) {
|
|
||||||
EmailEditText.this.setCompoundDrawablesWithIntrinsicBounds(0, 0,
|
|
||||||
R.drawable.ic_stat_retyped_ok, 0);
|
|
||||||
} else {
|
|
||||||
EmailEditText.this.setCompoundDrawablesWithIntrinsicBounds(0, 0,
|
|
||||||
R.drawable.ic_stat_retyped_bad, 0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// remove drawable if email is empty
|
|
||||||
EmailEditText.this.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,9 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_marginBottom="8dp"
|
||||||
android:layout_marginLeft="8dp"
|
android:layout_marginLeft="8dp"
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -54,6 +56,8 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_marginBottom="8dp"
|
||||||
android:layout_marginLeft="8dp" />
|
android:layout_marginLeft="8dp" />
|
||||||
|
|
||||||
|
|
|
@ -768,6 +768,7 @@
|
||||||
<string name="create_key_passphrases_not_equal">"Passwords do not match"</string>
|
<string name="create_key_passphrases_not_equal">"Passwords do not match"</string>
|
||||||
<string name="create_key_final_text">"You entered the following identity:"</string>
|
<string name="create_key_final_text">"You entered the following identity:"</string>
|
||||||
<string name="create_key_final_robot_text">"Creating a key may take a while, have a cup of coffee in the meantime…"</string>
|
<string name="create_key_final_robot_text">"Creating a key may take a while, have a cup of coffee in the meantime…"</string>
|
||||||
|
<string name="create_key_final_email_valid_warning">"Many applications work better when provided with keys only containing valid email addresses"</string>
|
||||||
<string name="create_key_rsa">"(3 subkeys, RSA, 4096 bit)"</string>
|
<string name="create_key_rsa">"(3 subkeys, RSA, 4096 bit)"</string>
|
||||||
<string name="create_key_custom">"(custom key configuration)"</string>
|
<string name="create_key_custom">"(custom key configuration)"</string>
|
||||||
<string name="create_key_name_text">"Choose a name associated with this key. This can be a full name, e.g., 'John Doe', or a nickname, e.g., 'Johnny'."</string>
|
<string name="create_key_name_text">"Choose a name associated with this key. This can be a full name, e.g., 'John Doe', or a nickname, e.g., 'Johnny'."</string>
|
||||||
|
@ -778,7 +779,7 @@
|
||||||
<string name="create_key_add_email">"Add email address"</string>
|
<string name="create_key_add_email">"Add email address"</string>
|
||||||
<string name="create_key_add_email_text">"Additional email addresses are also associated to this key and can be used for secure communication."</string>
|
<string name="create_key_add_email_text">"Additional email addresses are also associated to this key and can be used for secure communication."</string>
|
||||||
<string name="create_key_email_already_exists_text">"Email address has already been added"</string>
|
<string name="create_key_email_already_exists_text">"Email address has already been added"</string>
|
||||||
<string name="create_key_email_invalid_email">"Email address format is invalid"</string>
|
<string name="create_key_email_empty_email">"Email address can not be empty"</string>
|
||||||
<string name="create_key_yubi_key_pin_text">"Please choose a PIN with 6 numbers."</string>
|
<string name="create_key_yubi_key_pin_text">"Please choose a PIN with 6 numbers."</string>
|
||||||
<string name="create_key_yubi_key_admin_pin_text">"Please write down the Admin PIN and store it in a safe place (required when you used a wrong PIN 3 times)."</string>
|
<string name="create_key_yubi_key_admin_pin_text">"Please write down the Admin PIN and store it in a safe place (required when you used a wrong PIN 3 times)."</string>
|
||||||
<string name="create_key_yubi_key_pin">"PIN"</string>
|
<string name="create_key_yubi_key_pin">"PIN"</string>
|
||||||
|
|
Loading…
Reference in a new issue