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
- Banners

View File

@ -128,12 +128,26 @@ class Backend:
@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:
nio.crypto.key_export.decrypt_and_read(file_path, password)
nio.crypto.key_export.decrypt_and_read(file_path, passphrase)
return True
except (FileNotFoundError, ValueError):
return False
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 (str(err), False)
async def load_settings(self) -> tuple:

View File

@ -9,9 +9,14 @@ Popup {
modal: true
padding: 0
onAboutToShow: {
acceptedPassword = ""
passwordValid = null
okClicked = false
errorMessage.text = ""
}
onOpened: passwordField.forceActiveFocus()
property bool validateWhileTyping: false
property string acceptedPassword: ""
@ -22,9 +27,11 @@ Popup {
property alias field: passwordField
function verifyPassword(pass) {
// Implement me when using this component
return false
function verifyPassword(pass, callback) {
// Implement this function when using this component.
// 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
button.loading = true
if (verifyPassword(password)) {
passwordValid = true
popup.acceptedPassword = password
popup.close()
} else {
passwordValid = false
}
verifyPassword(password, result => {
if (result === true) {
passwordValid = true
popup.acceptedPassword = password
popup.close()
} else if (result === false) {
passwordValid = false
} else {
let [msg, translated] = result
errorMessage.text = translated ? msg : qsTr(msg)
}
button.loading = false
button.loading = false
})
},
cancel: button => { popup.close() },
})
@ -105,5 +117,17 @@ Popup {
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) {
importButton.loading = true
let path = Qt.resolvedUrl(file).replace(/^file:\/\//, "")
let path = file.toString().replace(/^file:\/\//, "")
py.callClientCoro(
editAccount.userId, "import_keys", [path, passphrase], () => {
print("import done")
importButton.loading = false
}
)
@ -63,9 +64,11 @@ HColumnLayout {
HPasswordPopup {
property url file: ""
function verifyPassword(pass) {
return py.callSync(
"check_exported_keys_password", [file.toString(), pass]
function verifyPassword(pass, callback) {
return py.callCoro(
"check_exported_keys_passphrase",
[file.toString().replace(/^file:\/\//, ""), pass],
callback
)
}
@ -73,6 +76,6 @@ HColumnLayout {
label.text: qsTr(
"Please enter the passphrase that was used to protect this file:"
)
onAcceptedPasswordChanged: importKeys(file, password)
onAcceptedPasswordChanged: importKeys(file, acceptedPassword)
}
}