mirror of https://github.com/borgbase/vorta
Improve SSH key process. By @bigtedde (#1802)
This commit is contained in:
parent
cff00ad8e1
commit
15fa46ff85
|
@ -198,10 +198,17 @@ class RepoTab(RepoBase, RepoUI, BackupProfileMixin):
|
||||||
ssh_add_window = SSHAddWindow()
|
ssh_add_window = SSHAddWindow()
|
||||||
self._window = ssh_add_window # For tests
|
self._window = ssh_add_window # For tests
|
||||||
ssh_add_window.setParent(self, QtCore.Qt.WindowType.Sheet)
|
ssh_add_window.setParent(self, QtCore.Qt.WindowType.Sheet)
|
||||||
ssh_add_window.accepted.connect(self.init_ssh)
|
ssh_add_window.rejected.connect(self.init_ssh)
|
||||||
# ssh_add_window.rejected.connect(lambda: self.sshComboBox.setCurrentIndex(0))
|
ssh_add_window.failure.connect(self.create_ssh_key_failure)
|
||||||
ssh_add_window.open()
|
ssh_add_window.open()
|
||||||
|
|
||||||
|
def create_ssh_key_failure(self, exit_code):
|
||||||
|
msg = QMessageBox()
|
||||||
|
msg.setStandardButtons(QMessageBox.StandardButton.Ok)
|
||||||
|
msg.setParent(self, QtCore.Qt.WindowType.Sheet)
|
||||||
|
msg.setText(self.tr(f'Error during key generation. Exited with code {exit_code}.'))
|
||||||
|
msg.show()
|
||||||
|
|
||||||
def ssh_copy_to_clipboard_action(self):
|
def ssh_copy_to_clipboard_action(self):
|
||||||
msg = QMessageBox()
|
msg = QMessageBox()
|
||||||
msg.setStandardButtons(QMessageBox.StandardButton.Ok)
|
msg.setStandardButtons(QMessageBox.StandardButton.Ok)
|
||||||
|
@ -223,7 +230,6 @@ class RepoTab(RepoBase, RepoUI, BackupProfileMixin):
|
||||||
"Use it to set up remote repo permissions."
|
"Use it to set up remote repo permissions."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
msg.setText(self.tr("Could not find public key."))
|
msg.setText(self.tr("Could not find public key."))
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from PyQt6 import uic
|
from PyQt6 import QtCore, uic
|
||||||
from PyQt6.QtCore import QProcess, Qt
|
from PyQt6.QtCore import QProcess, Qt, pyqtSlot
|
||||||
from PyQt6.QtWidgets import QApplication, QDialogButtonBox
|
from PyQt6.QtWidgets import QApplication, QDialogButtonBox
|
||||||
|
|
||||||
from ..utils import get_asset
|
from ..utils import get_asset
|
||||||
|
@ -11,6 +11,8 @@ SSHAddUI, SSHAddBase = uic.loadUiType(uifile)
|
||||||
|
|
||||||
|
|
||||||
class SSHAddWindow(SSHAddBase, SSHAddUI):
|
class SSHAddWindow(SSHAddBase, SSHAddUI):
|
||||||
|
failure = QtCore.pyqtSignal(int)
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
|
@ -68,15 +70,17 @@ class SSHAddWindow(SSHAddBase, SSHAddUI):
|
||||||
self.sshproc.finished.connect(self.generate_key_result)
|
self.sshproc.finished.connect(self.generate_key_result)
|
||||||
self.sshproc.start('ssh-keygen', ['-t', format, '-b', length, '-f', output_path, '-N', ''])
|
self.sshproc.start('ssh-keygen', ['-t', format, '-b', length, '-f', output_path, '-N', ''])
|
||||||
|
|
||||||
def generate_key_result(self, exitCode, exitStatus):
|
@pyqtSlot(int)
|
||||||
if exitCode == 0:
|
def generate_key_result(self, exit_code):
|
||||||
|
if exit_code == 0:
|
||||||
output_path = os.path.expanduser(self.outputFileTextBox.text())
|
output_path = os.path.expanduser(self.outputFileTextBox.text())
|
||||||
pub_key = open(output_path + '.pub').read().strip()
|
pub_key = open(output_path + '.pub').read().strip()
|
||||||
clipboard = QApplication.clipboard()
|
clipboard = QApplication.clipboard()
|
||||||
clipboard.setText(pub_key)
|
clipboard.setText(pub_key)
|
||||||
self.errors.setText(self.tr('New key was copied to clipboard and written to %s.') % output_path)
|
self.reject()
|
||||||
else:
|
else:
|
||||||
self.errors.setText(self.tr('Error during key generation.'))
|
self.reject()
|
||||||
|
self.failure.emit(exit_code)
|
||||||
|
|
||||||
def get_values(self):
|
def get_values(self):
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -131,13 +131,13 @@ def test_repo_add_success(qapp, qtbot, mocker, borg_json_output):
|
||||||
assert tab.repoSelector.currentText() == f"{test_repo_name} - {test_repo_url}"
|
assert tab.repoSelector.currentText() == f"{test_repo_name} - {test_repo_url}"
|
||||||
|
|
||||||
|
|
||||||
def test_ssh_dialog(qapp, qtbot, tmpdir):
|
def test_ssh_dialog_success(qapp, qtbot, mocker, tmpdir):
|
||||||
main = qapp.main_window
|
main = qapp.main_window
|
||||||
tab = main.repoTab
|
tab = main.repoTab
|
||||||
|
|
||||||
qtbot.mouseClick(tab.bAddSSHKey, QtCore.Qt.MouseButton.LeftButton)
|
qtbot.mouseClick(tab.bAddSSHKey, QtCore.Qt.MouseButton.LeftButton)
|
||||||
ssh_dialog = tab._window
|
ssh_dialog = tab._window
|
||||||
|
ssh_dialog_closed = mocker.spy(ssh_dialog, 'reject')
|
||||||
ssh_dir = tmpdir
|
ssh_dir = tmpdir
|
||||||
key_tmpfile = ssh_dir.join("id_rsa-test")
|
key_tmpfile = ssh_dir.join("id_rsa-test")
|
||||||
pub_tmpfile = ssh_dir.join("id_rsa-test.pub")
|
pub_tmpfile = ssh_dir.join("id_rsa-test.pub")
|
||||||
|
@ -145,18 +145,46 @@ def test_ssh_dialog(qapp, qtbot, tmpdir):
|
||||||
ssh_dialog.outputFileTextBox.setText(key_tmpfile_full)
|
ssh_dialog.outputFileTextBox.setText(key_tmpfile_full)
|
||||||
ssh_dialog.generate_key()
|
ssh_dialog.generate_key()
|
||||||
|
|
||||||
# Ensure new key files exist
|
# Ensure new key file was created
|
||||||
qtbot.waitUntil(lambda: ssh_dialog.errors.text().startswith('New key was copied'), **pytest._wait_defaults)
|
qtbot.waitUntil(lambda: ssh_dialog_closed.called, **pytest._wait_defaults)
|
||||||
assert len(ssh_dir.listdir()) == 2
|
assert len(ssh_dir.listdir()) == 2
|
||||||
|
|
||||||
|
# Ensure new key is populated in SSH combobox
|
||||||
|
mocker.patch('os.path.expanduser', return_value=str(tmpdir))
|
||||||
|
tab.init_ssh()
|
||||||
|
assert tab.sshComboBox.count() == 2
|
||||||
|
|
||||||
# Ensure valid keys were created
|
# Ensure valid keys were created
|
||||||
key_tmpfile_content = key_tmpfile.read()
|
key_tmpfile_content = key_tmpfile.read()
|
||||||
assert key_tmpfile_content.startswith('-----BEGIN OPENSSH PRIVATE KEY-----')
|
assert key_tmpfile_content.startswith('-----BEGIN OPENSSH PRIVATE KEY-----')
|
||||||
pub_tmpfile_content = pub_tmpfile.read()
|
pub_tmpfile_content = pub_tmpfile.read()
|
||||||
assert pub_tmpfile_content.startswith('ssh-ed25519')
|
assert pub_tmpfile_content.startswith('ssh-ed25519')
|
||||||
|
|
||||||
|
|
||||||
|
def test_ssh_dialog_failure(qapp, qtbot, mocker, monkeypatch, tmpdir):
|
||||||
|
main = qapp.main_window
|
||||||
|
tab = main.repoTab
|
||||||
|
monkeypatch.setattr(QMessageBox, "show", lambda *args: True)
|
||||||
|
failure_message = mocker.spy(tab, "create_ssh_key_failure")
|
||||||
|
|
||||||
|
qtbot.mouseClick(tab.bAddSSHKey, QtCore.Qt.MouseButton.LeftButton)
|
||||||
|
ssh_dialog = tab._window
|
||||||
|
ssh_dir = tmpdir
|
||||||
|
key_tmpfile = ssh_dir.join("invalid///===for_testing")
|
||||||
|
key_tmpfile_full = os.path.join(key_tmpfile.dirname, key_tmpfile.basename)
|
||||||
|
ssh_dialog.outputFileTextBox.setText(key_tmpfile_full)
|
||||||
ssh_dialog.generate_key()
|
ssh_dialog.generate_key()
|
||||||
qtbot.waitUntil(lambda: ssh_dialog.errors.text().startswith('Key file already'), **pytest._wait_defaults)
|
|
||||||
|
qtbot.waitUntil(lambda: failure_message.called, **pytest._wait_defaults)
|
||||||
|
failure_message.assert_called_once()
|
||||||
|
|
||||||
|
# Ensure no new ney file was created
|
||||||
|
assert len(ssh_dir.listdir()) == 0
|
||||||
|
|
||||||
|
# Ensure no new key file in combo box
|
||||||
|
mocker.patch('os.path.expanduser', return_value=str(tmpdir))
|
||||||
|
tab.init_ssh()
|
||||||
|
assert tab.sshComboBox.count() == 1
|
||||||
|
|
||||||
|
|
||||||
def test_create(qapp, borg_json_output, mocker, qtbot):
|
def test_create(qapp, borg_json_output, mocker, qtbot):
|
||||||
|
|
Loading…
Reference in New Issue