aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/main/java/dev/msfjarvis/aps/ui/crypto/BasePgpActivity.kt
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/ui/crypto/BasePgpActivity.kt
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/ui/crypto/BasePgpActivity.kt')
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/crypto/BasePgpActivity.kt442
1 files changed, 211 insertions, 231 deletions
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/crypto/BasePgpActivity.kt b/app/src/main/java/dev/msfjarvis/aps/ui/crypto/BasePgpActivity.kt
index 5dee98cb..fc03b76b 100644
--- a/app/src/main/java/dev/msfjarvis/aps/ui/crypto/BasePgpActivity.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/ui/crypto/BasePgpActivity.kt
@@ -42,269 +42,249 @@ import org.openintents.openpgp.OpenPgpError
@Suppress("Registered")
open class BasePgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound {
- /**
- * Full path to the repository
- */
- val repoPath by lazy(LazyThreadSafetyMode.NONE) { intent.getStringExtra("REPO_PATH")!! }
+ /** Full path to the repository */
+ val repoPath by lazy(LazyThreadSafetyMode.NONE) { intent.getStringExtra("REPO_PATH")!! }
- /**
- * Full path to the password file being worked on
- */
- val fullPath by lazy(LazyThreadSafetyMode.NONE) { intent.getStringExtra("FILE_PATH")!! }
+ /** Full path to the password file being worked on */
+ val fullPath by lazy(LazyThreadSafetyMode.NONE) { intent.getStringExtra("FILE_PATH")!! }
- /**
- * Name of the password file
- *
- * Converts personal/auth.foo.org/john_doe@example.org.gpg to john_doe.example.org
- */
- val name: String by lazy(LazyThreadSafetyMode.NONE) { File(fullPath).nameWithoutExtension }
+ /**
+ * Name of the password file
+ *
+ * Converts personal/auth.foo.org/john_doe@example.org.gpg to john_doe.example.org
+ */
+ val name: String by lazy(LazyThreadSafetyMode.NONE) { File(fullPath).nameWithoutExtension }
- /**
- * Get the timestamp for when this file was last modified.
- */
- val lastChangedString: CharSequence by lazy(LazyThreadSafetyMode.NONE) {
- getLastChangedString(
- intent.getLongExtra(
- "LAST_CHANGED_TIMESTAMP",
- -1L
- )
- )
- }
+ /** Get the timestamp for when this file was last modified. */
+ val lastChangedString: CharSequence by lazy(LazyThreadSafetyMode.NONE) {
+ getLastChangedString(intent.getLongExtra("LAST_CHANGED_TIMESTAMP", -1L))
+ }
- /**
- * [SharedPreferences] instance used by subclasses to persist settings
- */
- val settings: SharedPreferences by lazy(LazyThreadSafetyMode.NONE) { sharedPrefs }
+ /** [SharedPreferences] instance used by subclasses to persist settings */
+ val settings: SharedPreferences by lazy(LazyThreadSafetyMode.NONE) { sharedPrefs }
- /**
- * Handle to the [OpenPgpApi] instance that is used by subclasses to interface with OpenKeychain.
- */
- private var serviceConnection: OpenPgpServiceConnection? = null
- var api: OpenPgpApi? = null
+ /**
+ * Handle to the [OpenPgpApi] instance that is used by subclasses to interface with OpenKeychain.
+ */
+ private var serviceConnection: OpenPgpServiceConnection? = null
+ var api: OpenPgpApi? = null
- /**
- * A [OpenPgpServiceConnection.OnBound] instance for the last listener that we wish to bind with
- * in case the previous attempt was cancelled due to missing [OPENPGP_PROVIDER] package.
- */
- private var previousListener: OpenPgpServiceConnection.OnBound? = null
+ /**
+ * A [OpenPgpServiceConnection.OnBound] instance for the last listener that we wish to bind with
+ * in case the previous attempt was cancelled due to missing [OPENPGP_PROVIDER] package.
+ */
+ private var previousListener: OpenPgpServiceConnection.OnBound? = null
- /**
- * [onCreate] sets the window up with the right flags to prevent auth leaks through screenshots
- * or recent apps screen.
- */
- @CallSuper
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE)
- tag(TAG)
- }
+ /**
+ * [onCreate] sets the window up with the right flags to prevent auth leaks through screenshots or
+ * recent apps screen.
+ */
+ @CallSuper
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE)
+ tag(TAG)
+ }
- /**
- * [onDestroy] handles unbinding from the OpenPgp service linked with [serviceConnection]. This
- * is annotated with [CallSuper] because it's critical to unbind the service to ensure we're not
- * leaking things.
- */
- @CallSuper
- override fun onDestroy() {
- super.onDestroy()
- serviceConnection?.unbindFromService()
- previousListener = null
- }
+ /**
+ * [onDestroy] handles unbinding from the OpenPgp service linked with [serviceConnection]. This is
+ * annotated with [CallSuper] because it's critical to unbind the service to ensure we're not
+ * leaking things.
+ */
+ @CallSuper
+ override fun onDestroy() {
+ super.onDestroy()
+ serviceConnection?.unbindFromService()
+ previousListener = null
+ }
- /**
- * [onResume] controls the flow for resumption of a PGP operation that was previously interrupted
- * by the [OPENPGP_PROVIDER] package being missing.
- */
- override fun onResume() {
- super.onResume()
- previousListener?.let { bindToOpenKeychain(it) }
- }
+ /**
+ * [onResume] controls the flow for resumption of a PGP operation that was previously interrupted
+ * by the [OPENPGP_PROVIDER] package being missing.
+ */
+ override fun onResume() {
+ super.onResume()
+ previousListener?.let { bindToOpenKeychain(it) }
+ }
- /**
- * Sets up [api] once the service is bound. Downstream consumers must call super this to
- * initialize [api]
- */
- @CallSuper
- override fun onBound(service: IOpenPgpService2) {
- api = OpenPgpApi(this, service)
- }
+ /**
+ * Sets up [api] once the service is bound. Downstream consumers must call super this to
+ * initialize [api]
+ */
+ @CallSuper
+ override fun onBound(service: IOpenPgpService2) {
+ api = OpenPgpApi(this, service)
+ }
- /**
- * Mandatory error handling from [OpenPgpServiceConnection.OnBound]. All subclasses must handle
- * their own errors, and hence this class simply logs and rethrows. Subclasses Must NOT call super.
- */
- override fun onError(e: Exception) {
- e(e) { "Callers must handle their own exceptions" }
- throw e
- }
+ /**
+ * Mandatory error handling from [OpenPgpServiceConnection.OnBound]. All subclasses must handle
+ * their own errors, and hence this class simply logs and rethrows. Subclasses Must NOT call
+ * super.
+ */
+ override fun onError(e: Exception) {
+ e(e) { "Callers must handle their own exceptions" }
+ throw e
+ }
- /**
- * Method for subclasses to initiate binding with [OpenPgpServiceConnection].
- */
- fun bindToOpenKeychain(onBoundListener: OpenPgpServiceConnection.OnBound) {
- val installed = runCatching {
- packageManager.getPackageInfo(OPENPGP_PROVIDER, 0)
- true
- }.getOr(false)
- if (!installed) {
- previousListener = onBoundListener
- MaterialAlertDialogBuilder(this)
- .setTitle(getString(R.string.openkeychain_not_installed_title))
- .setMessage(getString(R.string.openkeychain_not_installed_message))
- .setPositiveButton(getString(R.string.openkeychain_not_installed_google_play)) { _, _ ->
- runCatching {
- val intent = Intent(Intent.ACTION_VIEW).apply {
- data = Uri.parse(getString(R.string.play_deeplink_template, OPENPGP_PROVIDER))
- setPackage("com.android.vending")
- }
- startActivity(intent)
- }
- }
- .setNeutralButton(getString(R.string.openkeychain_not_installed_fdroid)) { _, _ ->
- runCatching {
- val intent = Intent(Intent.ACTION_VIEW).apply {
- data = Uri.parse(getString(R.string.fdroid_deeplink_template, OPENPGP_PROVIDER))
- }
- startActivity(intent)
- }
- }
- .setOnCancelListener { finish() }
- .show()
- return
- } else {
- previousListener = null
- serviceConnection = OpenPgpServiceConnection(this, OPENPGP_PROVIDER, onBoundListener).also {
- it.bindToService()
- }
+ /** Method for subclasses to initiate binding with [OpenPgpServiceConnection]. */
+ fun bindToOpenKeychain(onBoundListener: OpenPgpServiceConnection.OnBound) {
+ val installed =
+ runCatching {
+ packageManager.getPackageInfo(OPENPGP_PROVIDER, 0)
+ true
}
+ .getOr(false)
+ if (!installed) {
+ previousListener = onBoundListener
+ MaterialAlertDialogBuilder(this)
+ .setTitle(getString(R.string.openkeychain_not_installed_title))
+ .setMessage(getString(R.string.openkeychain_not_installed_message))
+ .setPositiveButton(getString(R.string.openkeychain_not_installed_google_play)) { _, _ ->
+ runCatching {
+ val intent =
+ Intent(Intent.ACTION_VIEW).apply {
+ data = Uri.parse(getString(R.string.play_deeplink_template, OPENPGP_PROVIDER))
+ setPackage("com.android.vending")
+ }
+ startActivity(intent)
+ }
+ }
+ .setNeutralButton(getString(R.string.openkeychain_not_installed_fdroid)) { _, _ ->
+ runCatching {
+ val intent =
+ Intent(Intent.ACTION_VIEW).apply {
+ data = Uri.parse(getString(R.string.fdroid_deeplink_template, OPENPGP_PROVIDER))
+ }
+ startActivity(intent)
+ }
+ }
+ .setOnCancelListener { finish() }
+ .show()
+ return
+ } else {
+ previousListener = null
+ serviceConnection = OpenPgpServiceConnection(this, OPENPGP_PROVIDER, onBoundListener).also { it.bindToService() }
}
+ }
- /**
- * Handle the case where OpenKeychain returns that it needs to interact with the user
- *
- * @param result The intent returned by OpenKeychain
- */
- fun getUserInteractionRequestIntent(result: Intent): IntentSender {
- i { "RESULT_CODE_USER_INTERACTION_REQUIRED" }
- return result.getParcelableExtra<PendingIntent>(OpenPgpApi.RESULT_INTENT)!!.intentSender
- }
-
- /**
- * Gets a relative string describing when this shape was last changed
- * (e.g. "one hour ago")
- */
- private fun getLastChangedString(timeStamp: Long): CharSequence {
- if (timeStamp < 0) {
- throw RuntimeException()
- }
+ /**
+ * Handle the case where OpenKeychain returns that it needs to interact with the user
+ *
+ * @param result The intent returned by OpenKeychain
+ */
+ fun getUserInteractionRequestIntent(result: Intent): IntentSender {
+ i { "RESULT_CODE_USER_INTERACTION_REQUIRED" }
+ return result.getParcelableExtra<PendingIntent>(OpenPgpApi.RESULT_INTENT)!!.intentSender
+ }
- return DateUtils.getRelativeTimeSpanString(this, timeStamp, true)
+ /** Gets a relative string describing when this shape was last changed (e.g. "one hour ago") */
+ private fun getLastChangedString(timeStamp: Long): CharSequence {
+ if (timeStamp < 0) {
+ throw RuntimeException()
}
- /**
- * Base handling of OpenKeychain errors based on the error contained in [result]. Subclasses
- * can use this when they want to default to sane error handling.
- */
- fun handleError(result: Intent) {
- val error: OpenPgpError? = result.getParcelableExtra(OpenPgpApi.RESULT_ERROR)
- if (error != null) {
- when (error.errorId) {
- OpenPgpError.NO_OR_WRONG_PASSPHRASE -> {
- snackbar(message = getString(R.string.openpgp_error_wrong_passphrase))
- }
- OpenPgpError.NO_USER_IDS -> {
- snackbar(message = getString(R.string.openpgp_error_no_user_ids))
- }
- else -> {
- snackbar(message = getString(R.string.openpgp_error_unknown, error.message))
- e { "onError getErrorId: ${error.errorId}" }
- e { "onError getMessage: ${error.message}" }
- }
- }
+ return DateUtils.getRelativeTimeSpanString(this, timeStamp, true)
+ }
+
+ /**
+ * Base handling of OpenKeychain errors based on the error contained in [result]. Subclasses can
+ * use this when they want to default to sane error handling.
+ */
+ fun handleError(result: Intent) {
+ val error: OpenPgpError? = result.getParcelableExtra(OpenPgpApi.RESULT_ERROR)
+ if (error != null) {
+ when (error.errorId) {
+ OpenPgpError.NO_OR_WRONG_PASSPHRASE -> {
+ snackbar(message = getString(R.string.openpgp_error_wrong_passphrase))
+ }
+ OpenPgpError.NO_USER_IDS -> {
+ snackbar(message = getString(R.string.openpgp_error_no_user_ids))
+ }
+ else -> {
+ snackbar(message = getString(R.string.openpgp_error_unknown, error.message))
+ e { "onError getErrorId: ${error.errorId}" }
+ e { "onError getMessage: ${error.message}" }
}
+ }
}
+ }
- /**
- * Copies provided [text] to the clipboard. Shows a [Snackbar] which can be disabled by passing
- * [showSnackbar] as false.
- */
- fun copyTextToClipboard(
- text: String?,
- showSnackbar: Boolean = true,
- @StringRes snackbarTextRes: Int = R.string.clipboard_copied_text
- ) {
- val clipboard = clipboard ?: return
- val clip = ClipData.newPlainText("pgp_handler_result_pm", text)
- clipboard.setPrimaryClip(clip)
- if (showSnackbar) {
- snackbar(message = resources.getString(snackbarTextRes))
- }
+ /**
+ * Copies provided [text] to the clipboard. Shows a [Snackbar] which can be disabled by passing
+ * [showSnackbar] as false.
+ */
+ fun copyTextToClipboard(
+ text: String?,
+ showSnackbar: Boolean = true,
+ @StringRes snackbarTextRes: Int = R.string.clipboard_copied_text
+ ) {
+ val clipboard = clipboard ?: return
+ val clip = ClipData.newPlainText("pgp_handler_result_pm", text)
+ clipboard.setPrimaryClip(clip)
+ if (showSnackbar) {
+ snackbar(message = resources.getString(snackbarTextRes))
}
+ }
- /**
- * Copies a provided [password] string to the clipboard. This wraps [copyTextToClipboard] to
- * hide the default [Snackbar] and starts off an instance of [ClipboardService] to provide a
- * way of clearing the clipboard.
- */
- fun copyPasswordToClipboard(password: String?) {
- copyTextToClipboard(password, showSnackbar = false)
+ /**
+ * Copies a provided [password] string to the clipboard. This wraps [copyTextToClipboard] to hide
+ * the default [Snackbar] and starts off an instance of [ClipboardService] to provide a way of
+ * clearing the clipboard.
+ */
+ fun copyPasswordToClipboard(password: String?) {
+ copyTextToClipboard(password, showSnackbar = false)
- val clearAfter = settings.getString(PreferenceKeys.GENERAL_SHOW_TIME)?.toIntOrNull() ?: 45
+ val clearAfter = settings.getString(PreferenceKeys.GENERAL_SHOW_TIME)?.toIntOrNull() ?: 45
- if (clearAfter != 0) {
- val service = Intent(this, ClipboardService::class.java).apply {
- action = ClipboardService.ACTION_START
- putExtra(ClipboardService.EXTRA_NOTIFICATION_TIME, clearAfter)
- }
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- startForegroundService(service)
- } else {
- startService(service)
- }
- snackbar(message = resources.getString(R.string.clipboard_password_toast_text, clearAfter))
- } else {
- snackbar(message = resources.getString(R.string.clipboard_password_no_clear_toast_text))
+ if (clearAfter != 0) {
+ val service =
+ Intent(this, ClipboardService::class.java).apply {
+ action = ClipboardService.ACTION_START
+ putExtra(ClipboardService.EXTRA_NOTIFICATION_TIME, clearAfter)
}
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ startForegroundService(service)
+ } else {
+ startService(service)
+ }
+ snackbar(message = resources.getString(R.string.clipboard_password_toast_text, clearAfter))
+ } else {
+ snackbar(message = resources.getString(R.string.clipboard_password_no_clear_toast_text))
}
+ }
- companion object {
+ companion object {
- private const val TAG = "APS/BasePgpActivity"
- const val KEY_PWGEN_TYPE_CLASSIC = "classic"
- const val KEY_PWGEN_TYPE_XKPASSWD = "xkpasswd"
+ private const val TAG = "APS/BasePgpActivity"
+ const val KEY_PWGEN_TYPE_CLASSIC = "classic"
+ const val KEY_PWGEN_TYPE_XKPASSWD = "xkpasswd"
- /**
- * Gets the relative path to the repository
- */
- fun getRelativePath(fullPath: String, repositoryPath: String): String =
- fullPath.replace(repositoryPath, "").replace("/+".toRegex(), "/")
+ /** Gets the relative path to the repository */
+ fun getRelativePath(fullPath: String, repositoryPath: String): String =
+ fullPath.replace(repositoryPath, "").replace("/+".toRegex(), "/")
- /**
- * Gets the Parent path, relative to the repository
- */
- fun getParentPath(fullPath: String, repositoryPath: String): String {
- val relativePath = getRelativePath(fullPath, repositoryPath)
- val index = relativePath.lastIndexOf("/")
- return "/${relativePath.substring(startIndex = 0, endIndex = index + 1)}/".replace("/+".toRegex(), "/")
- }
+ /** Gets the Parent path, relative to the repository */
+ fun getParentPath(fullPath: String, repositoryPath: String): String {
+ val relativePath = getRelativePath(fullPath, repositoryPath)
+ val index = relativePath.lastIndexOf("/")
+ return "/${relativePath.substring(startIndex = 0, endIndex = index + 1)}/".replace("/+".toRegex(), "/")
+ }
- /**
- * /path/to/store/social/facebook.gpg -> social/facebook
- */
- @JvmStatic
- fun getLongName(fullPath: String, repositoryPath: String, basename: String): String {
- var relativePath = getRelativePath(fullPath, repositoryPath)
- return if (relativePath.isNotEmpty() && relativePath != "/") {
- // remove preceding '/'
- relativePath = relativePath.substring(1)
- if (relativePath.endsWith('/')) {
- relativePath + basename
- } else {
- "$relativePath/$basename"
- }
- } else {
- basename
- }
+ /** /path/to/store/social/facebook.gpg -> social/facebook */
+ @JvmStatic
+ fun getLongName(fullPath: String, repositoryPath: String, basename: String): String {
+ var relativePath = getRelativePath(fullPath, repositoryPath)
+ return if (relativePath.isNotEmpty() && relativePath != "/") {
+ // remove preceding '/'
+ relativePath = relativePath.substring(1)
+ if (relativePath.endsWith('/')) {
+ relativePath + basename
+ } else {
+ "$relativePath/$basename"
}
+ } else {
+ basename
+ }
}
+ }
}