DroidFS/app/src/main/java/sushi/hardcore/droidfs/ChangePasswordActivity.kt

218 lines
9.5 KiB
Kotlin
Raw Normal View History

2020-07-17 16:35:39 +02:00
package sushi.hardcore.droidfs
import android.app.Activity
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.View
import android.widget.AdapterView.OnItemClickListener
import android.widget.Toast
2020-07-28 22:25:10 +02:00
import androidx.appcompat.app.AppCompatActivity
2020-07-17 16:35:39 +02:00
import kotlinx.android.synthetic.main.activity_change_password.*
2020-10-15 17:43:13 +02:00
import kotlinx.android.synthetic.main.checkboxes_section.*
import kotlinx.android.synthetic.main.volume_path_section.*
2020-07-17 16:35:39 +02:00
import sushi.hardcore.droidfs.adapters.SavedVolumesAdapter
2020-07-28 22:25:10 +02:00
import sushi.hardcore.droidfs.util.*
2020-07-27 16:20:52 +02:00
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
2020-08-25 14:10:46 +02:00
import java.io.File
2020-07-17 16:35:39 +02:00
import java.util.*
2020-10-22 22:14:22 +02:00
class ChangePasswordActivity : VolumeActionActivity() {
2020-07-17 16:35:39 +02:00
companion object {
private const val PICK_DIRECTORY_REQUEST_CODE = 1
}
2020-10-15 17:43:13 +02:00
private lateinit var savedVolumesAdapter: SavedVolumesAdapter
2020-07-17 16:35:39 +02:00
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_change_password)
2020-10-22 22:14:22 +02:00
setupActionBar()
setupFingerprintStuff()
2020-10-15 17:43:13 +02:00
savedVolumesAdapter = SavedVolumesAdapter(this, sharedPrefs)
2020-07-17 16:35:39 +02:00
if (savedVolumesAdapter.count > 0){
saved_path_listview.adapter = savedVolumesAdapter
saved_path_listview.onItemClickListener = OnItemClickListener { _, _, position, _ ->
edit_volume_path.setText(savedVolumesAdapter.getItem(position))
}
} else {
WidgetUtil.hide(saved_path_listview)
}
edit_volume_path.addTextChangedListener(object: TextWatcher{
override fun afterTextChanged(s: Editable?) {
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
2020-10-15 17:43:13 +02:00
if (savedVolumesAdapter.isPathSaved(s.toString())){
checkbox_remember_path.isEnabled = false
checkbox_remember_path.isChecked = false
if (sharedPrefs.getString(s.toString(), null) != null){
edit_old_password.text = null
edit_old_password.hint = getString(R.string.hash_saved_hint)
edit_old_password.isEnabled = false
} else {
edit_old_password.hint = null
edit_old_password.isEnabled = true
}
} else {
checkbox_remember_path.isEnabled = true
2020-07-17 16:35:39 +02:00
edit_old_password.hint = null
2020-07-28 22:25:10 +02:00
edit_old_password.isEnabled = true
2020-07-17 16:35:39 +02:00
}
}
})
edit_new_password_confirm.setOnEditorActionListener { v, _, _ ->
onClickChangePassword(v)
true
}
}
2020-07-21 15:05:05 +02:00
fun pickDirectory(view: View?) {
2020-07-17 16:35:39 +02:00
val i = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
startActivityForResult(i, PICK_DIRECTORY_REQUEST_CODE)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK) {
if (requestCode == PICK_DIRECTORY_REQUEST_CODE) {
2020-08-25 14:10:46 +02:00
if (data?.data != null) {
2020-11-03 17:22:09 +01:00
if (PathUtils.isTreeUriOnPrimaryStorage(data.data!!)){
2020-08-25 14:10:46 +02:00
val path = PathUtils.getFullPathFromTreeUri(data.data, this)
if (path != null){
edit_volume_path.setText(path)
} else {
ColoredAlertDialogBuilder(this)
.setTitle(R.string.error)
.setMessage(R.string.path_from_uri_null_error_msg)
.setPositiveButton(R.string.ok, null)
.show()
}
} else {
ColoredAlertDialogBuilder(this)
.setTitle(R.string.warning)
.setMessage(R.string.change_pwd_on_sdcard_error_msg)
.setPositiveButton(R.string.ok, null)
.show()
}
2020-07-17 16:35:39 +02:00
}
}
}
}
fun onClickChangePassword(view: View?) {
2020-07-27 16:20:52 +02:00
rootCipherDir = edit_volume_path.text.toString()
if (rootCipherDir.isEmpty()) {
2020-07-17 16:35:39 +02:00
Toast.makeText(this, R.string.enter_volume_path, Toast.LENGTH_SHORT).show()
} else {
2020-10-14 19:04:19 +02:00
val rootCipherDirFile = File(rootCipherDir)
if (!GocryptfsVolume.isGocryptfsVolume(rootCipherDirFile)){
ColoredAlertDialogBuilder(this)
.setTitle(R.string.error)
.setMessage(R.string.error_not_a_volume)
.setPositiveButton(R.string.ok, null)
.show()
} else if (!rootCipherDirFile.canWrite()){
2020-08-25 14:10:46 +02:00
ColoredAlertDialogBuilder(this)
.setTitle(R.string.warning)
.setMessage(R.string.change_pwd_cant_write_error_msg)
.setPositiveButton(R.string.ok, null)
.show()
} else {
changePassword(null)
}
2020-07-17 16:35:39 +02:00
}
}
2020-07-27 16:20:52 +02:00
private fun changePassword(givenHash: ByteArray?){
2020-08-25 14:10:46 +02:00
val newPassword = edit_new_password.text.toString().toCharArray()
val newPasswordConfirm = edit_new_password_confirm.text.toString().toCharArray()
if (!newPassword.contentEquals(newPasswordConfirm)) {
Toast.makeText(this, R.string.passwords_mismatch, Toast.LENGTH_SHORT).show()
} else {
object : LoadingTask(this, R.string.loading_msg_change_password) {
override fun doTask(activity: AppCompatActivity) {
2020-07-28 22:25:10 +02:00
val oldPassword = edit_old_password.text.toString().toCharArray()
var returnedHash: ByteArray? = null
2020-10-22 22:14:22 +02:00
if (checkbox_save_password.isChecked) {
2020-07-28 22:25:10 +02:00
returnedHash = ByteArray(GocryptfsVolume.KeyLen)
2020-07-17 16:35:39 +02:00
}
2020-07-28 22:25:10 +02:00
var changePasswordImmediately = true
2020-08-25 14:10:46 +02:00
if (givenHash == null) {
2020-07-28 22:25:10 +02:00
val cipherText = sharedPrefs.getString(rootCipherDir, null)
2020-10-22 22:14:22 +02:00
if (cipherText != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { //password hash saved
2020-07-28 22:25:10 +02:00
stopTask {
2020-10-22 22:14:22 +02:00
loadPasswordHash(cipherText, ::changePassword)
2020-07-28 22:25:10 +02:00
}
changePasswordImmediately = false
2020-07-17 16:35:39 +02:00
}
2020-07-28 22:25:10 +02:00
}
2020-08-25 14:10:46 +02:00
if (changePasswordImmediately) {
if (GocryptfsVolume.changePassword(
rootCipherDir,
oldPassword,
givenHash,
newPassword,
returnedHash
)
) {
if (sharedPrefs.getString(rootCipherDir, null) != null) {
2020-10-15 17:43:13 +02:00
val editor = sharedPrefs.edit()
2020-07-28 22:25:10 +02:00
editor.remove(rootCipherDir)
2020-07-27 16:20:52 +02:00
editor.apply()
}
2020-07-28 22:25:10 +02:00
if (checkbox_remember_path.isChecked) {
2020-10-15 17:43:13 +02:00
savedVolumesAdapter.addVolumePath(rootCipherDir)
2020-07-17 16:35:39 +02:00
}
2020-10-22 22:14:22 +02:00
if (checkbox_save_password.isChecked && returnedHash != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
stopTask {
savePasswordHash(returnedHash) {
onPasswordChanged()
}
2020-10-15 17:43:13 +02:00
}
} else {
2020-07-28 22:25:10 +02:00
stopTask { onPasswordChanged() }
}
} else {
stopTask {
ColoredAlertDialogBuilder(activity)
.setTitle(R.string.error)
.setMessage(R.string.change_password_failed)
.setPositiveButton(R.string.ok, null)
.show()
}
2020-07-17 16:35:39 +02:00
}
}
2020-07-28 22:25:10 +02:00
Arrays.fill(oldPassword, 0.toChar())
2020-07-17 16:35:39 +02:00
}
2020-08-25 14:10:46 +02:00
override fun doFinally(activity: AppCompatActivity) {
Arrays.fill(newPassword, 0.toChar())
Arrays.fill(newPasswordConfirm, 0.toChar())
}
2020-07-17 16:35:39 +02:00
}
2020-07-28 22:25:10 +02:00
}
2020-07-17 16:35:39 +02:00
}
2020-07-27 16:20:52 +02:00
private fun onPasswordChanged(){
ColoredAlertDialogBuilder(this)
2020-07-17 16:35:39 +02:00
.setTitle(R.string.success_change_password)
.setMessage(R.string.success_change_password_msg)
.setCancelable(false)
.setPositiveButton(R.string.ok) { _, _ -> finish() }
.show()
}
fun onClickRememberPath(view: View) {
if (!checkbox_remember_path.isChecked){
checkbox_save_password.isChecked = false
}
}
override fun onDestroy() {
super.onDestroy()
Wiper.wipeEditText(edit_old_password)
Wiper.wipeEditText(edit_new_password)
Wiper.wipeEditText(edit_new_password_confirm)
}
}