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/ui/crypto/BasePgpActivity.kt | |
| 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/ui/crypto/BasePgpActivity.kt')
| -rw-r--r-- | app/src/main/java/dev/msfjarvis/aps/ui/crypto/BasePgpActivity.kt | 442 |
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 + } } + } } |
