aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/main/java/dev/msfjarvis/aps/data/password
diff options
context:
space:
mode:
authorHarsh Shandilya <me@msfjarvis.dev>2021-03-09 14:53:11 +0530
committerHarsh Shandilya <me@msfjarvis.dev>2021-03-18 11:40:30 +0530
commit774fda83ac276a635e3402034b1eedbd10be916f (patch)
tree57783a953fcd193d32f1e3dc8df26e07f03df328 /app/src/main/java/dev/msfjarvis/aps/data/password
parentbe31ae37f443982b377d027cd613f04d0926568d (diff)
downloadHardenedPass-774fda83ac276a635e3402034b1eedbd10be916f.tar.gz
HardenedPass-774fda83ac276a635e3402034b1eedbd10be916f.zip
all: reformat with ktfmt
Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
Diffstat (limited to 'app/src/main/java/dev/msfjarvis/aps/data/password')
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/data/password/FieldItem.kt37
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/data/password/PasswordEntry.kt318
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/data/password/PasswordItem.kt99
3 files changed, 217 insertions, 237 deletions
diff --git a/app/src/main/java/dev/msfjarvis/aps/data/password/FieldItem.kt b/app/src/main/java/dev/msfjarvis/aps/data/password/FieldItem.kt
index 2a3b52cd..5b4931e7 100644
--- a/app/src/main/java/dev/msfjarvis/aps/data/password/FieldItem.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/data/password/FieldItem.kt
@@ -6,27 +6,30 @@
package dev.msfjarvis.aps.data.password
class FieldItem(val key: String, val value: String, val action: ActionType) {
- enum class ActionType {
- COPY, HIDE
- }
+ enum class ActionType {
+ COPY,
+ HIDE
+ }
- enum class ItemType(val type: String) {
- USERNAME("Username"), PASSWORD("Password"), OTP("OTP")
- }
+ enum class ItemType(val type: String) {
+ USERNAME("Username"),
+ PASSWORD("Password"),
+ OTP("OTP")
+ }
- companion object {
+ companion object {
- // Extra helper methods
- fun createOtpField(otp: String): FieldItem {
- return FieldItem(ItemType.OTP.type, otp, ActionType.COPY)
- }
+ // Extra helper methods
+ fun createOtpField(otp: String): FieldItem {
+ return FieldItem(ItemType.OTP.type, otp, ActionType.COPY)
+ }
- fun createPasswordField(password: String): FieldItem {
- return FieldItem(ItemType.PASSWORD.type, password, ActionType.HIDE)
- }
+ fun createPasswordField(password: String): FieldItem {
+ return FieldItem(ItemType.PASSWORD.type, password, ActionType.HIDE)
+ }
- fun createUsernameField(username: String): FieldItem {
- return FieldItem(ItemType.USERNAME.type, username, ActionType.COPY)
- }
+ fun createUsernameField(username: String): FieldItem {
+ return FieldItem(ItemType.USERNAME.type, username, ActionType.COPY)
}
+ }
}
diff --git a/app/src/main/java/dev/msfjarvis/aps/data/password/PasswordEntry.kt b/app/src/main/java/dev/msfjarvis/aps/data/password/PasswordEntry.kt
index d6f3c15f..8a2ca3c6 100644
--- a/app/src/main/java/dev/msfjarvis/aps/data/password/PasswordEntry.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/data/password/PasswordEntry.kt
@@ -18,178 +18,178 @@ import java.util.Date
*/
class PasswordEntry(content: String, private val totpFinder: TotpFinder = UriTotpFinder()) {
- val password: String
- val username: String?
-
- @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
- val digits: String
-
- @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
- val totpSecret: String?
- val totpPeriod: Long
-
- @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
- val totpAlgorithm: String
- val extraContent: String
- val extraContentWithoutAuthData: String
- val extraContentMap: Map<String, String>
-
- constructor(os: ByteArrayOutputStream) : this(os.toString(Charsets.UTF_8.name()), UriTotpFinder())
-
- init {
- val (foundPassword, passContent) = findAndStripPassword(content.split("\n".toRegex()))
- password = foundPassword
- extraContent = passContent.joinToString("\n")
- extraContentWithoutAuthData = generateExtraContentWithoutAuthData()
- extraContentMap = generateExtraContentPairs()
- username = findUsername()
- digits = findOtpDigits(content)
- totpSecret = findTotpSecret(content)
- totpPeriod = findTotpPeriod(content)
- totpAlgorithm = findTotpAlgorithm(content)
- }
-
- fun hasExtraContent(): Boolean {
- return extraContent.isNotEmpty()
- }
-
- fun hasExtraContentWithoutAuthData(): Boolean {
- return extraContentWithoutAuthData.isNotEmpty()
- }
-
- fun hasTotp(): Boolean {
- return totpSecret != null
+ val password: String
+ val username: String?
+
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) val digits: String
+
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) val totpSecret: String?
+ val totpPeriod: Long
+
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) val totpAlgorithm: String
+ val extraContent: String
+ val extraContentWithoutAuthData: String
+ val extraContentMap: Map<String, String>
+
+ constructor(os: ByteArrayOutputStream) : this(os.toString(Charsets.UTF_8.name()), UriTotpFinder())
+
+ init {
+ val (foundPassword, passContent) = findAndStripPassword(content.split("\n".toRegex()))
+ password = foundPassword
+ extraContent = passContent.joinToString("\n")
+ extraContentWithoutAuthData = generateExtraContentWithoutAuthData()
+ extraContentMap = generateExtraContentPairs()
+ username = findUsername()
+ digits = findOtpDigits(content)
+ totpSecret = findTotpSecret(content)
+ totpPeriod = findTotpPeriod(content)
+ totpAlgorithm = findTotpAlgorithm(content)
+ }
+
+ fun hasExtraContent(): Boolean {
+ return extraContent.isNotEmpty()
+ }
+
+ fun hasExtraContentWithoutAuthData(): Boolean {
+ return extraContentWithoutAuthData.isNotEmpty()
+ }
+
+ fun hasTotp(): Boolean {
+ return totpSecret != null
+ }
+
+ fun hasUsername(): Boolean {
+ return username != null
+ }
+
+ fun calculateTotpCode(): String? {
+ if (totpSecret == null) return null
+ return Otp.calculateCode(totpSecret, Date().time / (1000 * totpPeriod), totpAlgorithm, digits).get()
+ }
+
+ private fun generateExtraContentWithoutAuthData(): String {
+ var foundUsername = false
+ return extraContent
+ .lineSequence()
+ .filter { line ->
+ return@filter when {
+ USERNAME_FIELDS.any { prefix -> line.startsWith(prefix, ignoreCase = true) } && !foundUsername -> {
+ foundUsername = true
+ false
+ }
+ line.startsWith("otpauth://", ignoreCase = true) || line.startsWith("totp:", ignoreCase = true) -> {
+ false
+ }
+ else -> {
+ true
+ }
+ }
+ }
+ .joinToString(separator = "\n")
+ }
+
+ private fun generateExtraContentPairs(): Map<String, String> {
+ fun MutableMap<String, String>.putOrAppend(key: String, value: String) {
+ if (value.isEmpty()) return
+ val existing = this[key]
+ this[key] =
+ if (existing == null) {
+ value
+ } else {
+ "$existing\n$value"
+ }
}
- fun hasUsername(): Boolean {
- return username != null
+ val items = mutableMapOf<String, String>()
+ // Take extraContentWithoutAuthData and onEach line perform the following tasks
+ extraContentWithoutAuthData.lines().forEach { line ->
+ // Split the line on ':' and save all the parts into an array
+ // "ABC : DEF:GHI" --> ["ABC", "DEF", "GHI"]
+ val splitArray = line.split(":")
+ // Take the first element of the array. This will be the key for the key-value pair.
+ // ["ABC ", " DEF", "GHI"] -> key = "ABC"
+ val key = splitArray.first().trimEnd()
+ // Remove the first element from the array and join the rest of the string again with
+ // ':' as separator.
+ // ["ABC ", " DEF", "GHI"] -> value = "DEF:GHI"
+ val value = splitArray.drop(1).joinToString(":").trimStart()
+
+ if (key.isNotEmpty() && value.isNotEmpty()) {
+ // If both key and value are not empty, we can form a pair with this so add it to
+ // the map.
+ // key = "ABC", value = "DEF:GHI"
+ items[key] = value
+ } else {
+ // If either key or value is empty, we were not able to form proper key-value pair.
+ // So append the original line into an "EXTRA CONTENT" map entry
+ items.putOrAppend(EXTRA_CONTENT, line)
+ }
}
- fun calculateTotpCode(): String? {
- if (totpSecret == null)
- return null
- return Otp.calculateCode(totpSecret, Date().time / (1000 * totpPeriod), totpAlgorithm, digits).get()
- }
+ return items
+ }
- private fun generateExtraContentWithoutAuthData(): String {
- var foundUsername = false
- return extraContent
- .lineSequence()
- .filter { line ->
- return@filter when {
- USERNAME_FIELDS.any { prefix -> line.startsWith(prefix, ignoreCase = true) } && !foundUsername -> {
- foundUsername = true
- false
- }
- line.startsWith("otpauth://", ignoreCase = true) ||
- line.startsWith("totp:", ignoreCase = true) -> {
- false
- }
- else -> {
- true
- }
- }
- }.joinToString(separator = "\n")
+ private fun findUsername(): String? {
+ extraContent.splitToSequence("\n").forEach { line ->
+ for (prefix in USERNAME_FIELDS) {
+ if (line.startsWith(prefix, ignoreCase = true)) return line.substring(prefix.length).trimStart()
+ }
}
-
- private fun generateExtraContentPairs(): Map<String, String> {
- fun MutableMap<String, String>.putOrAppend(key: String, value: String) {
- if (value.isEmpty()) return
- val existing = this[key]
- this[key] = if (existing == null) {
- value
- } else {
- "$existing\n$value"
- }
+ return null
+ }
+
+ private fun findAndStripPassword(passContent: List<String>): Pair<String, List<String>> {
+ if (UriTotpFinder.TOTP_FIELDS.any { passContent[0].startsWith(it) }) return Pair("", passContent)
+ for (line in passContent) {
+ for (prefix in PASSWORD_FIELDS) {
+ if (line.startsWith(prefix, ignoreCase = true)) {
+ return Pair(line.substring(prefix.length).trimStart(), passContent.minus(line))
}
-
- val items = mutableMapOf<String, String>()
- // Take extraContentWithoutAuthData and onEach line perform the following tasks
- extraContentWithoutAuthData.lines().forEach { line ->
- // Split the line on ':' and save all the parts into an array
- // "ABC : DEF:GHI" --> ["ABC", "DEF", "GHI"]
- val splitArray = line.split(":")
- // Take the first element of the array. This will be the key for the key-value pair.
- // ["ABC ", " DEF", "GHI"] -> key = "ABC"
- val key = splitArray.first().trimEnd()
- // Remove the first element from the array and join the rest of the string again with ':' as separator.
- // ["ABC ", " DEF", "GHI"] -> value = "DEF:GHI"
- val value = splitArray.drop(1).joinToString(":").trimStart()
-
- if (key.isNotEmpty() && value.isNotEmpty()) {
- // If both key and value are not empty, we can form a pair with this so add it to the map.
- // key = "ABC", value = "DEF:GHI"
- items[key] = value
- } else {
- // If either key or value is empty, we were not able to form proper key-value pair.
- // So append the original line into an "EXTRA CONTENT" map entry
- items.putOrAppend(EXTRA_CONTENT, line)
- }
- }
-
- return items
+ }
}
+ return Pair(passContent[0], passContent.minus(passContent[0]))
+ }
- private fun findUsername(): String? {
- extraContent.splitToSequence("\n").forEach { line ->
- for (prefix in USERNAME_FIELDS) {
- if (line.startsWith(prefix, ignoreCase = true))
- return line.substring(prefix.length).trimStart()
- }
- }
- return null
- }
+ private fun findTotpSecret(decryptedContent: String): String? {
+ return totpFinder.findSecret(decryptedContent)
+ }
- private fun findAndStripPassword(passContent: List<String>): Pair<String, List<String>> {
- if (UriTotpFinder.TOTP_FIELDS.any { passContent[0].startsWith(it) }) return Pair("", passContent)
- for (line in passContent) {
- for (prefix in PASSWORD_FIELDS) {
- if (line.startsWith(prefix, ignoreCase = true)) {
- return Pair(line.substring(prefix.length).trimStart(), passContent.minus(line))
- }
- }
- }
- return Pair(passContent[0], passContent.minus(passContent[0]))
- }
+ private fun findOtpDigits(decryptedContent: String): String {
+ return totpFinder.findDigits(decryptedContent)
+ }
- private fun findTotpSecret(decryptedContent: String): String? {
- return totpFinder.findSecret(decryptedContent)
- }
+ private fun findTotpPeriod(decryptedContent: String): Long {
+ return totpFinder.findPeriod(decryptedContent)
+ }
- private fun findOtpDigits(decryptedContent: String): String {
- return totpFinder.findDigits(decryptedContent)
- }
+ private fun findTotpAlgorithm(decryptedContent: String): String {
+ return totpFinder.findAlgorithm(decryptedContent)
+ }
- private fun findTotpPeriod(decryptedContent: String): Long {
- return totpFinder.findPeriod(decryptedContent)
- }
+ companion object {
- private fun findTotpAlgorithm(decryptedContent: String): String {
- return totpFinder.findAlgorithm(decryptedContent)
- }
+ private const val EXTRA_CONTENT = "Extra Content"
- companion object {
-
- private const val EXTRA_CONTENT = "Extra Content"
-
- @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
- val USERNAME_FIELDS = arrayOf(
- "login:",
- "username:",
- "user:",
- "account:",
- "email:",
- "name:",
- "handle:",
- "id:",
- "identity:",
- )
-
- @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
- val PASSWORD_FIELDS = arrayOf(
- "password:",
- "secret:",
- "pass:",
- )
- }
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+ val USERNAME_FIELDS =
+ arrayOf(
+ "login:",
+ "username:",
+ "user:",
+ "account:",
+ "email:",
+ "name:",
+ "handle:",
+ "id:",
+ "identity:",
+ )
+
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+ val PASSWORD_FIELDS =
+ arrayOf(
+ "password:",
+ "secret:",
+ "pass:",
+ )
+ }
}
diff --git a/app/src/main/java/dev/msfjarvis/aps/data/password/PasswordItem.kt b/app/src/main/java/dev/msfjarvis/aps/data/password/PasswordItem.kt
index 60889150..89923dff 100644
--- a/app/src/main/java/dev/msfjarvis/aps/data/password/PasswordItem.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/data/password/PasswordItem.kt
@@ -8,79 +8,56 @@ import dev.msfjarvis.aps.ui.crypto.BasePgpActivity
import java.io.File
data class PasswordItem(
- val name: String,
- val parent: PasswordItem? = null,
- val type: Char,
- val file: File,
- val rootDir: File
+ val name: String,
+ val parent: PasswordItem? = null,
+ val type: Char,
+ val file: File,
+ val rootDir: File
) : Comparable<PasswordItem> {
- val fullPathToParent = file.absolutePath
- .replace(rootDir.absolutePath, "")
- .replace(file.name, "")
+ val fullPathToParent = file.absolutePath.replace(rootDir.absolutePath, "").replace(file.name, "")
- val longName = BasePgpActivity.getLongName(
- fullPathToParent,
- rootDir.absolutePath,
- toString())
+ val longName = BasePgpActivity.getLongName(fullPathToParent, rootDir.absolutePath, toString())
- override fun equals(other: Any?): Boolean {
- return (other is PasswordItem) && (other.file == file)
- }
+ override fun equals(other: Any?): Boolean {
+ return (other is PasswordItem) && (other.file == file)
+ }
- override fun compareTo(other: PasswordItem): Int {
- return (type + name).compareTo(other.type + other.name, ignoreCase = true)
- }
+ override fun compareTo(other: PasswordItem): Int {
+ return (type + name).compareTo(other.type + other.name, ignoreCase = true)
+ }
- override fun toString(): String {
- return name.replace("\\.gpg$".toRegex(), "")
- }
+ override fun toString(): String {
+ return name.replace("\\.gpg$".toRegex(), "")
+ }
- override fun hashCode(): Int {
- return 0
- }
+ override fun hashCode(): Int {
+ return 0
+ }
- companion object {
+ companion object {
- const val TYPE_CATEGORY = 'c'
- const val TYPE_PASSWORD = 'p'
+ const val TYPE_CATEGORY = 'c'
+ const val TYPE_PASSWORD = 'p'
- @JvmStatic
- fun newCategory(
- name: String,
- file: File,
- parent: PasswordItem,
- rootDir: File
- ): PasswordItem {
- return PasswordItem(name, parent, TYPE_CATEGORY, file, rootDir)
- }
+ @JvmStatic
+ fun newCategory(name: String, file: File, parent: PasswordItem, rootDir: File): PasswordItem {
+ return PasswordItem(name, parent, TYPE_CATEGORY, file, rootDir)
+ }
- @JvmStatic
- fun newCategory(
- name: String,
- file: File,
- rootDir: File
- ): PasswordItem {
- return PasswordItem(name, null, TYPE_CATEGORY, file, rootDir)
- }
+ @JvmStatic
+ fun newCategory(name: String, file: File, rootDir: File): PasswordItem {
+ return PasswordItem(name, null, TYPE_CATEGORY, file, rootDir)
+ }
- @JvmStatic
- fun newPassword(
- name: String,
- file: File,
- parent: PasswordItem,
- rootDir: File
- ): PasswordItem {
- return PasswordItem(name, parent, TYPE_PASSWORD, file, rootDir)
- }
+ @JvmStatic
+ fun newPassword(name: String, file: File, parent: PasswordItem, rootDir: File): PasswordItem {
+ return PasswordItem(name, parent, TYPE_PASSWORD, file, rootDir)
+ }
- @JvmStatic
- fun newPassword(
- name: String,
- file: File,
- rootDir: File
- ): PasswordItem {
- return PasswordItem(name, null, TYPE_PASSWORD, file, rootDir)
- }
+ @JvmStatic
+ fun newPassword(name: String, file: File, rootDir: File): PasswordItem {
+ return PasswordItem(name, null, TYPE_PASSWORD, file, rootDir)
}
+ }
}