Rework import keys pass confirmation

- Show button as loading until the import is done, *then* close popup
- Remove the dedicated backend password checking function, we can use
  import_keys() directly now
- Handle all the possible errors that could be thrown from python
This commit is contained in:
miruka 2019-11-30 05:50:56 -04:00
parent a09e811e56
commit 3b2ab048fb
4 changed files with 33 additions and 47 deletions

View File

@ -141,29 +141,6 @@ class Backend:
return nio.Api.mxc_to_http(mxc)
@staticmethod
async def check_exported_keys_passphrase(file_path: str, passphrase: str,
) -> Union[bool, Tuple[str, bool]]:
"""Check if the exported keys file can be decrypted with passphrase.
Returns True on success, False is the passphrase is invalid, or
an (error_message, error_is_translated) tuple if another error occured.
"""
try:
nio.crypto.key_export.decrypt_and_read(file_path, passphrase)
return True
except OSError as err: # XXX raise
return (f"{file_path}: {err.strerror}", True)
except ValueError as err: # XXX raise
if str(err).startswith("HMAC check failed"):
return False
return (str(err), False)
async def load_settings(self) -> tuple:
from .config_files import Theme
settings = await self.ui_settings.read()

View File

@ -12,6 +12,8 @@ HFileDialogOpener {
}
// This is used for the LogoutPopup to know when the export is done
// so it can close
signal done()

View File

@ -11,24 +11,10 @@ HFileDialogOpener {
}
signal done()
property string userId: ""
property bool importing: false
function importKeys(file, passphrase) {
importing = true
let path = file.toString().replace(/^file:\/\//, "")
py.callClientCoro(userId, "import_keys", [path, passphrase], () => {
importing = false
done()
})
}
PasswordPopup {
id: importPasswordPopup
details.text: qsTr(
@ -36,16 +22,38 @@ HFileDialogOpener {
)
okText: qsTr("Import")
onAcceptedPasswordChanged: importKeys(file, acceptedPassword)
property url file: ""
function verifyPassword(pass, callback) {
py.callCoro(
"check_exported_keys_passphrase",
[file.toString().replace(/^file:\/\//, ""), pass],
callback
)
importing = true
let path = file.toString().replace(/^file:\/\//, "")
py.callClientCoro(userId, "import_keys", [path, pass], () => {
importing = false
callback(true)
}, (type, args) => {
callback(
type === "EncryptionError" ?
false :
type === "ValueError" ?
qsTr("Invalid file format") :
type === "FileNotFoundError" ?
qsTr("This file doesn't exist") :
type === "IsADirectoryError" ?
qsTr("A folder was given, expecting a file") :
type === "PermissionError" ?
qsTr("No permission to read this file") :
qsTr("Unknown error: %1 - %2").arg(type).arg(args)
)
})
}
}
}

View File

@ -25,8 +25,8 @@ BoxPopup {
function verifyPassword(pass, callback) {
// Can be reimplemented when using this component.
// Pass to the callback true on success, false on invalid password, or
// a [error message, translated] array for any other error.
// Pass to the callback true on success, false on invalid password,
// or a custom error message string.
callback(true)
}
@ -46,8 +46,7 @@ BoxPopup {
} else if (result === false) {
passwordValid = false
} else {
let [msg, translated] = result
errorMessage.text = translated ? msg : qsTr(msg)
errorMessage.text = result
}
button.loading = false