From 549ee790d3e52bc62565ddf92e6a556e98b5195e Mon Sep 17 00:00:00 2001 From: Harsh Shandilya Date: Fri, 15 Jul 2022 00:53:48 +0530 Subject: all: re-do package structure yet again --- .../msfjarvis/aps/data/crypto/CryptoRepository.kt | 55 ------- .../dev/msfjarvis/aps/data/password/FieldItem.kt | 43 ----- .../msfjarvis/aps/data/password/PasswordItem.kt | 77 --------- .../msfjarvis/aps/data/repo/PasswordRepository.kt | 176 --------------------- 4 files changed, 351 deletions(-) delete mode 100644 app/src/main/java/dev/msfjarvis/aps/data/crypto/CryptoRepository.kt delete mode 100644 app/src/main/java/dev/msfjarvis/aps/data/password/FieldItem.kt delete mode 100644 app/src/main/java/dev/msfjarvis/aps/data/password/PasswordItem.kt delete mode 100644 app/src/main/java/dev/msfjarvis/aps/data/repo/PasswordRepository.kt (limited to 'app/src/main/java/dev/msfjarvis/aps/data') diff --git a/app/src/main/java/dev/msfjarvis/aps/data/crypto/CryptoRepository.kt b/app/src/main/java/dev/msfjarvis/aps/data/crypto/CryptoRepository.kt deleted file mode 100644 index 0e262e7a..00000000 --- a/app/src/main/java/dev/msfjarvis/aps/data/crypto/CryptoRepository.kt +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved. - * SPDX-License-Identifier: GPL-3.0-only - */ - -package dev.msfjarvis.aps.data.crypto - -import com.github.michaelbull.result.unwrap -import dev.msfjarvis.aps.crypto.PGPKeyManager -import dev.msfjarvis.aps.crypto.PGPainlessCryptoHandler -import dev.msfjarvis.aps.util.extensions.isOk -import java.io.ByteArrayInputStream -import java.io.ByteArrayOutputStream -import javax.inject.Inject -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext - -class CryptoRepository -@Inject -constructor( - private val pgpKeyManager: PGPKeyManager, - private val pgpCryptoHandler: PGPainlessCryptoHandler, -) { - - suspend fun decrypt( - password: String, - message: ByteArrayInputStream, - out: ByteArrayOutputStream, - ) { - withContext(Dispatchers.IO) { decryptPgp(password, message, out) } - } - - suspend fun encrypt(content: ByteArrayInputStream, out: ByteArrayOutputStream) { - withContext(Dispatchers.IO) { encryptPgp(content, out) } - } - - private suspend fun decryptPgp( - password: String, - message: ByteArrayInputStream, - out: ByteArrayOutputStream, - ) { - val keys = pgpKeyManager.getAllKeys().unwrap() - // Iterates through the keys until the first successful decryption, then returns. - keys.firstOrNull { key -> pgpCryptoHandler.decrypt(key, password, message, out).isOk() } - } - - private suspend fun encryptPgp(content: ByteArrayInputStream, out: ByteArrayOutputStream) { - val keys = pgpKeyManager.getAllKeys().unwrap() - pgpCryptoHandler.encrypt( - keys, - content, - out, - ) - } -} 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 deleted file mode 100644 index e7c88ef1..00000000 --- a/app/src/main/java/dev/msfjarvis/aps/data/password/FieldItem.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved. - * SPDX-License-Identifier: GPL-3.0-only - */ - -package dev.msfjarvis.aps.data.password - -import dev.msfjarvis.aps.data.passfile.Totp -import kotlin.time.ExperimentalTime - -@OptIn(ExperimentalTime::class) -class FieldItem(val key: String, val value: String, val action: ActionType) { - enum class ActionType { - COPY, - HIDE - } - - enum class ItemType(val type: String, val label: String) { - USERNAME("Username", "Username"), - PASSWORD("Password", "Password"), - OTP("OTP", "OTP (expires in %ds)"), - } - - companion object { - - // Extra helper methods - fun createOtpField(totp: Totp): FieldItem { - return FieldItem( - ItemType.OTP.label.format(totp.remainingTime.inWholeSeconds), - totp.value, - ActionType.COPY, - ) - } - - fun createPasswordField(password: String): FieldItem { - return FieldItem(ItemType.PASSWORD.label, password, ActionType.HIDE) - } - - fun createUsernameField(username: String): FieldItem { - return FieldItem(ItemType.USERNAME.label, username, ActionType.COPY) - } - } -} 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 deleted file mode 100644 index 82b0dc35..00000000 --- a/app/src/main/java/dev/msfjarvis/aps/data/password/PasswordItem.kt +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved. - * SPDX-License-Identifier: GPL-3.0-only - */ -package dev.msfjarvis.aps.data.password - -import android.content.Context -import android.content.Intent -import dev.msfjarvis.aps.data.repo.PasswordRepository -import dev.msfjarvis.aps.ui.crypto.BasePgpActivity -import dev.msfjarvis.aps.ui.main.LaunchActivity -import java.io.File - -data class PasswordItem( - val name: String, - val parent: PasswordItem? = null, - val type: Char, - val file: File, - val rootDir: File -) : Comparable { - - val fullPathToParent = file.absolutePath.replace(rootDir.absolutePath, "").replace(file.name, "") - - val longName = BasePgpActivity.getLongName(fullPathToParent, rootDir.absolutePath, toString()) - - 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 toString(): String { - return name.replace("\\.gpg$".toRegex(), "") - } - - override fun hashCode(): Int { - return 0 - } - - /** Creates an [Intent] to launch this [PasswordItem] through the authentication process. */ - fun createAuthEnabledIntent(context: Context): Intent { - val intent = Intent(context, LaunchActivity::class.java) - intent.putExtra("NAME", toString()) - intent.putExtra("FILE_PATH", file.absolutePath) - intent.putExtra("REPO_PATH", PasswordRepository.getRepositoryDirectory().absolutePath) - intent.action = LaunchActivity.ACTION_DECRYPT_PASS - return intent - } - - companion object { - - 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, 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, 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 deleted file mode 100644 index f675e80a..00000000 --- a/app/src/main/java/dev/msfjarvis/aps/data/repo/PasswordRepository.kt +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved. - * SPDX-License-Identifier: GPL-3.0-only - */ -package dev.msfjarvis.aps.data.repo - -import androidx.core.content.edit -import com.github.michaelbull.result.getOrElse -import com.github.michaelbull.result.onFailure -import com.github.michaelbull.result.runCatching -import dev.msfjarvis.aps.Application -import dev.msfjarvis.aps.data.password.PasswordItem -import dev.msfjarvis.aps.util.extensions.sharedPrefs -import dev.msfjarvis.aps.util.extensions.unsafeLazy -import dev.msfjarvis.aps.util.settings.PasswordSortOrder -import dev.msfjarvis.aps.util.settings.PreferenceKeys -import java.io.File -import org.eclipse.jgit.api.Git -import org.eclipse.jgit.lib.Repository -import org.eclipse.jgit.storage.file.FileRepositoryBuilder -import org.eclipse.jgit.transport.RefSpec -import org.eclipse.jgit.transport.RemoteConfig -import org.eclipse.jgit.transport.URIish - -object PasswordRepository { - - var repository: Repository? = null - private val settings by unsafeLazy { Application.instance.sharedPrefs } - private val filesDir - get() = Application.instance.filesDir - val isInitialized: Boolean - get() = repository != null - - fun isGitRepo(): Boolean { - return repository?.objectDatabase?.exists() ?: false - } - - /** - * Takes in a [repositoryDir] to initialize a Git repository with, and assigns it to [repository] - * as static state. - */ - private fun initializeRepository(repositoryDir: File) { - val builder = FileRepositoryBuilder() - repository = - runCatching { builder.setGitDir(repositoryDir).build() } - .getOrElse { e -> - e.printStackTrace() - null - } - } - - fun createRepository(repositoryDir: File) { - repositoryDir.delete() - Git.init().setDirectory(repositoryDir).call() - initializeRepository(repositoryDir) - } - - // TODO add multiple remotes support for pull/push - 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]) - } - - remoteConfig.addURI(uri) - remoteConfig.addPushURI(uri) - - remoteConfig.update(storedConfig) - - storedConfig.save() - } - .onFailure { e -> e.printStackTrace() } - } - } - - fun closeRepository() { - repository?.close() - repository = null - } - - fun getRepositoryDirectory(): File { - return File(filesDir.toString(), "/store") - } - - fun initialize(): Repository? { - val dir = getRepositoryDirectory() - // Un-initialize 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 - initializeRepository(dir.resolve(".git")) - - return repository - } - - /** - * Gets the .gpg files in a directory - * - * @param path the directory path - * @return the list of gpg files in that directory - */ - private fun getFilesList(path: File): ArrayList { - if (!path.exists()) return ArrayList() - val files = - (path.listFiles { file -> file.isDirectory || file.extension == "gpg" } ?: emptyArray()) - .toList() - val items = ArrayList() - items.addAll(files) - return items - } - - /** - * Gets the passwords (PasswordItem) in a directory - * - * @param path the directory path - * @return a list of password items - */ - fun getPasswords( - path: File, - rootDir: File, - sortOrder: PasswordSortOrder - ): ArrayList { - // We need to recover the passwords then parse the files - val passList = getFilesList(path).also { it.sortBy { f -> f.name } } - val passwordList = ArrayList() - 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) - } - ) - } - passwordList.sortWith(sortOrder.comparator) - return passwordList - } -} -- cgit v1.2.3