Add extended Ascii (ñæËÌÂÝÜ...) #36

This commit is contained in:
J-Jamet
2018-03-23 16:54:32 +01:00
parent 50bf22a4c7
commit c1969402f1
6 changed files with 117 additions and 45 deletions

View File

@@ -21,14 +21,12 @@ package com.keepassdroid.dialogs;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
@@ -57,6 +55,7 @@ public class GeneratePasswordDialogFragment extends DialogFragment {
private CompoundButton spaceBox;
private CompoundButton specialsBox;
private CompoundButton bracketsBox;
private CompoundButton extendedBox;
@Override
public void onAttach(Context context) {
@@ -76,20 +75,21 @@ public class GeneratePasswordDialogFragment extends DialogFragment {
LayoutInflater inflater = getActivity().getLayoutInflater();
root = inflater.inflate(R.layout.generate_password, null);
lengthTextView = (EditText) root.findViewById(R.id.length);
lengthTextView = root.findViewById(R.id.length);
uppercaseBox = (CompoundButton) root.findViewById(R.id.cb_uppercase);
lowercaseBox = (CompoundButton) root.findViewById(R.id.cb_lowercase);
digitsBox = (CompoundButton) root.findViewById(R.id.cb_digits);
minusBox = (CompoundButton) root.findViewById(R.id.cb_minus);
underlineBox = (CompoundButton) root.findViewById(R.id.cb_underline);
spaceBox = (CompoundButton) root.findViewById(R.id.cb_space);
specialsBox = (CompoundButton) root.findViewById(R.id.cb_specials);
bracketsBox = (CompoundButton) root.findViewById(R.id.cb_brackets);
uppercaseBox = root.findViewById(R.id.cb_uppercase);
lowercaseBox = root.findViewById(R.id.cb_lowercase);
digitsBox = root.findViewById(R.id.cb_digits);
minusBox = root.findViewById(R.id.cb_minus);
underlineBox = root.findViewById(R.id.cb_underline);
spaceBox = root.findViewById(R.id.cb_space);
specialsBox = root.findViewById(R.id.cb_specials);
bracketsBox = root.findViewById(R.id.cb_brackets);
extendedBox = root.findViewById(R.id.cb_extended);
assignDefaultCharacters();
SeekBar seekBar = (SeekBar) root.findViewById(R.id.seekbar_length);
SeekBar seekBar = root.findViewById(R.id.seekbar_length);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
@@ -102,34 +102,25 @@ public class GeneratePasswordDialogFragment extends DialogFragment {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {}
});
seekBar.setProgress(PreferencesUtil.getDefaultPasswordLength(getContext().getApplicationContext()));
seekBar.setProgress(PreferencesUtil.getDefaultPasswordLength(getContext()));
Button genPassButton = (Button) root.findViewById(R.id.generate_password_button);
genPassButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
fillPassword();
}
});
Button genPassButton = root.findViewById(R.id.generate_password_button);
genPassButton.setOnClickListener(v -> fillPassword());
builder.setView(root)
.setPositiveButton(R.string.accept, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
EditText password = (EditText) root.findViewById(R.id.password);
Bundle bundle = new Bundle();
bundle.putString(KEY_PASSWORD_ID, password.getText().toString());
mListener.acceptPassword(bundle);
.setPositiveButton(R.string.accept, (dialog, id) -> {
EditText password = root.findViewById(R.id.password);
Bundle bundle = new Bundle();
bundle.putString(KEY_PASSWORD_ID, password.getText().toString());
mListener.acceptPassword(bundle);
dismiss();
}
dismiss();
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Bundle bundle = new Bundle();
mListener.cancelPassword(bundle);
.setNegativeButton(R.string.cancel, (dialog, id) -> {
Bundle bundle = new Bundle();
mListener.cancelPassword(bundle);
dismiss();
}
dismiss();
});
// Pre-populate a password to possibly save the user a few clicks
@@ -147,9 +138,10 @@ public class GeneratePasswordDialogFragment extends DialogFragment {
spaceBox.setChecked(false);
specialsBox.setChecked(false);
bracketsBox.setChecked(false);
extendedBox.setChecked(false);
Set<String> defaultPasswordChars =
PreferencesUtil.getDefaultPasswordCharacters(getContext().getApplicationContext());
PreferencesUtil.getDefaultPasswordCharacters(getContext());
for(String passwordChar : defaultPasswordChars) {
if (passwordChar.equals(getString(R.string.value_password_uppercase))) {
uppercaseBox.setChecked(true);
@@ -175,11 +167,14 @@ public class GeneratePasswordDialogFragment extends DialogFragment {
else if (passwordChar.equals(getString(R.string.value_password_brackets))) {
bracketsBox.setChecked(true);
}
else if (passwordChar.equals(getString(R.string.value_password_extended))) {
extendedBox.setChecked(true);
}
}
}
private void fillPassword() {
EditText txtPassword = (EditText) root.findViewById(R.id.password);
EditText txtPassword = root.findViewById(R.id.password);
txtPassword.setText(generatePassword());
}
@@ -197,7 +192,8 @@ public class GeneratePasswordDialogFragment extends DialogFragment {
underlineBox.isChecked(),
spaceBox.isChecked(),
specialsBox.isChecked(),
bracketsBox.isChecked());
bracketsBox.isChecked(),
extendedBox.isChecked());
} catch (NumberFormatException e) {
Toast.makeText(getContext(), R.string.error_wrong_length, Toast.LENGTH_LONG).show();
} catch (IllegalArgumentException e) {

View File

@@ -27,7 +27,7 @@ import com.kunzisoft.keepass.R;
public class PasswordGenerator {
private static final String UPPERCASE_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final String LOWERCASE_CHARS = "abcdefghijklmnopqrstuvwxyz";
private static final String LOWERCASE_CHARS = "abcdefghijklmnopqrstuvwxyz";
private static final String DIGIT_CHARS = "0123456789";
private static final String MINUS_CHAR = "-";
private static final String UNDERLINE_CHAR = "_";
@@ -35,6 +35,19 @@ public class PasswordGenerator {
private static final String SPECIAL_CHARS = "!\"#$%&'*+,./:;=?@\\^`";
private static final String BRACKET_CHARS = "[]{}()<>";
// From KeePassXC code https://github.com/keepassxreboot/keepassxc/pull/538
private String extendedChars() {
StringBuilder charSet = new StringBuilder();
// [U+0080, U+009F] are C1 control characters,
// U+00A0 is non-breaking space
for(char ch = '\u00A1'; ch <= '\u00AC'; ++ch)
charSet.append(ch);
// U+00AD is soft hyphen (format character)
for(char ch = '\u00AE'; ch < '\u00FF'; ++ch)
charSet.append(ch);
charSet.append('\u00FF');
return charSet.toString();
}
private Context cxt;
@@ -42,22 +55,48 @@ public class PasswordGenerator {
this.cxt = cxt;
}
public String generatePassword(int length, boolean upperCase, boolean lowerCase, boolean digits, boolean minus, boolean underline, boolean space, boolean specials, boolean brackets) throws IllegalArgumentException{
public String generatePassword(int length,
boolean upperCase,
boolean lowerCase,
boolean digits,
boolean minus,
boolean underline,
boolean space,
boolean specials,
boolean brackets,
boolean extended) throws IllegalArgumentException{
// Desired password length is 0 or less
if (length <= 0) {
throw new IllegalArgumentException(cxt.getString(R.string.error_wrong_length));
}
// No option has been checked
if (!upperCase && !lowerCase && !digits && !minus && !underline && !space && !specials && !brackets) {
if ( !upperCase
&& !lowerCase
&& !digits
&& !minus
&& !underline
&& !space
&& !specials
&& !brackets
&& !extended) {
throw new IllegalArgumentException(cxt.getString(R.string.error_pass_gen_type));
}
String characterSet = getCharacterSet(upperCase, lowerCase, digits, minus, underline, space, specials, brackets);
String characterSet = getCharacterSet(
upperCase,
lowerCase,
digits,
minus,
underline,
space,
specials,
brackets,
extended);
int size = characterSet.length();
StringBuffer buffer = new StringBuffer();
StringBuilder buffer = new StringBuilder();
SecureRandom random = new SecureRandom(); // use more secure variant of Random!
if (size > 0) {
@@ -69,8 +108,16 @@ public class PasswordGenerator {
return buffer.toString();
}
public String getCharacterSet(boolean upperCase, boolean lowerCase, boolean digits, boolean minus, boolean underline, boolean space, boolean specials, boolean brackets) {
StringBuffer charSet = new StringBuffer();
private String getCharacterSet(boolean upperCase,
boolean lowerCase,
boolean digits,
boolean minus,
boolean underline,
boolean space,
boolean specials,
boolean brackets,
boolean extended) {
StringBuilder charSet = new StringBuilder();
if (upperCase) {
charSet.append(UPPERCASE_CHARS);
@@ -104,6 +151,10 @@ public class PasswordGenerator {
charSet.append(BRACKET_CHARS);
}
if (extended) {
charSet.append(extendedChars());
}
return charSet.toString();
}
}

View File

@@ -257,6 +257,27 @@
android:text="@string/visual_brackets" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<CheckBox android:id="@+id/cb_extended"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/extended_ASCII"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:gravity="end"
android:layout_toEndOf="@+id/cb_extended"
android:layout_toRightOf="@+id/cb_extended"
android:text="@string/visual_extended" />
</RelativeLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>

View File

@@ -35,6 +35,7 @@
<string name="menu_form_filling_settings">Remplissage de formulaire</string>
<string name="beta_dontask">Ne plus afficher</string>
<string name="brackets">Crochets</string>
<string name="extended_ASCII">ASCII étendu</string>
<string name="browser_intall_text">File browsing requires the Open Intents File Manager, click below to install it. Due to some quirks in the file manager, browsing may not work correctly, the first time you browse.</string>
<string name="cancel">Annuler</string>
<string name="allow">Permettre</string>

View File

@@ -121,6 +121,7 @@
<string name="value_password_space" translatable="false">value_password_space</string>
<string name="value_password_special" translatable="false">value_password_special</string>
<string name="value_password_brackets" translatable="false">value_password_brackets</string>
<string name="value_password_extended" translatable="false">value_password_extended</string>
<string name="visual_uppercase" translatable="false">A-Z</string>
<string name="visual_lowercase" translatable="false">a-z</string>
<string name="visual_digits" translatable="false">0-9</string>
@@ -129,6 +130,7 @@
<string name="visual_space" translatable="false"> </string>
<string name="visual_special" translatable="false">&amp;\/,^@.#&quot;:%\\='$!*`;+</string>
<string name="visual_brackets" translatable="false">[](){}&lt;&gt;</string>
<string name="visual_extended" translatable="false">Extended ASCII</string>
<string-array name="list_password_generator_options_default_values">
<item translatable="false">@string/value_password_uppercase</item>
<item translatable="false">@string/value_password_lowercase</item>

View File

@@ -33,6 +33,7 @@
<string name="application">Application</string>
<string name="beta_dontask">Don\'t show again</string>
<string name="brackets">Brackets</string>
<string name="extended_ASCII">Extended ASCII</string>
<string name="browser_intall_text">File browsing requires the Open Intents File Manager, click below to install it. Due to some quirks in the file manager, browsing may not work correctly, the first time you browse.</string>
<string name="cancel">Cancel</string>
<string name="allow">Allow</string>