build: update to openpgp-ktx 2.0 (#749)

Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
Harsh Shandilya 2020-04-29 11:01:22 +05:30 committed by GitHub
parent f9c310e93a
commit edc6dcda88
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 188 additions and 203 deletions

View file

@ -9,15 +9,6 @@ plugins {
final def keystorePropertiesFile = rootProject.file 'keystore.properties' final def keystorePropertiesFile = rootProject.file 'keystore.properties'
final def gitHash = { ->
final def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'describe', '--tags'
standardOutput = stdout
}
stdout.toString().trim()
}
static final def isSnapshot() { static final def isSnapshot() {
return System.env['GITHUB_WORKFLOW'] != null && System.env['SNAPSHOT'] != null return System.env['GITHUB_WORKFLOW'] != null && System.env['SNAPSHOT'] != null
} }

View file

@ -365,175 +365,173 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound {
val oStream = ByteArrayOutputStream() val oStream = ByteArrayOutputStream()
lifecycleScope.launch(IO) { lifecycleScope.launch(IO) {
api?.executeApiAsync(data, iStream, oStream, object : OpenPgpApi.IOpenPgpCallback { api?.executeApiAsync(data, iStream, oStream) { result ->
override fun onReturn(result: Intent?) { when (result?.getIntExtra(RESULT_CODE, RESULT_CODE_ERROR)) {
when (result?.getIntExtra(RESULT_CODE, RESULT_CODE_ERROR)) { RESULT_CODE_SUCCESS -> {
RESULT_CODE_SUCCESS -> { try {
try { val showPassword = settings.getBoolean("show_password", true)
val showPassword = settings.getBoolean("show_password", true) val showExtraContent = settings.getBoolean("show_extra_content", true)
val showExtraContent = settings.getBoolean("show_extra_content", true)
crypto_container_decrypt.visibility = View.VISIBLE crypto_container_decrypt.visibility = View.VISIBLE
val monoTypeface = Typeface.createFromAsset(assets, "fonts/sourcecodepro.ttf") val monoTypeface = Typeface.createFromAsset(assets, "fonts/sourcecodepro.ttf")
val entry = PasswordEntry(oStream) val entry = PasswordEntry(oStream)
passwordEntry = entry passwordEntry = entry
if (intent.getStringExtra("OPERATION") == "EDIT") { if (intent.getStringExtra("OPERATION") == "EDIT") {
editPassword() editPassword()
return return@executeApiAsync
} }
if (entry.password.isEmpty()) { if (entry.password.isEmpty()) {
crypto_password_show.visibility = View.GONE crypto_password_show.visibility = View.GONE
crypto_password_show_label.visibility = View.GONE crypto_password_show_label.visibility = View.GONE
} else { } else {
crypto_password_show.visibility = View.VISIBLE crypto_password_show.visibility = View.VISIBLE
crypto_password_show_label.visibility = View.VISIBLE crypto_password_show_label.visibility = View.VISIBLE
crypto_password_show.typeface = monoTypeface
crypto_password_show.text = entry.password
}
crypto_password_show.typeface = monoTypeface crypto_password_show.typeface = monoTypeface
crypto_password_show.text = entry.password crypto_password_show.text = entry.password
}
crypto_password_show.typeface = monoTypeface
crypto_password_show.text = entry.password
crypto_password_toggle_show.visibility = if (showPassword) View.GONE else View.VISIBLE crypto_password_toggle_show.visibility = if (showPassword) View.GONE else View.VISIBLE
crypto_password_show.transformationMethod = if (showPassword) { crypto_password_show.transformationMethod = if (showPassword) {
null null
} else { } else {
HoldToShowPasswordTransformation( HoldToShowPasswordTransformation(
crypto_password_toggle_show, crypto_password_toggle_show,
Runnable { crypto_password_show.text = entry.password } Runnable { crypto_password_show.text = entry.password }
) )
} }
if (entry.hasExtraContent()) { if (entry.hasExtraContent()) {
crypto_extra_show.typeface = monoTypeface crypto_extra_show.typeface = monoTypeface
crypto_extra_show.text = entry.extraContent crypto_extra_show.text = entry.extraContent
if (showExtraContent) { if (showExtraContent) {
crypto_extra_show_layout.visibility = View.VISIBLE
crypto_extra_toggle_show.visibility = View.GONE
crypto_extra_show.transformationMethod = null
} else {
crypto_extra_show_layout.visibility = View.GONE
crypto_extra_toggle_show.visibility = View.VISIBLE
crypto_extra_toggle_show.setOnCheckedChangeListener { _, _ ->
crypto_extra_show.text = entry.extraContent
}
crypto_extra_show.transformationMethod = object : PasswordTransformationMethod() {
override fun getTransformation(source: CharSequence, view: View): CharSequence {
return if (crypto_extra_toggle_show.isChecked) source else super.getTransformation(source, view)
}
}
}
if (entry.hasUsername()) {
crypto_username_show.visibility = View.VISIBLE
crypto_username_show_label.visibility = View.VISIBLE
crypto_copy_username.visibility = View.VISIBLE
crypto_copy_username.setOnClickListener { copyUsernameToClipBoard(entry.username!!) }
crypto_username_show.typeface = monoTypeface
crypto_username_show.text = entry.username
} else {
crypto_username_show.visibility = View.GONE
crypto_username_show_label.visibility = View.GONE
crypto_copy_username.visibility = View.GONE
}
}
if (entry.hasTotp() || entry.hasHotp()) {
crypto_extra_show_layout.visibility = View.VISIBLE crypto_extra_show_layout.visibility = View.VISIBLE
crypto_extra_show.typeface = monoTypeface crypto_extra_toggle_show.visibility = View.GONE
crypto_extra_show.text = entry.extraContent crypto_extra_show.transformationMethod = null
} else {
crypto_extra_show_layout.visibility = View.GONE
crypto_extra_toggle_show.visibility = View.VISIBLE
crypto_extra_toggle_show.setOnCheckedChangeListener { _, _ ->
crypto_extra_show.text = entry.extraContent
}
crypto_otp_show.visibility = View.VISIBLE crypto_extra_show.transformationMethod = object : PasswordTransformationMethod() {
crypto_otp_show_label.visibility = View.VISIBLE override fun getTransformation(source: CharSequence, view: View): CharSequence {
crypto_copy_otp.visibility = View.VISIBLE return if (crypto_extra_toggle_show.isChecked) source else super.getTransformation(source, view)
if (entry.hasTotp()) {
crypto_copy_otp.setOnClickListener {
copyOtpToClipBoard(
Otp.calculateCode(
entry.totpSecret,
Date().time / (1000 * entry.totpPeriod),
entry.totpAlgorithm,
entry.digits)
)
} }
crypto_otp_show.text = }
}
if (entry.hasUsername()) {
crypto_username_show.visibility = View.VISIBLE
crypto_username_show_label.visibility = View.VISIBLE
crypto_copy_username.visibility = View.VISIBLE
crypto_copy_username.setOnClickListener { copyUsernameToClipBoard(entry.username!!) }
crypto_username_show.typeface = monoTypeface
crypto_username_show.text = entry.username
} else {
crypto_username_show.visibility = View.GONE
crypto_username_show_label.visibility = View.GONE
crypto_copy_username.visibility = View.GONE
}
}
if (entry.hasTotp() || entry.hasHotp()) {
crypto_extra_show_layout.visibility = View.VISIBLE
crypto_extra_show.typeface = monoTypeface
crypto_extra_show.text = entry.extraContent
crypto_otp_show.visibility = View.VISIBLE
crypto_otp_show_label.visibility = View.VISIBLE
crypto_copy_otp.visibility = View.VISIBLE
if (entry.hasTotp()) {
crypto_copy_otp.setOnClickListener {
copyOtpToClipBoard(
Otp.calculateCode( Otp.calculateCode(
entry.totpSecret, entry.totpSecret,
Date().time / (1000 * entry.totpPeriod), Date().time / (1000 * entry.totpPeriod),
entry.totpAlgorithm, entry.totpAlgorithm,
entry.digits) entry.digits)
} else { )
// we only want to calculate and show HOTP if the user requests it }
crypto_copy_otp.setOnClickListener { crypto_otp_show.text =
if (settings.getBoolean("hotp_remember_check", false)) { Otp.calculateCode(
if (settings.getBoolean("hotp_remember_choice", false)) { entry.totpSecret,
calculateAndCommitHotp(entry) Date().time / (1000 * entry.totpPeriod),
} else { entry.totpAlgorithm,
calculateHotp(entry) entry.digits)
} } else {
// we only want to calculate and show HOTP if the user requests it
crypto_copy_otp.setOnClickListener {
if (settings.getBoolean("hotp_remember_check", false)) {
if (settings.getBoolean("hotp_remember_choice", false)) {
calculateAndCommitHotp(entry)
} else { } else {
// show a dialog asking permission to update the HOTP counter in the entry calculateHotp(entry)
val checkInflater = LayoutInflater.from(this@PgpActivity) }
val checkLayout = checkInflater.inflate(R.layout.otp_confirm_layout, null) } else {
val rememberCheck: CheckBox = // show a dialog asking permission to update the HOTP counter in the entry
checkLayout.findViewById(R.id.hotp_remember_checkbox) val checkInflater = LayoutInflater.from(this@PgpActivity)
val dialogBuilder = MaterialAlertDialogBuilder(this@PgpActivity) val checkLayout = checkInflater.inflate(R.layout.otp_confirm_layout, null)
dialogBuilder.setView(checkLayout) val rememberCheck: CheckBox =
dialogBuilder.setMessage(R.string.dialog_update_body) checkLayout.findViewById(R.id.hotp_remember_checkbox)
.setCancelable(false) val dialogBuilder = MaterialAlertDialogBuilder(this@PgpActivity)
.setPositiveButton(R.string.dialog_update_positive) { _, _ -> dialogBuilder.setView(checkLayout)
run { dialogBuilder.setMessage(R.string.dialog_update_body)
calculateAndCommitHotp(entry) .setCancelable(false)
if (rememberCheck.isChecked) { .setPositiveButton(R.string.dialog_update_positive) { _, _ ->
settings.edit { run {
putBoolean("hotp_remember_check", true) calculateAndCommitHotp(entry)
putBoolean("hotp_remember_choice", true) if (rememberCheck.isChecked) {
}
}
}
}
.setNegativeButton(R.string.dialog_update_negative) { _, _ ->
run {
calculateHotp(entry)
settings.edit { settings.edit {
putBoolean("hotp_remember_check", true) putBoolean("hotp_remember_check", true)
putBoolean("hotp_remember_choice", false) putBoolean("hotp_remember_choice", true)
} }
} }
} }
val updateDialog = dialogBuilder.create() }
updateDialog.setTitle(R.string.dialog_update_title) .setNegativeButton(R.string.dialog_update_negative) { _, _ ->
updateDialog.show() run {
} calculateHotp(entry)
settings.edit {
putBoolean("hotp_remember_check", true)
putBoolean("hotp_remember_choice", false)
}
}
}
val updateDialog = dialogBuilder.create()
updateDialog.setTitle(R.string.dialog_update_title)
updateDialog.show()
} }
crypto_otp_show.setText(R.string.hotp_pending)
} }
crypto_otp_show.typeface = monoTypeface crypto_otp_show.setText(R.string.hotp_pending)
} else {
crypto_otp_show.visibility = View.GONE
crypto_otp_show_label.visibility = View.GONE
crypto_copy_otp.visibility = View.GONE
} }
crypto_otp_show.typeface = monoTypeface
if (settings.getBoolean("copy_on_decrypt", true)) { } else {
copyPasswordToClipBoard() crypto_otp_show.visibility = View.GONE
} crypto_otp_show_label.visibility = View.GONE
} catch (e: Exception) { crypto_copy_otp.visibility = View.GONE
e(e) { "An Exception occurred" }
} }
if (settings.getBoolean("copy_on_decrypt", true)) {
copyPasswordToClipBoard()
}
} catch (e: Exception) {
e(e) { "An Exception occurred" }
} }
RESULT_CODE_USER_INTERACTION_REQUIRED -> handleUserInteractionRequest(result, REQUEST_DECRYPT)
RESULT_CODE_ERROR -> handleError(result)
} }
RESULT_CODE_USER_INTERACTION_REQUIRED -> handleUserInteractionRequest(result, REQUEST_DECRYPT)
RESULT_CODE_ERROR -> handleError(result)
} }
}) }
} }
} }
@ -591,48 +589,46 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound {
} }
lifecycleScope.launch(IO) { lifecycleScope.launch(IO) {
api?.executeApiAsync(data, iStream, oStream, object : OpenPgpApi.IOpenPgpCallback { api?.executeApiAsync(data, iStream, oStream) { result ->
override fun onReturn(result: Intent?) { when (result?.getIntExtra(RESULT_CODE, RESULT_CODE_ERROR)) {
when (result?.getIntExtra(RESULT_CODE, RESULT_CODE_ERROR)) { RESULT_CODE_SUCCESS -> {
RESULT_CODE_SUCCESS -> { try {
try { // TODO This might fail, we should check that the write is successful
// TODO This might fail, we should check that the write is successful val file = File(path)
val file = File(path) val outputStream = FileUtils.openOutputStream(file)
val outputStream = FileUtils.openOutputStream(file) outputStream.write(oStream.toByteArray())
outputStream.write(oStream.toByteArray()) outputStream.close()
outputStream.close()
val returnIntent = Intent() val returnIntent = Intent()
returnIntent.putExtra("CREATED_FILE", path) returnIntent.putExtra("CREATED_FILE", path)
returnIntent.putExtra("NAME", editName) returnIntent.putExtra("NAME", editName)
returnIntent.putExtra("LONG_NAME", getLongName(fullPath, repoPath, editName!!)) returnIntent.putExtra("LONG_NAME", getLongName(fullPath, repoPath, editName!!))
// if coming from decrypt screen->edit button // if coming from decrypt screen->edit button
if (intent.getBooleanExtra("fromDecrypt", false)) { if (intent.getBooleanExtra("fromDecrypt", false)) {
returnIntent.putExtra("OPERATION", "EDIT") returnIntent.putExtra("OPERATION", "EDIT")
returnIntent.putExtra("needCommit", true) returnIntent.putExtra("needCommit", true)
}
if (shouldGeneratePassword) {
val directoryStructure =
AutofillPreferences.directoryStructure(applicationContext)
val entry = PasswordEntry(content)
returnIntent.putExtra("PASSWORD", entry.password)
val username = PasswordEntry(content).username
?: directoryStructure.getUsernameFor(file)
returnIntent.putExtra("USERNAME", username)
}
setResult(RESULT_OK, returnIntent)
finish()
} catch (e: Exception) {
e(e) { "An Exception occurred" }
} }
if (shouldGeneratePassword) {
val directoryStructure =
AutofillPreferences.directoryStructure(applicationContext)
val entry = PasswordEntry(content)
returnIntent.putExtra("PASSWORD", entry.password)
val username = PasswordEntry(content).username
?: directoryStructure.getUsernameFor(file)
returnIntent.putExtra("USERNAME", username)
}
setResult(RESULT_OK, returnIntent)
finish()
} catch (e: Exception) {
e(e) { "An Exception occurred" }
} }
RESULT_CODE_ERROR -> handleError(result)
} }
RESULT_CODE_ERROR -> handleError(result)
} }
}) }
} }
} }
@ -715,31 +711,29 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound {
val data = receivedIntent ?: Intent() val data = receivedIntent ?: Intent()
data.action = OpenPgpApi.ACTION_GET_KEY_IDS data.action = OpenPgpApi.ACTION_GET_KEY_IDS
lifecycleScope.launch(IO) { lifecycleScope.launch(IO) {
api?.executeApiAsync(data, null, null, object : OpenPgpApi.IOpenPgpCallback { api?.executeApiAsync(data, null, null) { result ->
override fun onReturn(result: Intent?) { when (result?.getIntExtra(RESULT_CODE, RESULT_CODE_ERROR)) {
when (result?.getIntExtra(RESULT_CODE, RESULT_CODE_ERROR)) { RESULT_CODE_SUCCESS -> {
RESULT_CODE_SUCCESS -> { try {
try { val ids = result.getLongArrayExtra(OpenPgpApi.RESULT_KEY_IDS)
val ids = result.getLongArrayExtra(OpenPgpApi.RESULT_KEY_IDS) ?: LongArray(0)
?: LongArray(0) val keys = ids.map { it.toString() }.toSet()
val keys = ids.map { it.toString() }.toSet()
// use Long // use Long
settings.edit { putStringSet("openpgp_key_ids_set", keys) } settings.edit { putStringSet("openpgp_key_ids_set", keys) }
showSnackbar("PGP keys selected") showSnackbar("PGP keys selected")
setResult(RESULT_OK) setResult(RESULT_OK)
finish() finish()
} catch (e: Exception) { } catch (e: Exception) {
e(e) { "An Exception occurred" } e(e) { "An Exception occurred" }
}
} }
RESULT_CODE_USER_INTERACTION_REQUIRED -> handleUserInteractionRequest(result, REQUEST_KEY_ID)
RESULT_CODE_ERROR -> handleError(result)
} }
RESULT_CODE_USER_INTERACTION_REQUIRED -> handleUserInteractionRequest(result, REQUEST_KEY_ID)
RESULT_CODE_ERROR -> handleError(result)
} }
}) }
} }
} }

View file

@ -52,7 +52,7 @@ ext.deps = [
jsch: 'com.jcraft:jsch:0.1.55', jsch: 'com.jcraft:jsch:0.1.55',
jgit: 'org.eclipse.jgit:org.eclipse.jgit:3.7.1.201504261725-r', jgit: 'org.eclipse.jgit:org.eclipse.jgit:3.7.1.201504261725-r',
leakcanary: 'com.squareup.leakcanary:leakcanary-android:2.2', leakcanary: 'com.squareup.leakcanary:leakcanary-android:2.2',
openpgp_ktx: 'com.github.android-password-store:openpgp-ktx:1.2.0', openpgp_ktx: 'com.github.android-password-store:openpgp-ktx:2.0.0',
// The library is updated every two weeks to include the most recent version of the Public // The library is updated every two weeks to include the most recent version of the Public
// suffix list. Its API is expected to remain stable for the foreseeable future, and thus // suffix list. Its API is expected to remain stable for the foreseeable future, and thus
// a reference to the latest version is warranted. // a reference to the latest version is warranted.