Better error handling and fixes for key import

This commit is contained in:
miruka 2019-08-27 23:51:38 -04:00
parent 399a35dacb
commit f65c0176ba
4 changed files with 64 additions and 21 deletions

View File

@ -1,3 +1,5 @@
rename hinterfacebox
translated arg for avatar upload and login
- Refactoring - Refactoring
- Banners - Banners

View File

@ -128,13 +128,27 @@ class Backend:
@staticmethod @staticmethod
def check_exported_keys_password(file_path: str, password: str) -> bool: 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: try:
nio.crypto.key_export.decrypt_and_read(file_path, password) nio.crypto.key_export.decrypt_and_read(file_path, passphrase)
return True return True
except (FileNotFoundError, ValueError):
except OSError as err:
return (f"{file_path}: {err.strerror}", True)
except ValueError as err:
if str(err).startswith("HMAC check failed"):
return False return False
return (str(err), False)
async def load_settings(self) -> tuple: async def load_settings(self) -> tuple:
from .config_files import Theme from .config_files import Theme

View File

@ -9,9 +9,14 @@ Popup {
modal: true modal: true
padding: 0 padding: 0
onAboutToShow: {
acceptedPassword = ""
passwordValid = null
okClicked = false
errorMessage.text = ""
}
onOpened: passwordField.forceActiveFocus() onOpened: passwordField.forceActiveFocus()
property bool validateWhileTyping: false property bool validateWhileTyping: false
property string acceptedPassword: "" property string acceptedPassword: ""
@ -22,9 +27,11 @@ Popup {
property alias field: passwordField property alias field: passwordField
function verifyPassword(pass) { function verifyPassword(pass, callback) {
// Implement me when using this component // Implement this function when using this component.
return false // Return true on success, false on invalid password, or
// a [error message, translated] array for any other error.
return ["Verification not implemented", false]
} }
@ -56,15 +63,20 @@ Popup {
okClicked = true okClicked = true
button.loading = true button.loading = true
if (verifyPassword(password)) { verifyPassword(password, result => {
if (result === true) {
passwordValid = true passwordValid = true
popup.acceptedPassword = password popup.acceptedPassword = password
popup.close() popup.close()
} else { } else if (result === false) {
passwordValid = false passwordValid = false
} else {
let [msg, translated] = result
errorMessage.text = translated ? msg : qsTr(msg)
} }
button.loading = false button.loading = false
})
}, },
cancel: button => { popup.close() }, cancel: button => { popup.close() },
}) })
@ -105,5 +117,17 @@ Popup {
Behavior on Layout.preferredWidth { HNumberAnimation {} } Behavior on Layout.preferredWidth { HNumberAnimation {} }
} }
} }
HLabel {
id: errorMessage
wrapMode: Text.Wrap
color: theme.colors.errorText
visible: Layout.maximumHeight > 0
Layout.maximumHeight: text ? implicitHeight : 0
Behavior on Layout.maximumHeight { HNumberAnimation {} }
Layout.fillWidth: true
}
} }
} }

View File

@ -8,10 +8,11 @@ HColumnLayout {
function importKeys(file, passphrase) { function importKeys(file, passphrase) {
importButton.loading = true importButton.loading = true
let path = Qt.resolvedUrl(file).replace(/^file:\/\//, "") let path = file.toString().replace(/^file:\/\//, "")
py.callClientCoro( py.callClientCoro(
editAccount.userId, "import_keys", [path, passphrase], () => { editAccount.userId, "import_keys", [path, passphrase], () => {
print("import done")
importButton.loading = false importButton.loading = false
} }
) )
@ -63,9 +64,11 @@ HColumnLayout {
HPasswordPopup { HPasswordPopup {
property url file: "" property url file: ""
function verifyPassword(pass) { function verifyPassword(pass, callback) {
return py.callSync( return py.callCoro(
"check_exported_keys_password", [file.toString(), pass] "check_exported_keys_passphrase",
[file.toString().replace(/^file:\/\//, ""), pass],
callback
) )
} }
@ -73,6 +76,6 @@ HColumnLayout {
label.text: qsTr( label.text: qsTr(
"Please enter the passphrase that was used to protect this file:" "Please enter the passphrase that was used to protect this file:"
) )
onAcceptedPasswordChanged: importKeys(file, password) onAcceptedPasswordChanged: importKeys(file, acceptedPassword)
} }
} }