Better error handling and fixes for key import
This commit is contained in:
		
							
								
								
									
										2
									
								
								TODO.md
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								TODO.md
									
									
									
									
									
								
							@@ -1,3 +1,5 @@
 | 
			
		||||
rename hinterfacebox
 | 
			
		||||
translated arg for avatar upload and login
 | 
			
		||||
- Refactoring
 | 
			
		||||
  - Banners
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -128,13 +128,27 @@ 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):
 | 
			
		||||
 | 
			
		||||
        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:
 | 
			
		||||
        from .config_files import Theme
 | 
			
		||||
 
 | 
			
		||||
@@ -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)) {
 | 
			
		||||
                verifyPassword(password, result => {
 | 
			
		||||
                    if (result === true) {
 | 
			
		||||
                        passwordValid          = true
 | 
			
		||||
                        popup.acceptedPassword = password
 | 
			
		||||
                        popup.close()
 | 
			
		||||
                } else {
 | 
			
		||||
                    } else if (result === false) {
 | 
			
		||||
                        passwordValid = false
 | 
			
		||||
                    } else {
 | 
			
		||||
                        let [msg, translated] = result
 | 
			
		||||
                        errorMessage.text     = translated ? msg : qsTr(msg)
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    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
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user