Add color for special password chars #454

This commit is contained in:
J-Jamet
2022-03-29 15:32:29 +02:00
parent 24587dc34e
commit d466e3077d
7 changed files with 104 additions and 28 deletions

View File

@@ -36,7 +36,7 @@ import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper
import com.kunzisoft.keepass.activities.helpers.setOpenDocumentClickListener
import com.kunzisoft.keepass.model.MainCredential
import com.kunzisoft.keepass.utils.PasswordEntropy
import com.kunzisoft.keepass.password.PasswordEntropy
import com.kunzisoft.keepass.utils.UriUtil
import com.kunzisoft.keepass.view.KeyFileSelectionView
import com.kunzisoft.keepass.view.PasswordView

View File

@@ -60,6 +60,11 @@ object TemplateField {
const val LABEL_SECURE_NOTE = "Secure Note"
const val LABEL_MEMBERSHIP = "Membership"
fun isStandardPasswordName(context: Context, name: String): Boolean {
return name.equals(LABEL_PASSWORD, true)
|| name == getLocalizedName(context, LABEL_PASSWORD)
}
fun isStandardFieldName(name: String): Boolean {
return arrayOf(
LABEL_TITLE,

View File

@@ -17,7 +17,7 @@
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.utils
package com.kunzisoft.keepass.password
import android.content.res.Resources
import android.graphics.Color

View File

@@ -20,6 +20,13 @@
package com.kunzisoft.keepass.password
import android.content.res.Resources
import android.graphics.Color
import android.graphics.Typeface
import android.text.Spannable
import android.text.SpannableString
import android.text.SpannableStringBuilder
import android.text.style.ForegroundColorSpan
import android.text.style.StyleSpan
import com.kunzisoft.keepass.R
import java.security.SecureRandom
import java.util.*
@@ -215,28 +222,6 @@ class PasswordGenerator(private val resources: Resources) {
}
}
// From KeePassXC code https://github.com/keepassxreboot/keepassxc/pull/538
private fun extendedChars(): String {
val charSet = StringBuilder()
// [U+0080, U+009F] are C1 control characters,
// U+00A0 is non-breaking space
run {
var ch = '\u00A1'
while (ch <= '\u00AC') {
charSet.append(ch)
++ch
}
}
// U+00AD is soft hyphen (format character)
var ch = '\u00AE'
while (ch < '\u00FF') {
charSet.append(ch)
++ch
}
charSet.append('\u00FF')
return charSet.toString()
}
companion object {
private const val UPPERCASE_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
private const val LOWERCASE_CHARS = "abcdefghijklmnopqrstuvwxyz"
@@ -247,5 +232,80 @@ class PasswordGenerator(private val resources: Resources) {
private const val SPECIAL_CHARS = "!\"#$%&'*+,./:;=?@\\^`"
private const val BRACKET_CHARS = "[]{}()<>"
private const val AMBIGUOUS_CHARS = "iI|lLoO01"
// From KeePassXC code https://github.com/keepassxreboot/keepassxc/pull/538
private fun extendedChars(): String {
val charSet = StringBuilder()
// [U+0080, U+009F] are C1 control characters,
// U+00A0 is non-breaking space
run {
var ch = '\u00A1'
while (ch <= '\u00AC') {
charSet.append(ch)
++ch
}
}
// U+00AD is soft hyphen (format character)
var ch = '\u00AE'
while (ch < '\u00FF') {
charSet.append(ch)
++ch
}
charSet.append('\u00FF')
return charSet.toString()
}
fun getColorizedPassword(password: String): Spannable {
val coloredString = SpannableStringBuilder()
if (password.isNotEmpty()) {
password.forEach {
when {
UPPERCASE_CHARS.contains(it)||
LOWERCASE_CHARS.contains(it) -> {
coloredString.append(it)
}
DIGIT_CHARS.contains(it) -> {
// RED
coloredString.append(colorizeChar(it, Color.rgb(224, 56, 56)))
}
SPECIAL_CHARS.contains(it) -> {
// Blue
coloredString.append(colorizeChar(it, Color.rgb(66, 132, 237)))
}
MINUS_CHAR.contains(it)||
UNDERLINE_CHAR.contains(it)||
BRACKET_CHARS.contains(it) -> {
// Purple
coloredString.append(colorizeChar(it, Color.rgb(141, 34, 191)))
}
extendedChars().contains(it) -> {
// Green
coloredString.append(colorizeChar(it, Color.rgb(44, 181, 50)))
}
else -> {
coloredString.append(it)
}
}
}
coloredString.setSpan(
StyleSpan(Typeface.BOLD),
0,
password.length,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
}
return coloredString
}
private fun colorizeChar(char: Char, color: Int): Spannable {
val spannableColorChar = SpannableString(char.toString())
spannableColorChar.setSpan(
ForegroundColorSpan(color),
0,
1,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
return spannableColorChar
}
}
}

View File

@@ -29,7 +29,8 @@ import android.widget.TextView
import com.google.android.material.progressindicator.LinearProgressIndicator
import com.google.android.material.textfield.TextInputLayout
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.utils.PasswordEntropy
import com.kunzisoft.keepass.password.PasswordGenerator
import com.kunzisoft.keepass.password.PasswordEntropy
class PasswordView @JvmOverloads constructor(context: Context,
attrs: AttributeSet? = null,
@@ -118,7 +119,7 @@ class PasswordView @JvmOverloads constructor(context: Context,
return passwordText.text.toString()
}
set(value) {
passwordText.text = value
passwordText.text = PasswordGenerator.getColorizedPassword(value)
getEntropyStrength(value)
}
}

View File

@@ -19,6 +19,8 @@ import androidx.core.view.isVisible
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.element.template.TemplateField
import com.kunzisoft.keepass.password.PasswordGenerator
class TextEditFieldView @JvmOverloads constructor(context: Context,
attrs: AttributeSet? = null,
@@ -123,7 +125,10 @@ class TextEditFieldView @JvmOverloads constructor(context: Context,
return valueView.text?.toString() ?: ""
}
set(value) {
valueView.setText(value)
if (TemplateField.isStandardPasswordName(context, label))
valueView.setText(PasswordGenerator.getColorizedPassword(value))
else
valueView.setText(value)
}
override var default: String = ""

View File

@@ -36,7 +36,9 @@ import androidx.core.text.util.LinkifyCompat
import androidx.core.view.ViewCompat
import androidx.core.view.isVisible
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.element.template.TemplateField
import com.kunzisoft.keepass.model.EntryInfo.Companion.APPLICATION_ID_FIELD_NAME
import com.kunzisoft.keepass.password.PasswordGenerator
import com.kunzisoft.keepass.utils.UriUtil
@@ -191,7 +193,10 @@ class TextFieldView @JvmOverloads constructor(context: Context,
return valueView.text.toString()
}
set(value) {
valueView.text = value
if (TemplateField.isStandardPasswordName(context, label))
valueView.text = PasswordGenerator.getColorizedPassword(value)
else
valueView.text = value
changeProtectedValueParameters()
}