Clean up keyring when a connection is deleted

This commit is contained in:
2023-01-10 23:23:55 +01:00
parent 5488e7cc81
commit b36e27a7f2
3 changed files with 41 additions and 3 deletions

View File

@@ -62,6 +62,7 @@ class RevPiSettings:
self.ssh_use_tunnel = True self.ssh_use_tunnel = True
self.ssh_port = 22 self.ssh_port = 22
self.ssh_user = "pi" self.ssh_user = "pi"
self.ssh_saved_password = False
self.last_dir_upload = "." self.last_dir_upload = "."
self.last_file_upload = "." self.last_file_upload = "."
@@ -96,6 +97,7 @@ class RevPiSettings:
self.ssh_use_tunnel = self._settings.value("ssh_use_tunnel", True, type=bool) self.ssh_use_tunnel = self._settings.value("ssh_use_tunnel", True, type=bool)
self.ssh_port = self._settings.value("ssh_port", 22, type=int) self.ssh_port = self._settings.value("ssh_port", 22, type=int)
self.ssh_user = self._settings.value("ssh_user", "pi", type=str) self.ssh_user = self._settings.value("ssh_user", "pi", type=str)
self.ssh_saved_password = self._settings.value("ssh_saved_password", False, type=bool)
self.last_dir_upload = self._settings.value("last_dir_upload", ".", type=str) self.last_dir_upload = self._settings.value("last_dir_upload", ".", type=str)
self.last_file_upload = self._settings.value("last_file_upload", ".", type=str) self.last_file_upload = self._settings.value("last_file_upload", ".", type=str)
@@ -172,6 +174,7 @@ class RevPiSettings:
self._settings.setValue("ssh_use_tunnel", self.ssh_use_tunnel) self._settings.setValue("ssh_use_tunnel", self.ssh_use_tunnel)
self._settings.setValue("ssh_port", self.ssh_port) self._settings.setValue("ssh_port", self.ssh_port)
self._settings.setValue("ssh_user", self.ssh_user) self._settings.setValue("ssh_user", self.ssh_user)
self._settings.setValue("ssh_saved_password", self.ssh_saved_password)
self._settings.setValue("last_dir_upload", self.last_dir_upload) self._settings.setValue("last_dir_upload", self.last_dir_upload)
self._settings.setValue("last_file_upload", self.last_file_upload) self._settings.setValue("last_file_upload", self.last_file_upload)
@@ -347,6 +350,7 @@ class ConnectionManager(QtCore.QThread):
revpi_settings.address, revpi_settings.address,
revpi_settings.ssh_port revpi_settings.ssh_port
) )
revpi_settings.ssh_saved_password = diag_ssh_auth.in_keyring
try: try:
ssh_tunnel_port = ssh_tunnel_server.connect_by_credentials(ssh_user, ssh_pass) ssh_tunnel_port = ssh_tunnel_server.connect_by_credentials(ssh_user, ssh_pass)
break break

View File

@@ -6,7 +6,9 @@ __license__ = "GPLv3"
from enum import IntEnum from enum import IntEnum
import keyring
from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5 import QtCore, QtGui, QtWidgets
from keyring.errors import KeyringError
from . import helper from . import helper
from . import proginit as pi from . import proginit as pi
@@ -29,6 +31,7 @@ class RevPiPlcList(QtWidgets.QDialog, Ui_diag_connections):
self.__current_item = QtWidgets.QTreeWidgetItem() # type: QtWidgets.QTreeWidgetItem self.__current_item = QtWidgets.QTreeWidgetItem() # type: QtWidgets.QTreeWidgetItem
self.changes = True self.changes = True
self._keyring_cleanup_id_user = []
self.tre_connections.setColumnWidth(0, 250) self.tre_connections.setColumnWidth(0, 250)
self.lbl_port.setText(self.lbl_port.text().format(self.__default_port)) self.lbl_port.setText(self.lbl_port.text().format(self.__default_port))
@@ -79,6 +82,18 @@ class RevPiPlcList(QtWidgets.QDialog, Ui_diag_connections):
def accept(self) -> None: def accept(self) -> None:
pi.logger.debug("RevPiPlcList.accept") pi.logger.debug("RevPiPlcList.accept")
for internal_id, ssh_user in self._keyring_cleanup_id_user:
service_name = "{0}.{1}_{2}".format(
helper.settings.applicationName(),
helper.settings.organizationName(),
internal_id
)
try:
# Remove information from os keyring, which we collected on_btn_delete_clicked
keyring.delete_password(service_name, ssh_user)
except KeyringError as e:
pi.logger.error(e)
helper.settings.remove("connections") helper.settings.remove("connections")
for i in range(self.tre_connections.topLevelItemCount()): for i in range(self.tre_connections.topLevelItemCount()):
@@ -242,6 +257,12 @@ class RevPiPlcList(QtWidgets.QDialog, Ui_diag_connections):
"""Remove selected entry.""" """Remove selected entry."""
item = self.tre_connections.currentItem() item = self.tre_connections.currentItem()
if item and item.type() == NodeType.CON: if item and item.type() == NodeType.CON:
revpi_settings = item.data(0, WidgetData.revpi_settings) # type: RevPiSettings
if revpi_settings.ssh_saved_password:
# Cleans up keyring in save function
self._keyring_cleanup_id_user.append((revpi_settings.internal_id, revpi_settings.ssh_user))
dir_node = item.parent() dir_node = item.parent()
if dir_node: if dir_node:
dir_node.removeChild(item) dir_node.removeChild(item)

View File

@@ -34,6 +34,7 @@ class SSHAuth(QtWidgets.QDialog, Ui_diag_sshauth):
super(SSHAuth, self).__init__(parent) super(SSHAuth, self).__init__(parent)
self.setupUi(self) self.setupUi(self)
self._in_keyring = False
self._service_name = service_name self._service_name = service_name
self.cbx_save_password.setVisible(bool(service_name)) self.cbx_save_password.setVisible(bool(service_name))
self.txt_username.setText(user_name) self.txt_username.setText(user_name)
@@ -46,6 +47,7 @@ class SSHAuth(QtWidgets.QDialog, Ui_diag_sshauth):
keyring.set_password(self._service_name, self.username, self.password) keyring.set_password(self._service_name, self.username, self.password)
except KeyringError as e: except KeyringError as e:
log.error(e) log.error(e)
self._in_keyring = False
QtWidgets.QMessageBox.warning( QtWidgets.QMessageBox.warning(
self, self.tr("Could not save password"), self.tr( self, self.tr("Could not save password"), self.tr(
"Could not save password to operating systems password save.\n\n" "Could not save password to operating systems password save.\n\n"
@@ -54,6 +56,9 @@ class SSHAuth(QtWidgets.QDialog, Ui_diag_sshauth):
"This is not an error of RevPi Commander." "This is not an error of RevPi Commander."
) )
) )
else:
self._in_keyring = True
super().accept() super().accept()
def exec(self) -> int: def exec(self) -> int:
@@ -62,11 +67,14 @@ class SSHAuth(QtWidgets.QDialog, Ui_diag_sshauth):
if self._service_name: if self._service_name:
try: try:
saved_password = keyring.get_password(self._service_name, self.username) saved_password = keyring.get_password(self._service_name, self.username)
if saved_password:
self.txt_password.setText(saved_password)
return QtWidgets.QDialog.Accepted
except KeyringError as e: except KeyringError as e:
log.error(e) log.error(e)
self._in_keyring = False
else:
if saved_password:
self._in_keyring = True
self.txt_password.setText(saved_password)
return QtWidgets.QDialog.Accepted
return super().exec() return super().exec()
@@ -80,6 +88,11 @@ class SSHAuth(QtWidgets.QDialog, Ui_diag_sshauth):
except KeyringError as e: except KeyringError as e:
log.error(e) log.error(e)
@property
def in_keyring(self) -> bool:
"""True, if password is in keyring."""
return self._in_keyring
@property @property
def password(self) -> str: def password(self) -> str:
"""Get the saved or entered password.""" """Get the saved or entered password."""