From ac6220eed31f1aab0f73403b3befe77c57f0c9a1 Mon Sep 17 00:00:00 2001 From: Harsh Shandilya Date: Mon, 29 Jun 2020 12:50:05 +0530 Subject: Merge SshKeyGenFragment into its activity (#897) * Merge SshKeyGenFragment into its activity Signed-off-by: Harsh Shandilya * Drop neutral button discouraged by material specs Signed-off-by: Harsh Shandilya * Address review comments Signed-off-by: Harsh Shandilya --- .../zeapo/pwdstore/sshkeygen/ShowSshKeyFragment.kt | 7 +- .../zeapo/pwdstore/sshkeygen/SshKeyGenActivity.kt | 94 +++++++++++++++-- .../zeapo/pwdstore/sshkeygen/SshKeyGenFragment.kt | 111 --------------------- 3 files changed, 91 insertions(+), 121 deletions(-) delete mode 100644 app/src/main/java/com/zeapo/pwdstore/sshkeygen/SshKeyGenFragment.kt (limited to 'app/src/main/java/com/zeapo') diff --git a/app/src/main/java/com/zeapo/pwdstore/sshkeygen/ShowSshKeyFragment.kt b/app/src/main/java/com/zeapo/pwdstore/sshkeygen/ShowSshKeyFragment.kt index 8f4fbf84..109ebd01 100644 --- a/app/src/main/java/com/zeapo/pwdstore/sshkeygen/ShowSshKeyFragment.kt +++ b/app/src/main/java/com/zeapo/pwdstore/sshkeygen/ShowSshKeyFragment.kt @@ -36,7 +36,7 @@ class ShowSshKeyFragment : DialogFragment() { createMaterialDialog(view) val ad = builder.create() ad.setOnShowListener { - val b = ad.getButton(AlertDialog.BUTTON_NEUTRAL) + val b = ad.getButton(AlertDialog.BUTTON_POSITIVE) b.setOnClickListener { val clipboard = activity.clipboard ?: return@setOnClickListener val clip = ClipData.newPlainText("public key", publicKey.text.toString()) @@ -49,9 +49,8 @@ class ShowSshKeyFragment : DialogFragment() { private fun createMaterialDialog(view: View) { builder.setView(view) builder.setTitle(getString(R.string.your_public_key)) - builder.setPositiveButton(getString(R.string.dialog_ok)) { _, _ -> requireActivity().finish() } - builder.setNegativeButton(getString(R.string.dialog_cancel), null) - builder.setNeutralButton(resources.getString(R.string.ssh_keygen_copy), null) + builder.setNegativeButton(R.string.dialog_ok) { _, _ -> requireActivity().finish() } + builder.setPositiveButton(R.string.ssh_keygen_copy, null) } private fun readKeyFromFile() { diff --git a/app/src/main/java/com/zeapo/pwdstore/sshkeygen/SshKeyGenActivity.kt b/app/src/main/java/com/zeapo/pwdstore/sshkeygen/SshKeyGenActivity.kt index 2bb04e20..0f844b31 100644 --- a/app/src/main/java/com/zeapo/pwdstore/sshkeygen/SshKeyGenActivity.kt +++ b/app/src/main/java/com/zeapo/pwdstore/sshkeygen/SshKeyGenActivity.kt @@ -6,18 +6,48 @@ package com.zeapo.pwdstore.sshkeygen import android.os.Bundle import android.view.MenuItem +import android.view.View +import android.view.inputmethod.InputMethodManager import androidx.appcompat.app.AppCompatActivity +import androidx.core.content.edit +import androidx.core.content.getSystemService +import androidx.lifecycle.lifecycleScope +import androidx.preference.PreferenceManager +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.jcraft.jsch.JSch +import com.jcraft.jsch.KeyPair +import com.zeapo.pwdstore.R +import com.zeapo.pwdstore.databinding.ActivitySshKeygenBinding +import com.zeapo.pwdstore.utils.getEncryptedPrefs +import com.zeapo.pwdstore.utils.viewBinding +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import java.io.File +import java.io.FileOutputStream class SshKeyGenActivity : AppCompatActivity() { - public override fun onCreate(savedInstanceState: Bundle?) { + private var keyLength = 4096 + private val binding by viewBinding(ActivitySshKeygenBinding::inflate) + + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + setContentView(binding.root) supportActionBar?.setDisplayHomeAsUpEnabled(true) - if (savedInstanceState == null) { - supportFragmentManager - .beginTransaction() - .replace(android.R.id.content, SshKeyGenFragment()) - .commit() + with(binding) { + generate.setOnClickListener { + lifecycleScope.launch { generate(passphrase.text.toString(), comment.text.toString()) } + } + keyLengthGroup.check(R.id.key_length_4096) + keyLengthGroup.addOnButtonCheckedListener { _, checkedId, isChecked -> + if (isChecked) { + when (checkedId) { + R.id.key_length_2048 -> keyLength = 2048 + R.id.key_length_4096 -> keyLength = 4096 + } + } + } } } @@ -31,4 +61,56 @@ class SshKeyGenActivity : AppCompatActivity() { else -> super.onOptionsItemSelected(item) } } + + private suspend fun generate(passphrase: String, comment: String) { + binding.generate.text = getString(R.string.ssh_key_gen_generating_progress) + val e = try { + withContext(Dispatchers.IO) { + val kp = KeyPair.genKeyPair(JSch(), KeyPair.RSA, keyLength) + var file = File(filesDir, ".ssh_key") + var out = FileOutputStream(file, false) + if (passphrase.isNotEmpty()) { + kp?.writePrivateKey(out, passphrase.toByteArray()) + } else { + kp?.writePrivateKey(out) + } + file = File(filesDir, ".ssh_key.pub") + out = FileOutputStream(file, false) + kp?.writePublicKey(out, comment) + } + null + } catch (e: Exception) { + e.printStackTrace() + e + } finally { + getEncryptedPrefs("git_operation").edit { + remove("ssh_key_local_passphrase") + } + } + binding.generate.text = getString(R.string.ssh_keygen_generating_done) + if (e == null) { + val df = ShowSshKeyFragment() + df.show(supportFragmentManager, "public_key") + val prefs = PreferenceManager.getDefaultSharedPreferences(this) + prefs.edit { putBoolean("use_generated_key", true) } + } else { + MaterialAlertDialogBuilder(this) + .setTitle(getString(R.string.error_generate_ssh_key)) + .setMessage(getString(R.string.ssh_key_error_dialog_text) + e.message) + .setPositiveButton(getString(R.string.dialog_ok)) { _, _ -> + finish() + } + .show() + } + hideKeyboard() + } + + private fun hideKeyboard() { + val imm = getSystemService() ?: return + var view = currentFocus + if (view == null) { + view = View(this) + } + imm.hideSoftInputFromWindow(view.windowToken, 0) + } } diff --git a/app/src/main/java/com/zeapo/pwdstore/sshkeygen/SshKeyGenFragment.kt b/app/src/main/java/com/zeapo/pwdstore/sshkeygen/SshKeyGenFragment.kt deleted file mode 100644 index 9b9d58f5..00000000 --- a/app/src/main/java/com/zeapo/pwdstore/sshkeygen/SshKeyGenFragment.kt +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved. - * SPDX-License-Identifier: GPL-3.0-only - */ -package com.zeapo.pwdstore.sshkeygen - -import android.os.Bundle -import android.view.View -import android.view.inputmethod.InputMethodManager -import androidx.core.content.edit -import androidx.core.content.getSystemService -import androidx.fragment.app.Fragment -import androidx.lifecycle.lifecycleScope -import androidx.preference.PreferenceManager -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import com.jcraft.jsch.JSch -import com.jcraft.jsch.KeyPair -import com.zeapo.pwdstore.R -import com.zeapo.pwdstore.databinding.FragmentSshKeygenBinding -import com.zeapo.pwdstore.utils.getEncryptedPrefs -import com.zeapo.pwdstore.utils.viewBinding -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import java.io.File -import java.io.FileOutputStream - -class SshKeyGenFragment : Fragment(R.layout.fragment_ssh_keygen) { - - private var keyLength = 4096 - private val binding by viewBinding(FragmentSshKeygenBinding::bind) - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - with(binding) { - generate.setOnClickListener { - lifecycleScope.launch { generate(passphrase.text.toString(), comment.text.toString()) } - } - keyLengthGroup.check(R.id.key_length_4096) - keyLengthGroup.addOnButtonCheckedListener { _, checkedId, isChecked -> - if (isChecked) { - when (checkedId) { - R.id.key_length_2048 -> keyLength = 2048 - R.id.key_length_4096 -> keyLength = 4096 - } - } - } - } - } - - override fun onDestroyView() { - super.onDestroyView() - } - - // Invoked when 'Generate' button of SshKeyGenFragment clicked. Generates a - // private and public key, then replaces the SshKeyGenFragment with a - // ShowSshKeyFragment which displays the public key. - private suspend fun generate(passphrase: String, comment: String) { - binding.generate.text = getString(R.string.ssh_key_gen_generating_progress) - val e = try { - withContext(Dispatchers.IO) { - val kp = KeyPair.genKeyPair(JSch(), KeyPair.RSA, keyLength) - var file = File(requireActivity().filesDir, ".ssh_key") - var out = FileOutputStream(file, false) - if (passphrase.isNotEmpty()) { - kp?.writePrivateKey(out, passphrase.toByteArray()) - } else { - kp?.writePrivateKey(out) - } - file = File(requireActivity().filesDir, ".ssh_key.pub") - out = FileOutputStream(file, false) - kp?.writePublicKey(out, comment) - } - null - } catch (e: Exception) { - e.printStackTrace() - e - } finally { - requireContext().getEncryptedPrefs("git_operation").edit { - remove("ssh_key_local_passphrase") - } - } - val activity = requireActivity() - binding.generate.text = getString(R.string.ssh_keygen_generating_done) - if (e == null) { - val df = ShowSshKeyFragment() - df.show(requireActivity().supportFragmentManager, "public_key") - val prefs = PreferenceManager.getDefaultSharedPreferences(activity) - prefs.edit { putBoolean("use_generated_key", true) } - } else { - MaterialAlertDialogBuilder(activity) - .setTitle(activity.getString(R.string.error_generate_ssh_key)) - .setMessage(activity.getString(R.string.ssh_key_error_dialog_text) + e.message) - .setPositiveButton(activity.getString(R.string.dialog_ok)) { _, _ -> - requireActivity().finish() - } - .show() - } - hideKeyboard() - } - - private fun hideKeyboard() { - val activity = activity ?: return - val imm = activity.getSystemService() ?: return - var view = activity.currentFocus - if (view == null) { - view = View(activity) - } - imm.hideSoftInputFromWindow(view.windowToken, 0) - } -} -- cgit v1.2.3