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

195 lines
8.7 KiB
Kotlin
Raw Normal View History

2020-07-17 16:35:39 +02:00
package sushi.hardcore.droidfs
import android.os.Build
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
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 sushi.hardcore.droidfs.adapters.SavedVolumesAdapter
2021-06-11 20:23:54 +02:00
import sushi.hardcore.droidfs.databinding.ActivityChangePasswordBinding
2021-06-07 14:12:40 +02:00
import sushi.hardcore.droidfs.util.PathUtils
import sushi.hardcore.droidfs.util.WidgetUtil
import sushi.hardcore.droidfs.util.Wiper
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-10-15 17:43:13 +02:00
private lateinit var savedVolumesAdapter: SavedVolumesAdapter
2021-06-11 20:23:54 +02:00
private lateinit var binding: ActivityChangePasswordBinding
2020-07-17 16:35:39 +02:00
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
2021-06-11 20:23:54 +02:00
binding = ActivityChangePasswordBinding.inflate(layoutInflater)
setContentView(binding.root)
2021-06-07 16:34:50 +02:00
setupLayout()
2020-10-22 22:14:22 +02:00
setupFingerprintStuff()
savedVolumesAdapter = SavedVolumesAdapter(this, volumeDatabase)
2020-07-17 16:35:39 +02:00
if (savedVolumesAdapter.count > 0){
2021-06-11 20:23:54 +02:00
binding.savedPathListview.adapter = savedVolumesAdapter
binding.savedPathListview.onItemClickListener = OnItemClickListener { _, _, position, _ ->
val volume = savedVolumesAdapter.getItem(position)
currentVolumeName = volume.name
if (volume.isHidden){
2021-06-11 20:23:54 +02:00
switchHiddenVolume.isChecked = true
editVolumeName.setText(currentVolumeName)
} else {
2021-06-11 20:23:54 +02:00
switchHiddenVolume.isChecked = false
editVolumePath.setText(currentVolumeName)
}
2021-06-07 16:34:50 +02:00
onClickSwitchHiddenVolume()
2020-07-17 16:35:39 +02:00
}
} else {
2021-06-11 20:23:54 +02:00
WidgetUtil.hideWithPadding(binding.savedPathListview)
2020-07-17 16:35:39 +02:00
}
val textWatcher = object: TextWatcher{
2020-07-17 16:35:39 +02:00
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) {
if (volumeDatabase.isVolumeSaved(s.toString())){
2021-06-11 20:23:54 +02:00
checkboxRememberPath.isEnabled = false
2021-10-19 13:52:06 +02:00
checkboxRememberPath.isChecked = true
2021-06-11 20:23:54 +02:00
binding.editOldPassword.apply {
if (volumeDatabase.isHashSaved(s.toString())){
text = null
hint = getString(R.string.hash_saved_hint)
isEnabled = false
} else {
hint = null
isEnabled = true
}
2020-10-15 17:43:13 +02:00
}
} else {
2021-06-11 20:23:54 +02:00
checkboxRememberPath.isEnabled = true
binding.editOldPassword.apply {
hint = null
isEnabled = true
}
2020-07-17 16:35:39 +02:00
}
}
}
2021-06-11 20:23:54 +02:00
editVolumePath.addTextChangedListener(textWatcher)
editVolumeName.addTextChangedListener(textWatcher)
binding.editNewPasswordConfirm.setOnEditorActionListener { _, _, _ ->
2021-06-07 16:34:50 +02:00
checkVolumePathThenChangePassword()
2020-07-17 16:35:39 +02:00
true
}
2021-06-11 20:23:54 +02:00
binding.buttonChangePassword.setOnClickListener {
2021-06-07 16:34:50 +02:00
checkVolumePathThenChangePassword()
}
2020-07-17 16:35:39 +02:00
}
2021-06-07 16:34:50 +02:00
fun checkVolumePathThenChangePassword() {
loadVolumePath {
val volumeFile = File(currentVolumePath)
if (!GocryptfsVolume.isGocryptfsVolume(volumeFile)){
2020-10-14 19:04:19 +02:00
ColoredAlertDialogBuilder(this)
.setTitle(R.string.error)
.setMessage(R.string.error_not_a_volume)
.setPositiveButton(R.string.ok, null)
.show()
} else if (!volumeFile.canWrite()){
errorDirectoryNotWritable(R.string.change_pwd_cant_write_error_msg)
2020-08-25 14:10:46 +02:00
} else {
changePassword()
2020-08-25 14:10:46 +02:00
}
2020-07-17 16:35:39 +02:00
}
}
private fun changePassword(givenHash: ByteArray? = null){
2021-06-11 20:23:54 +02:00
val newPassword = binding.editNewPassword.text.toString().toCharArray()
val newPasswordConfirm = binding.editNewPasswordConfirm.text.toString().toCharArray()
2020-08-25 14:10:46 +02:00
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) {
2021-06-11 20:23:54 +02:00
val oldPassword = binding.editOldPassword.text.toString().toCharArray()
2020-07-28 22:25:10 +02:00
var returnedHash: ByteArray? = null
2021-06-11 20:23:54 +02:00
if (checkboxSavePassword.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) {
var volume: Volume? = null
volumeDatabase.getVolumes().forEach { testVolume ->
if (testVolume.name == currentVolumeName){
volume = testVolume
}
}
volume?.let {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
it.hash?.let { hash ->
it.iv?.let { iv ->
currentVolumePath = if (it.isHidden){
PathUtils.pathJoin(filesDir.path, it.name)
} else {
it.name
}
stopTask {
loadPasswordHash(hash, iv, ::changePassword)
}
changePasswordImmediately = false
}
}
2020-07-28 22:25:10 +02:00
}
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(currentVolumePath, oldPassword, givenHash, newPassword, returnedHash)) {
2021-06-11 20:23:54 +02:00
val volume = Volume(currentVolumeName, switchHiddenVolume.isChecked)
if (volumeDatabase.isHashSaved(currentVolumeName)) {
volumeDatabase.removeHash(volume)
2020-07-27 16:20:52 +02:00
}
2021-06-11 20:23:54 +02:00
if (checkboxRememberPath.isChecked) {
volumeDatabase.saveVolume(volume)
2020-07-17 16:35:39 +02:00
}
2021-06-11 20:23:54 +02:00
if (checkboxSavePassword.isChecked && returnedHash != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
2020-10-22 22:14:22 +02:00
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()
}
override fun onDestroy() {
super.onDestroy()
2021-06-11 20:23:54 +02:00
Wiper.wipeEditText(binding.editOldPassword)
Wiper.wipeEditText(binding.editNewPassword)
Wiper.wipeEditText(binding.editNewPasswordConfirm)
2020-07-17 16:35:39 +02:00
}
}