mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Add extended Ascii (ñæËÌÂÝÜ...) #36
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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">&\/,^@.#":%\\='$!*`;+</string>
|
||||
<string name="visual_brackets" translatable="false">[](){}<></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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user