diff options
Diffstat (limited to 'app/src/main/java/com/zeapo/pwdstore/crypto/PgpActivity.kt')
| -rw-r--r-- | app/src/main/java/com/zeapo/pwdstore/crypto/PgpActivity.kt | 98 |
1 files changed, 85 insertions, 13 deletions
diff --git a/app/src/main/java/com/zeapo/pwdstore/crypto/PgpActivity.kt b/app/src/main/java/com/zeapo/pwdstore/crypto/PgpActivity.kt index 6f09ca5a..90efd583 100644 --- a/app/src/main/java/com/zeapo/pwdstore/crypto/PgpActivity.kt +++ b/app/src/main/java/com/zeapo/pwdstore/crypto/PgpActivity.kt @@ -16,6 +16,7 @@ import android.content.SharedPreferences import android.graphics.Typeface import android.os.Build import android.os.Bundle +import android.text.InputType import android.text.TextUtils import android.text.format.DateUtils import android.text.method.PasswordTransformationMethod @@ -30,6 +31,7 @@ import android.widget.CheckBox import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.widget.doOnTextChanged import androidx.lifecycle.lifecycleScope import androidx.localbroadcastmanager.content.LocalBroadcastManager import androidx.preference.PreferenceManager @@ -48,11 +50,7 @@ import java.io.File import java.nio.charset.Charset import java.util.Date import kotlinx.android.synthetic.main.decrypt_layout.* -import kotlinx.android.synthetic.main.encrypt_layout.crypto_extra_edit -import kotlinx.android.synthetic.main.encrypt_layout.crypto_password_category -import kotlinx.android.synthetic.main.encrypt_layout.crypto_password_edit -import kotlinx.android.synthetic.main.encrypt_layout.crypto_password_file_edit -import kotlinx.android.synthetic.main.encrypt_layout.generate_password +import kotlinx.android.synthetic.main.encrypt_layout.* import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.launch import me.msfjarvis.openpgpktx.util.OpenPgpApi @@ -81,6 +79,11 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound { private var editPass: String? = null private var editExtra: String? = null + private val suggestedName by lazy { intent.getStringExtra("SUGGESTED_NAME") } + private val suggestedPass by lazy { intent.getStringExtra("SUGGESTED_PASS") } + private val suggestedExtra by lazy { intent.getStringExtra("SUGGESTED_EXTRA") } + private val shouldGeneratePassword by lazy { intent.getBooleanExtra("GENERATE_PASSWORD", false) } + private val operation: String by lazy { intent.getStringExtra("OPERATION") } private val repoPath: String by lazy { intent.getStringExtra("REPO_PATH") } @@ -150,25 +153,85 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound { setContentView(R.layout.encrypt_layout) generate_password?.setOnClickListener { - when (settings.getString("pref_key_pwgen_type", KEY_PWGEN_TYPE_CLASSIC)) { - KEY_PWGEN_TYPE_CLASSIC -> PasswordGeneratorDialogFragment() - .show(supportFragmentManager, "generator") - KEY_PWGEN_TYPE_XKPASSWD -> XkPasswordGeneratorDialogFragment() - .show(supportFragmentManager, "xkpwgenerator") - } + generatePassword() } title = getString(R.string.new_password_title) crypto_password_category.text = getRelativePath(fullPath, repoPath) + suggestedName?.let { + crypto_password_file_edit.setText(it) + encrypt_username.apply { + visibility = View.VISIBLE + setOnClickListener { + if (isChecked) { + // User wants to enable username encryption, so we add it to the + // encrypted extras as the first line. + val username = crypto_password_file_edit.text!!.toString() + val extras = "username:$username\n${crypto_extra_edit.text!!}" + + crypto_password_file_edit.setText("") + crypto_extra_edit.setText(extras) + } else { + // User wants to disable username encryption, so we extract the + // username from the encrypted extras and use it as the filename. + val entry = PasswordEntry("PASSWORD\n${crypto_extra_edit.text!!}") + val username = entry.username + + // username should not be null here by the logic in + // updateEncryptUsernameState, but it could still happen due to + // input lag. + if (username != null) { + crypto_password_file_edit.setText(username) + crypto_extra_edit.setText(entry.extraContentWithoutUsername) + } + } + updateEncryptUsernameState() + } + } + crypto_password_file_edit.doOnTextChanged { _, _, _, _ -> updateEncryptUsernameState() } + crypto_extra_edit.doOnTextChanged { _, _, _, _ -> updateEncryptUsernameState() } + updateEncryptUsernameState() + } + suggestedPass?.let { + crypto_password_edit.setText(it) + crypto_password_edit.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD + } + suggestedExtra?.let { crypto_extra_edit.setText(it) } + if (shouldGeneratePassword) { + generatePassword() + crypto_password_edit.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD + } } } } + fun updateEncryptUsernameState() { + encrypt_username.apply { + if (visibility != View.VISIBLE) + return + val hasUsernameInFileName = crypto_password_file_edit.text!!.toString().isNotBlank() + // Use PasswordEntry to parse extras for username + val entry = PasswordEntry("PLACEHOLDER\n${crypto_extra_edit.text!!}") + val hasUsernameInExtras = entry.hasUsername() + isEnabled = hasUsernameInFileName xor hasUsernameInExtras + isChecked = hasUsernameInExtras + } + } + override fun onResume() { super.onResume() LocalBroadcastManager.getInstance(this).registerReceiver(receiver, IntentFilter(ACTION_CLEAR)) } + private fun generatePassword() { + when (settings.getString("pref_key_pwgen_type", KEY_PWGEN_TYPE_CLASSIC)) { + KEY_PWGEN_TYPE_CLASSIC -> PasswordGeneratorDialogFragment() + .show(supportFragmentManager, "generator") + KEY_PWGEN_TYPE_XKPASSWD -> XkPasswordGeneratorDialogFragment() + .show(supportFragmentManager, "xkpwgenerator") + } + } + override fun onStop() { LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver) super.onStop() @@ -482,7 +545,8 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound { data.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true) // TODO Check if we could use PasswordEntry to generate the file - val iStream = ByteArrayInputStream("$editPass\n$editExtra".toByteArray(Charset.forName("UTF-8"))) + val content = "$editPass\n$editExtra" + val iStream = ByteArrayInputStream(content.toByteArray(Charset.forName("UTF-8"))) val oStream = ByteArrayOutputStream() val path = if (intent.getBooleanExtra("fromDecrypt", false)) fullPath else "$fullPath/$editName.gpg" @@ -494,7 +558,8 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound { RESULT_CODE_SUCCESS -> { try { // TODO This might fail, we should check that the write is successful - val outputStream = FileUtils.openOutputStream(File(path)) + val file = File(path) + val outputStream = FileUtils.openOutputStream(file) outputStream.write(oStream.toByteArray()) outputStream.close() @@ -508,6 +573,13 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound { returnIntent.putExtra("OPERATION", "EDIT") returnIntent.putExtra("needCommit", true) } + + if (shouldGeneratePassword) { + val entry = PasswordEntry(content) + returnIntent.putExtra("PASSWORD", entry.password) + returnIntent.putExtra("USERNAME", entry.username ?: file.nameWithoutExtension) + } + setResult(RESULT_OK, returnIntent) finish() } catch (e: Exception) { |
