Allow adding digits and symbols in XkPasswd generator using mask-like values (#1023)

* - XkPasswordGeneratorDialogFragment: add symbol/number mask to allow appending numbers+symbols via a mask such as `ddds` which would generate random.password123!; position of `d` and `s` is not currently considered; only the count is relevant

* - update CHANGELOG.md

* - update CHANGELOG.md

* - rename constants

* Update CHANGELOG.md

Co-authored-by: Harsh Shandilya <me@msfjarvis.dev>

* - add missing marginTop

* - add missing marginTop

Co-authored-by: null <null>
Co-authored-by: Harsh Shandilya <me@msfjarvis.dev>
Co-authored-by: glowinthedark <glowinthedark>
Co-authored-by: Harsh Shandilya <msfjarvis@gmail.com>
This commit is contained in:
glowinthedark 2020-08-17 12:40:03 +02:00 committed by GitHub
parent e2a372bc63
commit 82ae0a8629
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 39 additions and 7 deletions

View file

@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file.
### Added ### Added
- Allow changing the branch used for Git operations - Allow changing the branch used for Git operations
- Allow setting a subdirectory key when creating folders - Allow setting a subdirectory key when creating folders
- Allow adding digits/symbols in XkPasswd generated passwords using a mask-like value (`dds` gives you two digits and a symbol, and so on)
### Changed ### Changed

View file

@ -5,5 +5,5 @@
package com.zeapo.pwdstore.pwgenxkpwd package com.zeapo.pwdstore.pwgenxkpwd
enum class CapsType { enum class CapsType {
lowercase, UPPERCASE, TitleCase, Sentencecase, As_iS lowercase, UPPERCASE, TitleCase, Sentence, As_iS
} }

View file

@ -22,7 +22,7 @@ class PasswordBuilder(ctx: Context) {
private var maxWordLength = 9 private var maxWordLength = 9
private var minWordLength = 5 private var minWordLength = 5
private var separator = "." private var separator = "."
private var capsType = CapsType.Sentencecase private var capsType = CapsType.Sentence
private var prependDigits = 0 private var prependDigits = 0
private var numDigits = 0 private var numDigits = 0
private var isPrependWithSeparator = false private var isPrependWithSeparator = false
@ -109,7 +109,7 @@ class PasswordBuilder(ctx: Context) {
val candidate = wordBank.secureRandomElement() val candidate = wordBank.secureRandomElement()
val s = when (capsType) { val s = when (capsType) {
CapsType.UPPERCASE -> candidate.toUpperCase(Locale.getDefault()) CapsType.UPPERCASE -> candidate.toUpperCase(Locale.getDefault())
CapsType.Sentencecase -> if (i == 0) candidate.capitalize(Locale.getDefault()) else candidate CapsType.Sentence -> if (i == 0) candidate.capitalize(Locale.getDefault()) else candidate
CapsType.TitleCase -> candidate.capitalize(Locale.getDefault()) CapsType.TitleCase -> candidate.capitalize(Locale.getDefault())
CapsType.lowercase -> candidate.toLowerCase(Locale.getDefault()) CapsType.lowercase -> candidate.toLowerCase(Locale.getDefault())
CapsType.As_iS -> candidate CapsType.As_iS -> candidate

View file

@ -58,6 +58,7 @@ class XkPasswordGeneratorDialogFragment : DialogFragment() {
binding.xkNumWords.setText(prefs.getString(PREF_KEY_NUM_WORDS, DEFAULT_NUMBER_OF_WORDS)) binding.xkNumWords.setText(prefs.getString(PREF_KEY_NUM_WORDS, DEFAULT_NUMBER_OF_WORDS))
binding.xkSeparator.setText(prefs.getString(PREF_KEY_SEPARATOR, DEFAULT_WORD_SEPARATOR)) binding.xkSeparator.setText(prefs.getString(PREF_KEY_SEPARATOR, DEFAULT_WORD_SEPARATOR))
binding.xkNumberSymbolMask.setText(prefs.getString(PREF_KEY_EXTRA_SYMBOLS_MASK, DEFAULT_EXTRA_SYMBOLS_MASK))
binding.xkPasswordText.typeface = monoTypeface binding.xkPasswordText.typeface = monoTypeface
@ -92,6 +93,8 @@ class XkPasswordGeneratorDialogFragment : DialogFragment() {
.setMinimumWordLength(DEFAULT_MIN_WORD_LENGTH) .setMinimumWordLength(DEFAULT_MIN_WORD_LENGTH)
.setMaximumWordLength(DEFAULT_MAX_WORD_LENGTH) .setMaximumWordLength(DEFAULT_MAX_WORD_LENGTH)
.setSeparator(binding.xkSeparator.text.toString()) .setSeparator(binding.xkSeparator.text.toString())
.appendNumbers(binding.xkNumberSymbolMask.text!!.count { c -> c == EXTRA_CHAR_PLACEHOLDER_DIGIT })
.appendSymbols(binding.xkNumberSymbolMask.text!!.count { c -> c == EXTRA_CHAR_PLACEHOLDER_SYMBOL })
.setCapitalization(CapsType.valueOf(binding.xkCapType.selectedItem.toString())).create() .setCapitalization(CapsType.valueOf(binding.xkCapType.selectedItem.toString())).create()
} catch (e: PasswordGenerator.PasswordGeneratorException) { } catch (e: PasswordGenerator.PasswordGeneratorException) {
Toast.makeText(requireActivity(), e.message, Toast.LENGTH_SHORT).show() Toast.makeText(requireActivity(), e.message, Toast.LENGTH_SHORT).show()
@ -105,6 +108,7 @@ class XkPasswordGeneratorDialogFragment : DialogFragment() {
putString(PREF_KEY_CAPITALS_STYLE, binding.xkCapType.selectedItem.toString()) putString(PREF_KEY_CAPITALS_STYLE, binding.xkCapType.selectedItem.toString())
putString(PREF_KEY_NUM_WORDS, binding.xkNumWords.text.toString()) putString(PREF_KEY_NUM_WORDS, binding.xkNumWords.text.toString())
putString(PREF_KEY_SEPARATOR, binding.xkSeparator.text.toString()) putString(PREF_KEY_SEPARATOR, binding.xkSeparator.text.toString())
putString(PREF_KEY_EXTRA_SYMBOLS_MASK, binding.xkNumberSymbolMask.text.toString())
} }
} }
@ -113,12 +117,16 @@ class XkPasswordGeneratorDialogFragment : DialogFragment() {
const val PREF_KEY_CAPITALS_STYLE = "pref_key_capitals_style" const val PREF_KEY_CAPITALS_STYLE = "pref_key_capitals_style"
const val PREF_KEY_NUM_WORDS = "pref_key_num_words" const val PREF_KEY_NUM_WORDS = "pref_key_num_words"
const val PREF_KEY_SEPARATOR = "pref_key_separator" const val PREF_KEY_SEPARATOR = "pref_key_separator"
val DEFAULT_CAPS_STYLE = CapsType.Sentencecase.name const val PREF_KEY_EXTRA_SYMBOLS_MASK = "pref_key_xkpwgen_extra_symbols_mask"
val DEFAULT_CAPS_INDEX = CapsType.Sentencecase.ordinal val DEFAULT_CAPS_STYLE = CapsType.Sentence.name
val DEFAULT_CAPS_INDEX = CapsType.Sentence.ordinal
const val DEFAULT_NUMBER_OF_WORDS = "3" const val DEFAULT_NUMBER_OF_WORDS = "3"
const val DEFAULT_WORD_SEPARATOR = "." const val DEFAULT_WORD_SEPARATOR = "."
const val DEFAULT_EXTRA_SYMBOLS_MASK = "ds"
const val DEFAULT_MIN_WORD_LENGTH = 3 const val DEFAULT_MIN_WORD_LENGTH = 3
const val DEFAULT_MAX_WORD_LENGTH = 9 const val DEFAULT_MAX_WORD_LENGTH = 9
const val FALLBACK_ERROR_PASS = "42" const val FALLBACK_ERROR_PASS = "42"
const val EXTRA_CHAR_PLACEHOLDER_DIGIT = 'd'
const val EXTRA_CHAR_PLACEHOLDER_SYMBOL = 's'
} }
} }

View file

@ -75,7 +75,28 @@
android:entries="@array/capitalization_type_values" android:entries="@array/capitalization_type_values"
android:entryValues="@array/capitalization_type_values" android:entryValues="@array/capitalization_type_values"
android:spinnerMode="dropdown" android:spinnerMode="dropdown"
app:layout_constraintEnd_toEndOf="@id/total_words"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/separator" /> app:layout_constraintTop_toBottomOf="@id/total_words" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/xk_numbers_symbols_label"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="@string/xkpwgen_extrachars_label"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/separator"
app:layout_constraintTop_toBottomOf="@id/separator"
app:layout_constraintTop_toTopOf="@id/xkCapType">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/xk_number_symbol_mask"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:autofillHints=""
android:inputType="text"
android:text="@string/xk_numbers_symbols_append_default" />
</com.google.android.material.textfield.TextInputLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView> </ScrollView>

View file

@ -18,7 +18,7 @@
<item>lowercase</item> <item>lowercase</item>
<item>UPPERCASE</item> <item>UPPERCASE</item>
<item>TitleCase</item> <item>TitleCase</item>
<item>Sentencecase</item> <item>Sentence</item>
</string-array> </string-array>
<string-array name="pwgen_provider_labels"> <string-array name="pwgen_provider_labels">
<item>Classic</item> <item>Classic</item>

View file

@ -390,4 +390,6 @@
<!-- GPG key selection in folder creation --> <!-- GPG key selection in folder creation -->
<string name="folder_creation_err_file_exists">A file by that name already exists</string> <string name="folder_creation_err_file_exists">A file by that name already exists</string>
<string name="folder_creation_err_folder_exists">A folder by that name already exists</string> <string name="folder_creation_err_folder_exists">A folder by that name already exists</string>
<string name="xkpwgen_extrachars_label" >Digits/Symbols (d/s)</string>
<string name="xk_numbers_symbols_append_default">ds</string>
</resources> </resources>