diff options
| author | Harsh Shandilya <me@msfjarvis.dev> | 2021-03-09 14:53:11 +0530 |
|---|---|---|
| committer | Harsh Shandilya <me@msfjarvis.dev> | 2021-03-18 11:40:30 +0530 |
| commit | 774fda83ac276a635e3402034b1eedbd10be916f (patch) | |
| tree | 57783a953fcd193d32f1e3dc8df26e07f03df328 /app/src/main/java/dev/msfjarvis/aps/data | |
| parent | be31ae37f443982b377d027cd613f04d0926568d (diff) | |
| download | HardenedPass-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')
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 + } } |
