summaryrefslogtreecommitdiffstats
path: root/app/src/main/java/dev/msfjarvis/aps/data
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
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')
-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
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/data/repo/PasswordRepository.kt368
4 files changed, 400 insertions, 422 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)
}
+ }
}
diff --git a/app/src/main/java/dev/msfjarvis/aps/data/repo/PasswordRepository.kt b/app/src/main/java/dev/msfjarvis/aps/data/repo/PasswordRepository.kt
index 1f12918d..5aa63e76 100644
--- a/app/src/main/java/dev/msfjarvis/aps/data/repo/PasswordRepository.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/data/repo/PasswordRepository.kt
@@ -31,213 +31,211 @@ import org.eclipse.jgit.util.FS_POSIX_Java6
object PasswordRepository {
- @RequiresApi(Build.VERSION_CODES.O)
- private class FS_POSIX_Java6_with_optional_symlinks : FS_POSIX_Java6() {
+ @RequiresApi(Build.VERSION_CODES.O)
+ private class FS_POSIX_Java6_with_optional_symlinks : FS_POSIX_Java6() {
- override fun supportsSymlinks() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
+ override fun supportsSymlinks() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
- override fun isSymLink(file: File) = Files.isSymbolicLink(file.toPath())
+ override fun isSymLink(file: File) = Files.isSymbolicLink(file.toPath())
- override fun readSymLink(file: File) = Files.readSymbolicLink(file.toPath()).toString()
+ override fun readSymLink(file: File) = Files.readSymbolicLink(file.toPath()).toString()
- override fun createSymLink(source: File, target: String) {
- val sourcePath = source.toPath()
- if (Files.exists(sourcePath, LinkOption.NOFOLLOW_LINKS))
- Files.delete(sourcePath)
- Files.createSymbolicLink(sourcePath, File(target).toPath())
- }
+ override fun createSymLink(source: File, target: String) {
+ val sourcePath = source.toPath()
+ if (Files.exists(sourcePath, LinkOption.NOFOLLOW_LINKS)) Files.delete(sourcePath)
+ Files.createSymbolicLink(sourcePath, File(target).toPath())
}
+ }
- @RequiresApi(Build.VERSION_CODES.O)
- private class Java7FSFactory : FS.FSFactory() {
+ @RequiresApi(Build.VERSION_CODES.O)
+ private class Java7FSFactory : FS.FSFactory() {
- override fun detect(cygwinUsed: Boolean?): FS {
- return FS_POSIX_Java6_with_optional_symlinks()
- }
+ override fun detect(cygwinUsed: Boolean?): FS {
+ return FS_POSIX_Java6_with_optional_symlinks()
}
-
- private var repository: Repository? = null
- private val settings by lazy(LazyThreadSafetyMode.NONE) { Application.instance.sharedPrefs }
- private val filesDir
- get() = Application.instance.filesDir
-
- /**
- * Returns the git repository
- *
- * @param localDir needed only on the creation
- * @return the git repository
- */
- @JvmStatic
- fun getRepository(localDir: File?): Repository? {
- if (repository == null && localDir != null) {
- val builder = FileRepositoryBuilder()
- repository = runCatching {
- builder.run {
- gitDir = localDir
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- fs = Java7FSFactory().detect(null)
- }
- readEnvironment()
- }.build()
- }.getOrElse { e ->
- e.printStackTrace()
- null
+ }
+
+ private var repository: Repository? = null
+ private val settings by lazy(LazyThreadSafetyMode.NONE) { Application.instance.sharedPrefs }
+ private val filesDir
+ get() = Application.instance.filesDir
+
+ /**
+ * Returns the git repository
+ *
+ * @param localDir needed only on the creation
+ * @return the git repository
+ */
+ @JvmStatic
+ fun getRepository(localDir: File?): Repository? {
+ if (repository == null && localDir != null) {
+ val builder = FileRepositoryBuilder()
+ repository =
+ runCatching {
+ builder
+ .run {
+ gitDir = localDir
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ fs = Java7FSFactory().detect(null)
+ }
+ readEnvironment()
}
+ .build()
}
- return repository
- }
-
- @JvmStatic
- val isInitialized: Boolean
- get() = repository != null
-
- @JvmStatic
- fun isGitRepo(): Boolean {
- if (repository != null) {
- return repository!!.objectDatabase.exists()
- }
- return false
+ .getOrElse { e ->
+ e.printStackTrace()
+ null
+ }
}
+ return repository
+ }
- @JvmStatic
- @Throws(Exception::class)
- fun createRepository(localDir: File) {
- localDir.delete()
+ @JvmStatic
+ val isInitialized: Boolean
+ get() = repository != null
- Git.init().setDirectory(localDir).call()
- getRepository(localDir)
+ @JvmStatic
+ fun isGitRepo(): Boolean {
+ if (repository != null) {
+ return repository!!.objectDatabase.exists()
}
+ return false
+ }
+
+ @JvmStatic
+ @Throws(Exception::class)
+ fun createRepository(localDir: File) {
+ localDir.delete()
+
+ Git.init().setDirectory(localDir).call()
+ getRepository(localDir)
+ }
+
+ // TODO add multiple remotes support for pull/push
+ @JvmStatic
+ fun addRemote(name: String, url: String, replace: Boolean = false) {
+ val storedConfig = repository!!.config
+ val remotes = storedConfig.getSubsections("remote")
+
+ if (!remotes.contains(name)) {
+ runCatching {
+ val uri = URIish(url)
+ val refSpec = RefSpec("+refs/head/*:refs/remotes/$name/*")
+
+ val remoteConfig = RemoteConfig(storedConfig, name)
+ remoteConfig.addFetchRefSpec(refSpec)
+ remoteConfig.addPushRefSpec(refSpec)
+ remoteConfig.addURI(uri)
+ remoteConfig.addPushURI(uri)
+
+ remoteConfig.update(storedConfig)
+
+ storedConfig.save()
+ }
+ .onFailure { e -> e.printStackTrace() }
+ } else if (replace) {
+ runCatching {
+ val uri = URIish(url)
+
+ val remoteConfig = RemoteConfig(storedConfig, name)
+ // remove the first and eventually the only uri
+ if (remoteConfig.urIs.size > 0) {
+ remoteConfig.removeURI(remoteConfig.urIs[0])
+ }
+ if (remoteConfig.pushURIs.size > 0) {
+ remoteConfig.removePushURI(remoteConfig.pushURIs[0])
+ }
- // TODO add multiple remotes support for pull/push
- @JvmStatic
- fun addRemote(name: String, url: String, replace: Boolean = false) {
- val storedConfig = repository!!.config
- val remotes = storedConfig.getSubsections("remote")
-
- if (!remotes.contains(name)) {
- runCatching {
- val uri = URIish(url)
- val refSpec = RefSpec("+refs/head/*:refs/remotes/$name/*")
-
- val remoteConfig = RemoteConfig(storedConfig, name)
- remoteConfig.addFetchRefSpec(refSpec)
- remoteConfig.addPushRefSpec(refSpec)
- remoteConfig.addURI(uri)
- remoteConfig.addPushURI(uri)
-
- remoteConfig.update(storedConfig)
+ remoteConfig.addURI(uri)
+ remoteConfig.addPushURI(uri)
- storedConfig.save()
- }.onFailure { e ->
- e.printStackTrace()
- }
- } else if (replace) {
- runCatching {
- val uri = URIish(url)
-
- val remoteConfig = RemoteConfig(storedConfig, name)
- // remove the first and eventually the only uri
- if (remoteConfig.urIs.size > 0) {
- remoteConfig.removeURI(remoteConfig.urIs[0])
- }
- if (remoteConfig.pushURIs.size > 0) {
- remoteConfig.removePushURI(remoteConfig.pushURIs[0])
- }
-
- remoteConfig.addURI(uri)
- remoteConfig.addPushURI(uri)
-
- remoteConfig.update(storedConfig)
-
- storedConfig.save()
- }.onFailure { e ->
- e.printStackTrace()
- }
- }
- }
+ remoteConfig.update(storedConfig)
- @JvmStatic
- fun closeRepository() {
- if (repository != null) repository!!.close()
- repository = null
+ storedConfig.save()
+ }
+ .onFailure { e -> e.printStackTrace() }
}
-
- @JvmStatic
- fun getRepositoryDirectory(): File {
- return if (settings.getBoolean(PreferenceKeys.GIT_EXTERNAL, false)) {
- val externalRepo = settings.getString(PreferenceKeys.GIT_EXTERNAL_REPO)
- if (externalRepo != null)
- File(externalRepo)
- else
- File(filesDir.toString(), "/store")
- } else {
- File(filesDir.toString(), "/store")
- }
+ }
+
+ @JvmStatic
+ fun closeRepository() {
+ if (repository != null) repository!!.close()
+ repository = null
+ }
+
+ @JvmStatic
+ fun getRepositoryDirectory(): File {
+ return if (settings.getBoolean(PreferenceKeys.GIT_EXTERNAL, false)) {
+ val externalRepo = settings.getString(PreferenceKeys.GIT_EXTERNAL_REPO)
+ if (externalRepo != null) File(externalRepo) else File(filesDir.toString(), "/store")
+ } else {
+ File(filesDir.toString(), "/store")
}
-
- @JvmStatic
- fun initialize(): Repository? {
- val dir = getRepositoryDirectory()
- // uninitialize the repo if the dir does not exist or is absolutely empty
- settings.edit {
- if (!dir.exists() || !dir.isDirectory || requireNotNull(dir.listFiles()).isEmpty()) {
- putBoolean(PreferenceKeys.REPOSITORY_INITIALIZED, false)
- } else {
- putBoolean(PreferenceKeys.REPOSITORY_INITIALIZED, true)
- }
- }
-
- // create the repository static variable in PasswordRepository
- return getRepository(File(dir.absolutePath + "/.git"))
+ }
+
+ @JvmStatic
+ fun initialize(): Repository? {
+ val dir = getRepositoryDirectory()
+ // uninitialize the repo if the dir does not exist or is absolutely empty
+ settings.edit {
+ if (!dir.exists() || !dir.isDirectory || requireNotNull(dir.listFiles()).isEmpty()) {
+ putBoolean(PreferenceKeys.REPOSITORY_INITIALIZED, false)
+ } else {
+ putBoolean(PreferenceKeys.REPOSITORY_INITIALIZED, true)
+ }
}
- /**
- * Gets the .gpg files in a directory
- *
- * @param path the directory path
- * @return the list of gpg files in that directory
- */
- @JvmStatic
- fun getFilesList(path: File?): ArrayList<File> {
- if (path == null || !path.exists()) return ArrayList()
-
- val directories = (path.listFiles(FileFilter { pathname -> pathname.isDirectory })
- ?: emptyArray()).toList()
- val files = (path.listFiles(FileFilter { pathname -> pathname.extension == "gpg" })
- ?: emptyArray()).toList()
-
- val items = ArrayList<File>()
- items.addAll(directories)
- items.addAll(files)
-
- return items
+ // create the repository static variable in PasswordRepository
+ return getRepository(File(dir.absolutePath + "/.git"))
+ }
+
+ /**
+ * Gets the .gpg files in a directory
+ *
+ * @param path the directory path
+ * @return the list of gpg files in that directory
+ */
+ @JvmStatic
+ fun getFilesList(path: File?): ArrayList<File> {
+ if (path == null || !path.exists()) return ArrayList()
+
+ val directories = (path.listFiles(FileFilter { pathname -> pathname.isDirectory }) ?: emptyArray()).toList()
+ val files = (path.listFiles(FileFilter { pathname -> pathname.extension == "gpg" }) ?: emptyArray()).toList()
+
+ val items = ArrayList<File>()
+ items.addAll(directories)
+ items.addAll(files)
+
+ return items
+ }
+
+ /**
+ * Gets the passwords (PasswordItem) in a directory
+ *
+ * @param path the directory path
+ * @return a list of password items
+ */
+ @JvmStatic
+ fun getPasswords(path: File, rootDir: File, sortOrder: PasswordSortOrder): ArrayList<PasswordItem> {
+ // We need to recover the passwords then parse the files
+ val passList = getFilesList(path).also { it.sortBy { f -> f.name } }
+ val passwordList = ArrayList<PasswordItem>()
+ val showHidden = settings.getBoolean(PreferenceKeys.SHOW_HIDDEN_CONTENTS, false)
+
+ if (passList.size == 0) return passwordList
+ if (!showHidden) {
+ passList.filter { !it.isHidden }.toCollection(passList.apply { clear() })
}
-
- /**
- * Gets the passwords (PasswordItem) in a directory
- *
- * @param path the directory path
- * @return a list of password items
- */
- @JvmStatic
- fun getPasswords(path: File, rootDir: File, sortOrder: PasswordSortOrder): ArrayList<PasswordItem> {
- // We need to recover the passwords then parse the files
- val passList = getFilesList(path).also { it.sortBy { f -> f.name } }
- val passwordList = ArrayList<PasswordItem>()
- val showHidden = settings.getBoolean(PreferenceKeys.SHOW_HIDDEN_CONTENTS, false)
-
- if (passList.size == 0) return passwordList
- if (!showHidden) {
- passList.filter { !it.isHidden }.toCollection(passList.apply { clear() })
- }
- passList.forEach { file ->
- passwordList.add(if (file.isFile) {
- PasswordItem.newPassword(file.name, file, rootDir)
- } else {
- PasswordItem.newCategory(file.name, file, rootDir)
- })
+ passList.forEach { file ->
+ passwordList.add(
+ if (file.isFile) {
+ PasswordItem.newPassword(file.name, file, rootDir)
+ } else {
+ PasswordItem.newCategory(file.name, file, rootDir)
}
- passwordList.sortWith(sortOrder.comparator)
- return passwordList
+ )
}
+ passwordList.sortWith(sortOrder.comparator)
+ return passwordList
+ }
}