diff options
author | reroman <reroman@users.noreply.github.com> | 2019-02-03 05:22:12 -0600 |
---|---|---|
committer | Mohamed Zenadi <zeapo@users.noreply.github.com> | 2019-02-03 12:22:12 +0100 |
commit | a819343c747b2ce022c5a5c7810979a62a213dc5 (patch) | |
tree | 0f9bf561db5d963886b3f1ced8cc74ab2db0481f | |
parent | 723a40a216fbb9530317ec377db3ce1b042623f4 (diff) |
Allow to create passwords without lowercase letters. (#478)
* Clipboard now is cleared after manual copy
* Spanish translation added
* Spanish translations for commit messages updated
* Now can generate passwords free of lowercase (for example only numbers, uppercase or symbols)
Also it makes sure that uppercase is included when the generated char is ambiguous and discarded
7 files changed, 88 insertions, 15 deletions
diff --git a/app/src/main/java/com/zeapo/pwdstore/PasswordGeneratorDialogFragment.java b/app/src/main/java/com/zeapo/pwdstore/PasswordGeneratorDialogFragment.java index f161b927..698ec495 100644 --- a/app/src/main/java/com/zeapo/pwdstore/PasswordGeneratorDialogFragment.java +++ b/app/src/main/java/com/zeapo/pwdstore/PasswordGeneratorDialogFragment.java @@ -13,9 +13,13 @@ import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.TextView; +import android.widget.Toast; + import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.DialogFragment; + import com.zeapo.pwdstore.pwgen.PasswordGenerator; + import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -53,6 +57,9 @@ public class PasswordGeneratorDialogFragment extends DialogFragment { checkBox = view.findViewById(R.id.uppercase); checkBox.setChecked(!prefs.getBoolean("A", false)); + checkBox = view.findViewById(R.id.lowercase); + checkBox.setChecked(!prefs.getBoolean("L", false)); + checkBox = view.findViewById(R.id.ambiguous); checkBox.setChecked(!prefs.getBoolean("B", false)); @@ -79,12 +86,22 @@ public class PasswordGeneratorDialogFragment extends DialogFragment { final AlertDialog ad = builder.setTitle(this.getResources().getString(R.string.pwgen_title)).create(); ad.setOnShowListener(dialog -> { setPreferences(); - passwordText.setText(PasswordGenerator.INSTANCE.generate(getActivity().getApplicationContext()).get(0)); + try { + passwordText.setText(PasswordGenerator.INSTANCE.generate(getActivity().getApplicationContext()).get(0)); + } catch (PasswordGenerator.PasswordGeneratorExeption e) { + Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show(); + passwordText.setText(""); + } Button b = ad.getButton(AlertDialog.BUTTON_NEUTRAL); b.setOnClickListener(v -> { setPreferences(); - passwordText.setText(PasswordGenerator.INSTANCE.generate(callingActivity.getApplicationContext()).get(0)); + try { + passwordText.setText(PasswordGenerator.INSTANCE.generate(callingActivity.getApplicationContext()).get(0)); + } catch (PasswordGenerator.PasswordGeneratorExeption e) { + Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show(); + passwordText.setText(""); + } }); }); return ad; @@ -107,6 +124,10 @@ public class PasswordGeneratorDialogFragment extends DialogFragment { if (!((CheckBox) getDialog().findViewById(R.id.pronounceable)).isChecked()) { preferences.add("s"); } + if (!((CheckBox) getDialog().findViewById(R.id.lowercase)).isChecked()) { + preferences.add("L"); + } + EditText editText = getDialog().findViewById(R.id.lengthNumber); try { int length = Integer.valueOf(editText.getText().toString()); diff --git a/app/src/main/java/com/zeapo/pwdstore/pwgen/PasswordGenerator.kt b/app/src/main/java/com/zeapo/pwdstore/pwgen/PasswordGenerator.kt index 3a7dcc27..6132d2dc 100644 --- a/app/src/main/java/com/zeapo/pwdstore/pwgen/PasswordGenerator.kt +++ b/app/src/main/java/com/zeapo/pwdstore/pwgen/PasswordGenerator.kt @@ -1,15 +1,19 @@ package com.zeapo.pwdstore.pwgen import android.content.Context +import com.zeapo.pwdstore.R import java.util.ArrayList + + object PasswordGenerator { internal const val DIGITS = 0x0001 internal const val UPPERS = 0x0002 internal const val SYMBOLS = 0x0004 internal const val AMBIGUOUS = 0x0008 internal const val NO_VOWELS = 0x0010 + internal const val LOWERS = 0x0020 internal const val DIGITS_STR = "0123456789" internal const val UPPERS_STR = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" @@ -19,7 +23,7 @@ object PasswordGenerator { internal const val VOWELS_STR = "01aeiouyAEIOUY" // No a, c, n, h, H, C, 1, N - private const val pwOptions = "0ABsvy" + private const val pwOptions = "0ABsvyL" /** * Sets password generation preferences. @@ -35,6 +39,7 @@ object PasswordGenerator { * <tr><td>s</td><td>generate completely random passwords</td></tr> * <tr><td>v</td><td>don't include vowels</td></tr> * <tr><td>y</td><td>include at least one symbol</td></tr> + * <tr><td>L</td><td>don't include lowercase letters</td></tr> </table> * * @param numArgv numerical options for password generation: length of * generated passwords followed by number of passwords to @@ -76,17 +81,19 @@ object PasswordGenerator { * preferences file 'PasswordGenerator' * @return list of generated passwords */ + @Throws(PasswordGenerator.PasswordGeneratorExeption::class) fun generate(ctx: Context): ArrayList<String> { val prefs = ctx.getSharedPreferences("PasswordGenerator", Context.MODE_PRIVATE) var phonemes = true - var pwgenFlags = DIGITS or UPPERS + var pwgenFlags = DIGITS or UPPERS or LOWERS for (option in pwOptions.toCharArray()) { if (prefs.getBoolean(option.toString(), false)) { when (option) { '0' -> pwgenFlags = pwgenFlags and DIGITS.inv() 'A' -> pwgenFlags = pwgenFlags and UPPERS.inv() + 'L' -> pwgenFlags = pwgenFlags and LOWERS.inv() 'B' -> pwgenFlags = pwgenFlags or AMBIGUOUS 's' -> phonemes = false 'y' -> pwgenFlags = pwgenFlags or SYMBOLS @@ -99,16 +106,28 @@ object PasswordGenerator { } val length = prefs.getInt("length", 8) - if (length < 5) { - phonemes = false + var numCategories = 0 + var categories = pwgenFlags and AMBIGUOUS.inv() + + while (categories != 0) { + if (categories and 1 == 1) + numCategories++ + categories = categories shr 1 } - if (length <= 2) { - pwgenFlags = pwgenFlags and UPPERS.inv() + if (numCategories == 0) { + throw PasswordGeneratorExeption(ctx.resources.getString(R.string.pwgen_no_chars_error)) } - if (length <= 1) { - pwgenFlags = pwgenFlags and DIGITS.inv() + if (length < numCategories) { + throw PasswordGeneratorExeption(ctx.resources.getString(R.string.pwgen_length_too_short_error)) + } + if ((pwgenFlags and UPPERS) == 0 && (pwgenFlags and LOWERS) == 0) { // Only digits and/or symbols + phonemes = false + pwgenFlags = pwgenFlags and AMBIGUOUS.inv() + } else if (length < 5) { + phonemes = false } + val passwords = ArrayList<String>() val num = prefs.getInt("num", 1) for (i in 0 until num) { @@ -120,5 +139,7 @@ object PasswordGenerator { } return passwords } + + public class PasswordGeneratorExeption(string: String) : Exception(string) } diff --git a/app/src/main/java/com/zeapo/pwdstore/pwgen/Phonemes.kt b/app/src/main/java/com/zeapo/pwdstore/pwgen/Phonemes.kt index 4ec204bc..24d1edef 100644 --- a/app/src/main/java/com/zeapo/pwdstore/pwgen/Phonemes.kt +++ b/app/src/main/java/com/zeapo/pwdstore/pwgen/Phonemes.kt @@ -65,6 +65,7 @@ internal object Phonemes { * <tr><td>1</td><td>include at least one uppercase letter</td></tr> * <tr><td>2</td><td>include at least one symbol</td></tr> * <tr><td>3</td><td>don't include ambiguous characters</td></tr> + * <tr><td>5</td><td>include at least one lowercase letter</td></tr> </table> * * @return the generated password */ @@ -119,7 +120,8 @@ internal object Phonemes { // Handle UPPERS if (pwFlags and PasswordGenerator.UPPERS > 0) { - if ((first || flags and CONSONANT > 0) && RandomNumberGenerator.number(10) < 2) { + if ((pwFlags and PasswordGenerator.LOWERS == 0) || + (first || flags and CONSONANT > 0) && RandomNumberGenerator.number(10) < 2) { val index = password.length - length password = password.substring(0, index) + str.toUpperCase() featureFlags = featureFlags and PasswordGenerator.UPPERS.inv() @@ -131,6 +133,17 @@ internal object Phonemes { for (ambiguous in PasswordGenerator.AMBIGUOUS_STR.toCharArray()) { if (password.contains(ambiguous.toString())) { password = password.substring(0, curSize) + + // Still have upper letters + if ((pwFlags and PasswordGenerator.UPPERS) > 0) { + featureFlags = featureFlags or PasswordGenerator.UPPERS + for (upper in PasswordGenerator.UPPERS_STR.toCharArray()) { + if (password.contains(upper.toString())) { + featureFlags = featureFlags and PasswordGenerator.UPPERS.inv() + break + } + } + } break } } diff --git a/app/src/main/java/com/zeapo/pwdstore/pwgen/RandomPasswordGenerator.kt b/app/src/main/java/com/zeapo/pwdstore/pwgen/RandomPasswordGenerator.kt index 632fa579..5e565c0e 100644 --- a/app/src/main/java/com/zeapo/pwdstore/pwgen/RandomPasswordGenerator.kt +++ b/app/src/main/java/com/zeapo/pwdstore/pwgen/RandomPasswordGenerator.kt @@ -15,6 +15,7 @@ internal object RandomPasswordGenerator { * <tr><td>2</td><td>include at least one symbol</td></tr> * <tr><td>3</td><td>don't include ambiguous characters</td></tr> * <tr><td>4</td><td>don't include vowels</td></tr> + * <tr><td>5</td><td>include at least one lowercase</td></tr> </table> * * @return the generated password */ @@ -33,7 +34,9 @@ internal object RandomPasswordGenerator { if (pwFlags and PasswordGenerator.UPPERS > 0) { bank += PasswordGenerator.UPPERS_STR } - bank += PasswordGenerator.LOWERS_STR + if (pwFlags and PasswordGenerator.LOWERS > 0) { + bank += PasswordGenerator.LOWERS_STR + } if (pwFlags and PasswordGenerator.SYMBOLS > 0) { bank += PasswordGenerator.SYMBOLS_STR } @@ -65,8 +68,11 @@ internal object RandomPasswordGenerator { if (PasswordGenerator.SYMBOLS_STR.contains(`val`)) { featureFlags = featureFlags and PasswordGenerator.SYMBOLS.inv() } + if (PasswordGenerator.LOWERS_STR.contains(`val`)) { + featureFlags = featureFlags and PasswordGenerator.LOWERS.inv() + } } - } while (featureFlags and (PasswordGenerator.UPPERS or PasswordGenerator.DIGITS or PasswordGenerator.SYMBOLS) > 0) + } while (featureFlags and (PasswordGenerator.UPPERS or PasswordGenerator.DIGITS or PasswordGenerator.SYMBOLS or PasswordGenerator.LOWERS) > 0) return password } } diff --git a/app/src/main/res/layout/fragment_pwgen.xml b/app/src/main/res/layout/fragment_pwgen.xml index b5293920..eab23f7c 100644 --- a/app/src/main/res/layout/fragment_pwgen.xml +++ b/app/src/main/res/layout/fragment_pwgen.xml @@ -62,10 +62,10 @@ android:text="@string/pwgen_uppercase" /> <CheckBox - android:id="@+id/ambiguous" + android:id="@+id/lowercase" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="@string/pwgen_ambiguous" /> + android:text="@string/pwgen_lowercase" /> </LinearLayout> @@ -97,6 +97,12 @@ android:layout_height="wrap_content" android:text="@string/pwgen_pronounceable" /> + <CheckBox + android:id="@+id/ambiguous" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/pwgen_ambiguous" /> + </LinearLayout> </LinearLayout> </LinearLayout> diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 392be07f..84d1f7b9 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -166,8 +166,11 @@ <string name="pwgen_numerals">Números</string> <string name="pwgen_symbols">Símbolos</string> <string name="pwgen_uppercase">Mayúsculas</string> + <string name="pwgen_lowercase">Minúsculas</string> <string name="pwgen_ambiguous">Caracteres ambiguos</string> <string name="pwgen_pronounceable">Pronunciable</string> + <string name="pwgen_no_chars_error">No se han incluído caracteres</string> + <string name="pwgen_length_too_short_error">Longitud demasiado corta para el criterio seleccionado</string> <!-- ssh keygen fragment --> <string name="ssh_keygen_length">Longitud</string> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0b1afda1..ba0fed4c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -180,8 +180,11 @@ <string name="pwgen_numerals">Numerals</string> <string name="pwgen_symbols">Symbols</string> <string name="pwgen_uppercase">Uppercase</string> + <string name="pwgen_lowercase">Lowercase</string> <string name="pwgen_ambiguous">Ambiguous</string> <string name="pwgen_pronounceable">Pronounceable</string> + <string name="pwgen_no_chars_error">No characters included</string> + <string name="pwgen_length_too_short_error">Length too short for selected criteria</string> <!-- ssh keygen fragment --> <string name="ssh_keygen_length">Length</string> |