aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/main/java/com/zeapo/pwdstore/crypto/PgpActivity.kt
diff options
context:
space:
mode:
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.kt98
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) {